/* modou dsp — Universal Product Detail Page template
   One shared stylesheet for every product; per-product colour comes from
   --product-accent set on <html> in each page. */

/* Sticky buy bar */
.buy-bar {
  position: sticky; top: 57px; z-index: 90;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.9rem var(--space-lg);
  background: color-mix(in srgb, var(--bg-charcoal) 92%, transparent);
  border-bottom: 1px solid var(--border-overlay);
  backdrop-filter: blur(16px);
}
.buy-bar .name { font-weight: 700; }
.buy-bar .price { font-family: var(--font-mono); color: var(--product-accent); margin-left: var(--space-sm); }
.buy-bar .actions { display: flex; gap: var(--space-xs); }

/* PDP hero */
.pdp-hero {
  padding: var(--space-xl) var(--space-lg) var(--space-section);
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-xl); align-items: center;
  max-width: 1180px; margin-inline: auto;
}
.pdp-hero .badges { display: flex; gap: 0.5rem; flex-wrap: wrap; margin: var(--space-sm) 0 var(--space-md); }
.pdp-hero .badges span {
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-muted);
  border: 1px solid var(--border-overlay); border-radius: var(--radius-pill); padding: 0.3rem 0.7rem;
}
.pdp-hero h1 { font-size: var(--text-2xl); line-height: 1.08; margin: 0.3rem 0; }
.pdp-hero .tagline { color: var(--product-accent); font-weight: 600; font-size: var(--text-lg); }
.pdp-hero .visual { border-radius: var(--radius-card); overflow: hidden; border: 1px solid var(--border-overlay); }
.pdp-hero .visual img,
.pdp-hero .visual .loop-video { width: 100%; display: block; }
/* PDP loads product.css, not home.css — .loop-video needs its own rule
   here or the clip renders at intrinsic size. */
.loop-video { display: block; width: 100%; height: auto; background: var(--bg-obsidian); }
.pdp-hero .price-row { display: flex; align-items: baseline; gap: 0.6rem; margin: var(--space-md) 0; }
.pdp-hero .price-row .price { font-family: var(--font-mono); font-size: var(--text-xl); color: var(--product-accent); }

/* generic two-col content block */
.content-split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-xl); align-items: center; }
.content-split h2 { font-size: var(--text-xl); margin: 0 0 var(--space-sm); }
.content-split p { color: var(--text-muted); }
.content-split .visual { border-radius: var(--radius-card); overflow: hidden; border: 1px solid var(--border-overlay); }
.content-split .visual img { width: 100%; display: block; }

/* interactive hotspots */
.hotspot-figure { position: relative; border-radius: var(--radius-card); overflow: hidden; border: 1px solid var(--border-overlay); }
.hotspot-figure img { width: 100%; display: block; }
.hotspot {
  position: absolute; width: 22px; height: 22px; border-radius: 50%;
  background: color-mix(in srgb, var(--product-accent) 25%, transparent);
  border: 1.5px solid var(--product-accent);
  cursor: help;
}
.hotspot::after { content: ""; position: absolute; inset: 6px; border-radius: 50%; background: var(--product-accent); }
.hotspot .tip {
  position: absolute; bottom: calc(100% + 10px); left: 50%; transform: translateX(-50%);
  width: max-content; max-width: 220px;
  background: var(--bg-charcoal); border: 1px solid var(--border-overlay); border-radius: 8px;
  padding: 0.6rem 0.75rem; font-size: var(--text-xs); color: var(--text-muted);
  opacity: 0; pointer-events: none; transition: opacity var(--duration-fast) var(--ease-out-expo);
}
.hotspot:hover .tip, .hotspot:focus .tip { opacity: 1; }
.hotspot .tip b { color: var(--text-primary); display: block; margin-bottom: 0.2rem; }

