/* ── plugins.css ────────────────────────────────────────────────────────────
   Four layouts for the plugins section. [data-layout] on <html> shows one;
   the rest are display:none, so they never interfere with each other.

   Shared rules across all four: the screenshot is never cropped and never a
   thumbnail, only one plugin dominates at a time (the rack is the deliberate
   exception), and there are no gradients, shadows, or glows.
   ───────────────────────────────────────────────────────────────────────── */

.pv { display: none; }
[data-layout="stage"] .pv-stage,
[data-layout="strip"] .pv-strip,
[data-layout="stack"] .pv-stack,
[data-layout="rack"]  .pv-rack { display: block; }
[data-layout="featured"] .pv-feature { display: block; }
[data-layout="stage"] .pv-stage { display: grid; }
[data-layout="strip"] .pv-strip { display: flex; }

/* Per-plugin colour (--p) is declared in tokens.css with the other literals. */

/* Shots are scaled well down while examining layouts. Still uncropped:
   this caps width only, so aspect ratio is untouched. Raise --shot-max
   once a layout is chosen. */
:root { --shot-max: 46%; }
.p-shot {
  width: 100%;
  max-width: var(--shot-max);
  height: auto;
  object-fit: contain;
  margin-inline: auto;
}
/* Each cell is a link. Anchors get a 44px tap floor and inline-flex in
   base.css; the cells set their own display and colour, and a class beats a
   type selector, so those hold. Stated here so the override is not accidental. */
.pv-f-lead, .pv-f-item { color: inherit; }

/* The affordance that replaces a hover state: on a touch screen there is no
   cursor to change, so the destination has to be visible at rest. */
.pv-view {
  margin-left: var(--s3);
  color: var(--fg-faint);
  white-space: nowrap;
}

/* The nav's "Plugins" lands here; keep the section band off the viewport edge. */
#plugins { scroll-margin-top: var(--s6); }
.pv-price { color: var(--accent); }

/* ══ 1. Stage + rail ═════════════════════════════════════════════════════ */
.pv-stage {
  border-top: 1px solid var(--rule);
  grid-template-columns: 1fr;
}
.pv-rail { border-bottom: 1px solid var(--rule); }
.pv-rail li + li { border-top: 1px solid var(--rule); }
.pv-rail-btn {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s4);
  padding: var(--s4) var(--gutter);
  border-left: 2px solid transparent;
  color: var(--fg-muted);
}
.pv-rail-btn[aria-pressed="true"] {
  border-left-color: var(--p);
  color: var(--fg);
  background: var(--surface);
}
.pv-rail-name { font-family: var(--font-display); letter-spacing: var(--track-display); font-size: var(--fs-h3); }

.pv-stage-view { padding: var(--s6) var(--gutter); }
.pv-stage-panel[hidden] { display: none; }
.pv-stage-panel .p-shot { border: 1px solid var(--p); }
.pv-stage-cap {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s5);
  padding-top: var(--s4);
}
.pv-stage-name { font-family: var(--font-display); letter-spacing: var(--track-display); font-size: var(--fs-h2); }

@media (min-width: 64em) {
  .pv-stage { grid-template-columns: minmax(26rem, 1fr) 3fr; }
  .pv-rail { border-bottom: 0; border-right: 1px solid var(--rule); }
  .pv-stage-view { padding: var(--s7); }
}

/* ══ 2. Full-bleed filmstrip ═════════════════════════════════════════════
   No card borders. Each shot runs near the full frame width and snaps.
   ═════════════════════════════════════════════════════════════════════ */
.pv-strip {
  border-top: 1px solid var(--rule);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  gap: 1px;
  background: var(--rule);
  scrollbar-width: thin;
}
.pv-strip-item {
  position: relative;
  flex: 0 0 92%;
  scroll-snap-align: center;
  background: var(--ground);
  padding: var(--s5) var(--s5) 0;
}
.pv-strip-meta {
  position: absolute;
  left: var(--s5); right: var(--s5); bottom: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s5);
  padding: var(--s3) var(--s4);
  background: var(--ground);
  border-top: 2px solid var(--p);
}
.pv-strip-name { font-family: var(--font-display); letter-spacing: var(--track-display); font-size: var(--fs-h3); }

