/* mira-site/previews.css (arch-103). ONE reusable live-preview-window
   pattern, shared by the main page (#explore) and the explore hub. Each
   window is a same-origin iframe of the real deployed page, rendered as
   a scaled-down miniature inside a fixed aspect-ratio box (height is
   reserved, so loading shifts nothing: CLS 0). The iframe itself is
   pointer-events: none, tabindex="-1" and aria-hidden: the ONE click
   target per card is the stretched title link, which opens the full
   page. preview.js injects src lazily (IntersectionObserver, capped
   concurrency); until a frame loads, or if it fails, or with JS off,
   the .pv-fallback caption shows the old static-card look.

   Colors, type and spacing come ONLY from tokens.css custom properties;
   the one exception is the slate example-data pair, declared by
   explore.css on the hub and provided here as var() fallbacks so the
   main page (which does not load explore.css) matches it exactly.
   Every animated property is covered by both reduced-motion belts. */

/* ---------- the grid: one section, two fixed rows at desktop ---------- */
.pv-grid {
  list-style: none;
  margin: 1.6rem auto 0;
  padding: 0;
  max-width: var(--maxw-wide-2);
  display: grid;
  gap: 1rem;
}

/* ---------- one preview card ---------- */
.pv {
  position: relative;
  background: var(--paper-raised);
  border: 1.5px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 0.8rem 0.85rem 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.pv:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 26px rgba(31, 41, 51, 0.13);
  border-color: var(--accent);
}
.pv:has(.pv-open:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }

/* head row: title link left, honesty chips right */
.pv-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.3rem 0.7rem;
  flex-wrap: wrap;
}
.pv-open {
  font-family: var(--font-law);
  font-size: 1.08rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink);
  text-decoration: none;
}
.pv-open:hover { color: var(--accent-deep); }
/* stretched link: the whole card is one click target */
.pv-open::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 4;
  border-radius: var(--radius);
}
.pv-open:focus-visible { outline: none; } /* the card outline above carries focus */

.pv-chips { display: flex; gap: 0.35rem; flex-wrap: wrap; align-items: center; }
.pv-chip {
  display: inline-block;
  font-family: var(--font-ui);
  font-size: 0.67rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: var(--radius-chip);
  padding: 0.14rem 0.6rem;
  white-space: nowrap;
}
.pv-chip.pv-working { background: var(--accent); color: var(--paper-raised); }
.pv-chip.pv-build {
  background: var(--accent-wash);
  color: var(--accent-deep);
  border: 1.5px solid var(--accent);
}
/* slate example-data chip: square corners, same grammar as the explore
   family fixchip; var() fallbacks keep the main page identical */
.pv-chip.pv-fixture {
  background: var(--unv-ink, #2f3941);
  color: #fff;
  border-radius: 4px;
  letter-spacing: 0.08em;
}

/* ---------- the window: fixed aspect ratio, height reserved ---------- */
.pv-win {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) - 6px);
  background: var(--paper);
  container-type: size;
}

/* the live miniature: the frame renders the page at --pv-zoom times the
   window size and is scaled back down by exactly 1/zoom, so the page
   lays out at a desktop-like viewport and lands pixel-exact in the box.
   Container query units make the compensation exact at every card
   width with no JS measuring. The px pair below is only the fallback
   for engines without cq units. */
.pv-frame {
  position: absolute;
  top: 0;
  left: 0;
  border: 0;
  background: var(--paper);
  pointer-events: none;
  width: 1200px;
  height: 750px;
  transform: scale(0.32);
  transform-origin: 0 0;
  opacity: 0;
  transition: opacity 0.4s ease;
}
@supports (width: 100cqw) {
  .pv-frame {
    width: calc(100cqw * 3);
    height: calc(100cqh * 3);
    transform: scale(calc(1 / 3));
  }
}
.pv-live .pv-frame { opacity: 1; }

/* ---------- fallback: the old static-card look, also the loading and
   JS-off state. Absolutely positioned inside the reserved box: CLS 0. */
.pv-fallback {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.45rem;
  padding: 1rem 1.15rem;
  color: var(--ink-soft);
  font-size: var(--fs-small);
  line-height: 1.5;
  background: var(--paper-raised);
  transition: opacity 0.3s ease, visibility 0.3s ease;
}
.pv-fallback .pv-go { color: var(--accent-deep); font-weight: 700; }
.pv-live .pv-fallback { opacity: 0; visibility: hidden; }
.pv-fail .pv-fallback { opacity: 1; visibility: visible; }
.pv-fail .pv-frame { opacity: 0; }

/* ---------- fixed two-row composition ---------- */
/* below 720px: one clean column, no horizontal scrolling */
@media (min-width: 720px) and (max-width: 899px) {
  .pv-grid { grid-template-columns: 1fr 1fr; }
  .pv:last-child { grid-column: 1 / -1; }
}
@media (min-width: 900px) {
  /* three windows over two: rows are fixed, everything visible at once */
  .pv-grid { grid-template-columns: repeat(6, 1fr); gap: 1.2rem; }
  .pv { grid-column: span 2; }
  .pv:nth-child(4), .pv:nth-child(5) { grid-column: span 3; }
  /* the two wide bottom windows zoom out less, so their pages render
     at a sane desktop viewport instead of an ultrawide one */
  .pv-wide .pv-frame { width: 1300px; height: 812px; transform: scale(0.5); }
  @supports (width: 100cqw) {
    .pv-wide .pv-frame {
      width: calc(100cqw * 2);
      height: calc(100cqh * 2);
      transform: scale(calc(1 / 2));
    }
  }
}

/* ---------- reduced-motion coverage (both belts) ---------- */
@media (prefers-reduced-motion: reduce) {
  .pv, .pv-frame, .pv-fallback { transition: none; }
  .pv:hover { transform: none; }
}
html[data-motion="off"] .pv,
html[data-motion="off"] .pv-frame,
html[data-motion="off"] .pv-fallback { transition: none; }
html[data-motion="off"] .pv:hover { transform: none; }