/* feature grid */
.feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-sm); }
.feature-grid .card { padding: var(--space-md); }
.feature-grid h3 { font-size: var(--text-base); margin: 0 0 0.4rem; }
.feature-grid p { font-size: var(--text-sm); color: var(--text-muted); margin: 0; }

/* walkthrough video */
.pdp-video { position: relative; aspect-ratio: 16/9; border-radius: var(--radius-card); overflow: hidden; border: 1px solid var(--border-overlay); background: var(--bg-charcoal); }
.pdp-video iframe, .pdp-video video { width: 100%; height: 100%; display: block; border: 0; }

/* Fallback for a URL we cannot embed — centred in the same 16:9 frame so
   the section still reads as a video block rather than a broken one. */
.pdp-video p {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  margin: 0;
  padding: var(--space-md);
  text-align: center;
}
.pdp-video p a { color: var(--product-accent); text-decoration: underline; }

/* A/B listen blocks */
.listen-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-sm); }
.listen-block { padding: var(--space-md); }
.listen-item-label { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.06em; margin: 0 0 var(--space-sm); }
.ab-toggle { display: inline-flex; border: 1px solid var(--border-overlay); border-radius: var(--radius-pill); overflow: hidden; margin-bottom: var(--space-md); }
.ab-toggle button {
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600;
  padding: 0.5rem 1.1rem; background: transparent; color: var(--text-muted); border: 0; cursor: pointer;
}
.ab-toggle button[aria-pressed="true"] { background: var(--product-accent); color: var(--bg-obsidian); }

.listen-controls { display: flex; align-items: center; gap: var(--space-sm); }
.listen-play {
  width: 34px; height: 34px; flex-shrink: 0; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--product-accent); color: var(--bg-obsidian);
  display: flex; align-items: center; justify-content: center;
}
.listen-play svg { width: 16px; height: 16px; }
.listen-seek { flex: 1; accent-color: var(--product-accent); }
.listen-time { font-size: var(--text-xs); color: var(--text-faint); min-width: 3ch; }

@media (max-width: 700px) {
  .listen-grid { grid-template-columns: 1fr; }
}

/* specs table */
.specs-table { width: 100%; border-collapse: collapse; }
.specs-table th { text-align: left; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-faint); text-transform: uppercase; padding: 0.6rem 0; letter-spacing: 0.06em; }
.specs-table td { padding: 0.8rem 0; border-top: 1px solid var(--border-overlay); font-size: var(--text-sm); }
.specs-table td:first-child { color: var(--text-muted); width: 40%; }

/* FAQ */
.faq details { border-top: 1px solid var(--border-overlay); padding: var(--space-sm) 0; }
.faq summary { cursor: pointer; font-weight: 600; list-style: none; display: flex; justify-content: space-between; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--product-accent); font-family: var(--font-mono); }
.faq details[open] summary::after { content: "\2212"; }
.faq p { color: var(--text-muted); margin: var(--space-xs) 0 0; }

@media (max-width: 980px) {
  .pdp-hero, .content-split { grid-template-columns: 1fr; }
  .feature-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
  .feature-grid { grid-template-columns: 1fr; }
}

/* ── The one job ────────────────────────────────────────────────────
   Sits above the tagline in the PDP hero and above the name in shop
   tiles. It's the first thing read in both places because the catalog's
   claim is per-job sufficiency, not a feature count. */
.pdp-job {
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--product-accent);
  margin: 0 0 0.5rem;
}

/* Manual links in the PDP hero. Two actions, one line: read it here,
   or keep the file. Set as links rather than buttons so they don't
   compete with Buy. */
.pdp-manual-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin: var(--space-sm) 0 0;
  font-size: var(--text-sm);
}
.pdp-manual-links a {
  color: var(--product-accent);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--product-accent) 35%, transparent);
  transition: border-color .14s ease;
}
.pdp-manual-links a:hover { border-bottom-color: var(--product-accent); }
.pdp-manual-links a[download] { color: var(--text-muted); border-bottom-color: var(--border-overlay); }
.pdp-manual-links a[download]:hover { color: var(--text-primary); border-bottom-color: var(--text-faint); }