@media (min-width: 64em) { .pv-strip-item { flex-basis: 68%; } }

/* ══ 3. Stacked full-height sections ═════════════════════════════════════
   The shot overruns the frame edge deliberately; the frame clips it.
   ═════════════════════════════════════════════════════════════════════ */
.pv-stack { overflow: hidden; }
.pv-stack-item {
  min-height: 48vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--s5);
  padding: var(--s7) 0 var(--s7) var(--gutter);
  border-top: 1px solid var(--rule);
}
.pv-stack-item:nth-child(even) { background: var(--surface); }
.pv-stack-shot { padding-right: 0; }
.p-shot.is-bleed {
  width: var(--shot-max);
  max-width: none;
  margin-inline: 0;
  border: 1px solid var(--p);
}
.pv-stack-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s5); padding-right: var(--gutter); }
.pv-stack-name { font-family: var(--font-display); letter-spacing: var(--track-display); font-size: var(--fs-h1); line-height: var(--lh-tight); }

@media (min-width: 64em) {
  .pv-stack-item { min-height: 60vh; }
  .p-shot.is-bleed { width: var(--shot-max); }
}

/* ══ 4. Signal-chain rack ════════════════════════════════════════════════
   Slots patched in series. The connector is a real rule between units, so
   the chain reads as structure rather than ornament.
   ═════════════════════════════════════════════════════════════════════ */
.pv-rack { border-top: 1px solid var(--rule); }
.pv-rack-slot {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
  padding: var(--s5) var(--gutter);
  border-bottom: 1px solid var(--rule);
  border-left: 2px solid var(--p);
  position: relative;
}
/* The patch line between one unit and the next. */
.pv-rack-slot + .pv-rack-slot::before {
  content: "";
  position: absolute;
  left: calc(var(--gutter) * -1 + var(--gutter) / 2);
  top: 0; bottom: 0;
  border-left: 1px solid var(--rule);
}
.pv-rack-id { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s4); }
.pv-rack-name { font-family: var(--font-display); letter-spacing: var(--track-display); font-size: var(--fs-h3); }
.pv-rack-unit .p-shot { border: 1px solid var(--rule); }

@media (min-width: 64em) {
  .pv-rack-slot { grid-template-columns: minmax(22rem, 1fr) 3fr; align-items: start; gap: var(--s6); }
  .pv-rack-id { flex-direction: column; gap: var(--s2); }
}

/* ══ 5. Featured + three ═════════════════════════════════════════════════
   The lead (SillySlices) sits full width; the other three share an equal
   row beneath it — equal to each other, no asymmetric spans between them.
   Hairlines come from 1px grid gaps, matching the rest of the page.
   ═════════════════════════════════════════════════════════════════════ */
.pv-feature { border-top: 0; }
.pv-f-lead { border-bottom: 1px solid var(--rule); }
/* Replaced by the animated stroke-draw line (base.css/js/motion.js) when
   motion is enabled — hidden here so the draw-in isn't just retracing an
   already-visible line. prefers-reduced-motion restores it: motion.js
   never builds the SVG overlay in that case, so this is the only line
   those visitors get. Same device as #faq's items (pages.css). */
.pv-f-lead[data-stroke-draw] { border-bottom-color: transparent; }
@media (prefers-reduced-motion: reduce) {
  .pv-f-lead[data-stroke-draw] { border-bottom-color: var(--rule); }
}
.pv-f-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--rule);
}
.pv-f-item { background: var(--ground); }