/* ── Walkthrough videos ───────────────────────────────────────────────
   One video keeps the full-width frame it always had. Two or more lay out
   two across, so four fill a 2×2 block. Below 720px they stack: a 16:9
   player at half of a phone's width is too small to follow. */
/* ── Video manual & quick start ────────────────────────────────────────
   The two named videos. Side by side when both are set; a single one
   keeps the full width rather than sitting in a half-empty row. */
.pdp-primary-videos { display: grid; gap: var(--space-md); }
.pdp-video-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.pdp-primary-video { margin: 0; }

.pdp-primary-video figcaption {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.4rem var(--space-sm);
  margin-top: 0.6rem;
}

.pdp-video-kind {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-base);
  color: var(--text-primary);
}

.pdp-video-note { color: var(--text-faint); font-size: var(--text-sm); }

/* ── Video gallery ─────────────────────────────────────────────────────
   Four at a time, scrolled sideways. Twenty tiles laid out as five rows
   is a page of video thumbnails with the product underneath it — the
   gallery stops being a section of the page and becomes the page. One
   row that pages sideways keeps it to the height of a single row however
   many videos there are.

   Scroll-snap rather than a JS carousel: the container is a real
   scroller, so a trackpad swipe, a touch drag, the arrow keys and the
   buttons below all work, and none of them are something we implemented. */
.pdp-gallery-wrap { position: relative; }

.pdp-gallery-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: var(--space-md);
}

.pdp-gallery-nav { display: flex; gap: 0.5rem; flex: none; }

.pdp-gallery-nav button {
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--border-overlay);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-out-expo),
              border-color var(--duration-fast) var(--ease-out-expo),
              opacity var(--duration-fast) var(--ease-out-expo);
}

.pdp-gallery-nav button:hover:not(:disabled) { color: var(--product-accent); border-color: var(--product-accent); }

/* Disabled rather than hidden at the ends: a control that disappears
   moves the one next to it, and the row jumps as you page. */
.pdp-gallery-nav button:disabled { opacity: 0.3; cursor: default; }

/* No videos beyond the first page — nothing to page through. */
.pdp-gallery-nav[hidden] { display: none; }

.pdp-video-gallery {
  list-style: none;
  margin: 0;
  padding: 0 0 var(--space-sm);
  display: grid;
  grid-auto-flow: column;
  /* Exactly four in view: the track minus the three gaps between them. */
  grid-auto-columns: calc((100% - 3 * var(--space-md)) / 4);
  gap: var(--space-md);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: thin;
  scrollbar-color: var(--border-overlay) transparent;
}

.pdp-video-gallery > li { margin: 0; scroll-snap-align: start; }

.pdp-video-gallery::-webkit-scrollbar { height: 6px; }
.pdp-video-gallery::-webkit-scrollbar-thumb { background: var(--border-overlay); border-radius: 999px; }
.pdp-video-gallery::-webkit-scrollbar-track { background: transparent; }

/* Focus ring on the scroller itself, which is keyboard-focusable so the
   arrow keys can page it. */
.pdp-video-gallery:focus-visible { outline: 2px solid var(--product-accent); outline-offset: 4px; }

.pdp-video-title {
  margin: 0.5rem 0 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
  /* Two lines, then ellipsis: titles vary in length, and in a single
     scrolling row a taller card would set the height of every other. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* A caption band across the top of a tile's frame.
   Over a photographic thumbnail, so it carries its own scrim rather than
   trusting the image behind it to be dark — YouTube thumbnails are
   whatever the uploader chose, and white text on a white frame is not a
   caption. pointer-events:none keeps the whole tile clickable. */
.pdp-video-caption {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  padding: 0.5rem var(--space-sm) 0.7rem;
  /* Held near-solid for the height of the text and faded only across the
     last stretch. A single top-to-bottom fade stretches with the box, so
     on a wrapped caption the lower lines ended up over bare thumbnail —
     the one place the scrim has to work hardest. */
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--bg-obsidian) 92%, transparent) 0%,
    color-mix(in srgb, var(--bg-obsidian) 88%, transparent) 65%,
    transparent 100%
  );
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.45;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
  pointer-events: none;
  /* Wraps rather than truncates. It was one line with an ellipsis, which
     meant a caption long enough to need reading was the one you could not
     read. Overlaying more of the frame is the trade being made here. */
  white-space: normal;
  overflow-wrap: anywhere;
}

/* The click-to-load thumbnail. A <button>, so it is keyboard-operable and
   announced as a control without any ARIA of its own. */
.video-facade {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: var(--bg-charcoal);
  cursor: pointer;
}

.video-facade img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* YouTube's hqdefault is letterboxed 4:3; cover crops it back to the
     16:9 the tile actually is. */
  display: block;
  transition: transform var(--duration-normal) var(--ease-out-expo),
              opacity var(--duration-fast) var(--ease-out-expo);
}

.video-facade:hover img { transform: scale(1.03); opacity: 0.85; }

.video-facade-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--bg-obsidian) 78%, transparent);
  border: 1px solid var(--product-accent);
  color: var(--product-accent);
  /* Nudged right: an optical centre for a triangle, not a geometric one. */
  padding-left: 3px;
  transition: background-color var(--duration-fast) var(--ease-out-expo);
}

.video-facade:hover .video-facade-play,
.video-facade:focus-visible .video-facade-play {
  background: var(--product-accent);
  color: var(--bg-obsidian);
}

.video-facade:focus-visible { outline: 2px solid var(--product-accent); outline-offset: 2px; }

@media (max-width: 1024px) {
  .pdp-video-gallery { grid-auto-columns: calc((100% - var(--space-md)) / 2); }
}

@media (max-width: 700px) {
  /* Just over one tile wide, so the next one peeks in at the edge. A
     full-width tile with nothing showing beside it looks like the end of
     the list rather than the start of a row. */
  .pdp-video-gallery { grid-auto-columns: 86%; }
  .pdp-video-pair { grid-template-columns: 1fr; }
  /* Touch already scrolls this; the buttons are for pointer users. */
  .pdp-gallery-nav { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .video-facade img { transition: none; }
  .video-facade:hover img { transform: none; }
  /* Paging jumps instead of gliding. */
  .pdp-video-gallery { scroll-behavior: auto; }
}

.pdp-video-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-sm);
}

@media (max-width: 720px) {
  .pdp-video-grid { grid-template-columns: 1fr; }
}

/* ── Review gallery ───────────────────────────────────────────────────
   A horizontal scroller rather than a JS carousel. Scroll snapping gives
   the same one-card-at-a-time feel with no script to load, no state to
   desync, and it keeps working with a trackpad, a touch swipe, the
   keyboard and a screen reader alike. */
.pdp-reviews {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(280px, 340px);
  gap: var(--space-sm);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* Room for the cards' shadow and for the last card to clear the edge. */
  padding-bottom: var(--space-sm);
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
}

.pdp-review {
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  border: 1px solid var(--border-overlay);
  border-radius: var(--radius-card);
  background: var(--bg-charcoal);
}

.pdp-review img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: calc(var(--radius-card) - 6px);
}

.pdp-review-quote {
  margin: 0;
  font-size: var(--text-sm);
  line-height: 1.7;
  color: var(--text-primary);
}

.pdp-review-source {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-faint);
}

.pdp-review-source a { color: var(--product-accent); }

/* The scroller is focusable so it can be reached and moved by keyboard;
   the outline needs to be visible when it is. */
.pdp-reviews:focus-visible {
  outline: 2px solid var(--product-accent);
  outline-offset: 4px;
}