/* ── The skeleton every variant shares ──────────────────────────────────────
   Copy block and media block, stacked in the three small cells and split
   left/right in the lead. The media row takes the leftover height (1fr), so
   the copy is always flush against an edge instead of floating mid-cell, and
   the sides alternate cell to cell so the row zig-zags.
   ═════════════════════════════════════════════════════════════════════ */
.pv-f-lead, .pv-f-item {
  position: relative;
  display: grid;
  gap: var(--s5);
  padding: var(--s6) var(--gutter);
}
.pv-f-copy { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s2); }
.pv-f-num {
  font-family: var(--font-data); font-size: var(--fs-data);
  letter-spacing: var(--track-data); color: var(--fg-faint); font-style: normal;
}
.pv-f-name {
  font-family: var(--font-display); font-weight: 400; line-height: 1;
  letter-spacing: var(--track-tight);
  font-size: var(--fs-h2);
}
.pv-f-lead .pv-f-name { font-size: var(--fs-h1); }
.pv-f-tag {
  font-size: var(--fs-text); color: var(--fg-muted); max-width: 24ch;
  text-transform: none; letter-spacing: 0;
}
.pv-f-lead .pv-f-tag { font-size: var(--fs-lead); line-height: var(--lh-snug); max-width: 20ch; }
.pv-price { font-size: var(--fs-text); }
.pv-f-badge { color: var(--accent); }

.pv-f-media { min-width: 0; display: flex; align-items: center; }
/* The glow layer is composed here rather than inside --shot-lift: var() in a
   custom property resolves where that property is declared, so a glow baked
   into :root could never see the cell's own --p-glow. */
.pv-f-media .p-shot {
  width: 100%; max-width: 100%; height: auto; margin: 0;
  border-radius: var(--shot-radius);
  box-shadow: var(--shot-lift), 0 14px 30px -14px var(--p-glow);
}
/* The lead shot is several times the size of the others, so it takes a cast
   scaled to match — the same shadow would read as a hairline against it. */
.pv-f-lead .p-shot { box-shadow: var(--shot-lift-lead), 0 30px 60px -26px var(--p-glow); }

@media (min-width: 48em) {
  .pv-f-lead { grid-template-columns: 1fr 1.7fr; align-items: center; padding: var(--s7) var(--s5); }
  .pv-f-item { grid-template-rows: auto 1fr; padding: var(--s6) var(--s5); }
  /* All three left-aligned, same order — the old zig-zag (even cells
     mirrored: shot first, copy right-aligned) read as inconsistent rather
     than composed. */
}

@media (min-width: 48em) {
  .pv-f-row { grid-template-columns: repeat(3, 1fr); }
}

/* ══ Micro-layouts ═══════════════════════════════════════════════════════
   The row of three stays equal-width in every [data-cell] variant now — no
   asymmetric spans. MASONRY staggers the three cells vertically; CASCADE
   pulls the row up to tuck under the lead's lower edge, same as before.
   ═════════════════════════════════════════════════════════════════════ */
@media (min-width: 48em) {
  :is([data-cell^="masonry"], [data-cell^="cascade"]) .pv-f-row {
    gap: var(--s6) var(--s5);
    background: var(--ground);
    padding: var(--s6) var(--s5) var(--s8);
  }
  :is([data-cell^="masonry"], [data-cell^="cascade"]) .pv-f-item {
    padding: 0; background: none;
  }
}

/* ── Arrangement: masonry ─────────────────────────────────────────────────
   Named for the falling stagger it used to have — dropped per feedback
   (the three cells read as misaligned, not composed), kept flush instead.
   The name stays since [data-cell] values are also the lab bar's stored
   choices; renaming would just orphan anyone's saved pick. */
@media (min-width: 48em) {
  [data-cell^="masonry"] .pv-f-item { align-self: start; }
}

/* ── Arrangement: cascade, rising and tucked under the lead ──────────────
   The negative top margin pulls the row into the lead's lower right, so the
   two read as one composition rather than a feature and a shelf below it.
   ═════════════════════════════════════════════════════════════════════ */
@media (min-width: 48em) {
  [data-cell^="cascade"] .pv-f-row { align-items: end; margin-top: calc(-1 * var(--s7)); }
  [data-cell^="cascade"] .pv-f-lead { border-bottom: 0; padding-bottom: var(--s8); }
  /* Cascade tucks the row up under the lead by design — no bottom line at
     all there, drawn or static. Without this, the stroke-draw SVG would
     still trace a line the design deliberately removes for this variant. */
  [data-cell^="cascade"] .pv-f-lead .stroke-draw-svg { display: none; }
  [data-cell^="cascade"] .pv-f-item { align-self: end; }
  [data-cell^="cascade"] .pv-f-item:nth-child(1) { margin-bottom: var(--s6); }
  [data-cell^="cascade"] .pv-f-item:nth-child(2) { margin-bottom: var(--s3); }
}

/* ── Copy treatment A — under the shot, behind a hairline ───────────────── */
@media (min-width: 48em) {
  :is([data-cell="masonry"], [data-cell="cascade"]) .pv-f-item { gap: 0; }
  :is([data-cell="masonry"], [data-cell="cascade"]) .pv-f-item .pv-f-media { order: -1; }
  :is([data-cell="masonry"], [data-cell="cascade"]) .pv-f-item .pv-f-copy {
    border-top: 1px solid var(--rule);
    margin-top: var(--s4); padding-top: var(--s4);
  }
}

/* ── Copy treatment B — name and price on one ruled row above the shot ──── */
@media (min-width: 48em) {
  :is([data-cell="masonry2"], [data-cell="cascade2"]) .pv-f-item { gap: var(--s5); }
  :is([data-cell="masonry2"], [data-cell="cascade2"]) .pv-f-item .pv-f-media { order: 0; }
  :is([data-cell="masonry2"], [data-cell="cascade2"]) .pv-f-item .pv-f-copy {
    display: grid; grid-template-columns: 1fr auto;
    align-items: baseline; column-gap: var(--s4); row-gap: var(--s2);
    border-bottom: 1px solid var(--rule); padding-bottom: var(--s3);
  }
  :is([data-cell="masonry2"], [data-cell="cascade2"]) .pv-f-item .pv-f-num { grid-column: 1 / -1; }
  /* The badge (FreeBounce's "Most Popular") needs the same full-span
     treatment as .pv-f-num/.pv-f-tag below — without it, badge and name
     shared row 1 as this grid's two columns, and name landed in the
     "price" column, right-aligned, on the one item that has a badge. */
  :is([data-cell="masonry2"], [data-cell="cascade2"]) .pv-f-item .pv-f-badge { grid-column: 1 / -1; }
  :is([data-cell="masonry2"], [data-cell="cascade2"]) .pv-f-item .pv-price { justify-self: end; }
  :is([data-cell="masonry2"], [data-cell="cascade2"]) .pv-f-item .pv-f-tag { grid-column: 1 / -1; max-width: none; }
}

/* ── Copy treatment C — shot and copy stacked, closed with a rule ───────── */
@media (min-width: 48em) {
  :is([data-cell="masonry3"], [data-cell="cascade3"]) .pv-f-item {
    gap: var(--s4);
  }
  :is([data-cell="masonry3"], [data-cell="cascade3"]) .pv-f-item .pv-f-media { order: -1; }
  :is([data-cell="masonry3"], [data-cell="cascade3"]) .pv-f-item .pv-f-copy {
    border-bottom: 1px solid var(--rule); padding-bottom: var(--s3);
  }
}

/* Entrance motion for the lead and each row item (except the row's first
   cell, which has no border-left to draw and reads fine simply present) is
   the stroke-draw primitive now (base.css, js/motion.js) — see the
   data-stroke-draw wiring above and in js/plugins.js. Replaced the old
   fade+translateY pv-reveal here; motion-system-handoff.md rules that
   pattern off-vocabulary as a primary reveal. */
