/* ─── catalogue-rows.css — row reveal variants (ROUGH DRAFT, html[data-rows]) ────
   js/rows-lab.js?v=18 sets html[data-rows]. `peek` (default) = no rules here: the
   existing combo peek in catalogue.css. All variants are desktop-hover only
   (≥64em, hover:hover); phones/touch keep the existing static stack.
   Open state (.is-open on the row) is still set by catalogue.js. Tokens only;
   radii are the draft-local vars. New motion (scale/tilt/pop, crossfade stage)
   approved by Jude 2026-10-15. */

/* Scroll runway per row: how far you scroll before the next catalogue row opens.
   --rx-runway-boost multiplies the old runway (phone 50svh, desktop 55svh per row).
   1 = old behaviour, 1.4 = 40% more scrolling per row. Tune this ONE number. */
:root { --rx-runway-boost: 1.4; }

.rx-stage { display: none; }
.rx-cat-big { display: none; }

@media (hover: hover) and (min-width: 64em) {
  /* A row that is open sits above its neighbours (float / thumb overlap them). */
  :root[data-rows] .rx-cat.is-open { z-index: 5; }

  /* ── float: the UI pops out over the rows, zero layout space ─────────────── */
  :root[data-rows="float"] .rx-cat-panel { position: absolute; inset: 0; display: block; pointer-events: none; }
  :root[data-rows="float"] .rx-cat-panel-in { display: block; overflow: visible; }
  :root[data-rows="float"] .rx-cat-shot,
  :root[data-rows="float"] .rx-cat.is-open .rx-cat-shot:hover {
    position: absolute; right: 12%; top: 50%; width: min(46rem, 34vw); height: auto; padding: 0; overflow: visible;
    opacity: 0; transform: translateY(-46%);
    transition: opacity 600ms var(--rx-ease), transform 800ms var(--rx-ease);
  }
  :root[data-rows="float"] .rx-cat-shot img { border-radius: var(--r-card); border: 1px solid color-mix(in srgb, var(--fg) 20%, transparent); aspect-ratio: auto; }
  :root[data-rows="float"] .rx-cat.is-open .rx-cat-shot { opacity: 1; transform: translateY(-50%); }

  /* ── thumb: peek, but with a thumbnail. The UI is always in the row (full, small);
     on hover the row grows downward and the same image swells smoothly inside it.
     Done by animating the grid's shot column (grid-template-columns interpolates),
     so the image and the row height move together. No overlap with neighbours. ── */
  :root[data-rows="thumb"] { --tw0: clamp(16rem, 15vw, 24rem); --tw1: clamp(24rem, 30vw, 50rem); }
  :root[data-rows="thumb"][data-rx-hover="combo"] .rx-cat {
    padding: var(--s3) var(--s6); align-items: start;
    grid-template-columns: 1fr var(--tw0) clamp(14rem, 16vw, 26rem) 8rem auto; grid-template-areas: "word shot id price cta";
    transition: color var(--rx-soft) ease-out 240ms, grid-template-columns var(--rx-dur) var(--rx-ease);
  }
  :root[data-rows="thumb"][data-rx-hover="combo"] .rx-cat.is-open { grid-template-columns: 1fr var(--tw1) clamp(14rem, 16vw, 26rem) 8rem auto; }
  :root[data-rows="thumb"][data-rx-hover="combo"] .rx-cat-panel,
  :root[data-rows="thumb"][data-rx-hover="combo"] .rx-cat-panel-in { display: contents; }
  :root[data-rows="thumb"][data-rx-hover="combo"] .rx-cat-shot,
  :root[data-rows="thumb"][data-rx-hover="combo"] .rx-cat.is-open .rx-cat-shot:hover { grid-area: shot; position: relative; z-index: 2; width: 100%; height: auto; padding: 0; margin-block: var(--s2); overflow: visible; transition: none; }
  :root[data-rows="thumb"] .rx-cat-shot img { aspect-ratio: auto; height: auto; object-fit: contain; border-radius: var(--r-card); border: 1px solid color-mix(in srgb, var(--fg) 18%, transparent); }
  :root[data-rows="thumb"] .rx-cat-word { font-size: clamp(4.8rem, 6.4vw, 9rem); padding-block: var(--s3) 0; }
  :root[data-rows="thumb"] :is(.rx-cat-id, .rx-cat-price, .rx-go) { align-self: start; padding-top: var(--s4); }

  /* ── stage: sticky showroom on the right; hover a row, the stage swaps ───── */
  :root[data-rows="stage"] .rx-cat-list { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); column-gap: var(--s6); padding-right: var(--s6); }
  :root[data-rows="stage"][data-rx-hover="combo"] .rx-cat { grid-column: 1; padding: var(--s3) var(--s6); grid-template-columns: 1fr auto; grid-template-areas: "word word" "id price"; }
  :root[data-rows="stage"] .rx-cat-word { font-size: clamp(6rem, 9vw, 11rem); padding-block: var(--s2) 0; }
  :root[data-rows="stage"] .rx-cat-panel, :root[data-rows="stage"] .rx-go { display: none; }
  :root[data-rows="stage"] .rx-cat-id { padding-bottom: var(--s3); }
  :root[data-rows="stage"] .rx-stage { display: block; grid-column: 2; grid-row: 1 / span 6; position: sticky; top: 14rem; align-self: start; height: min(62svh, 54rem); margin-block: var(--s4); overflow: hidden; border: 1px solid color-mix(in srgb, var(--rule) 60%, transparent); border-radius: var(--r-tray); background: var(--surface); }
  .rx-stage-img { position: absolute; inset: 0; display: grid; place-items: center; padding: var(--s5); opacity: 0; transform: scale(.96); transition: opacity 700ms var(--rx-ease), transform 900ms var(--rx-ease); }
  .rx-stage-img.is-on { opacity: 1; transform: none; }
  :root[data-rows="stage"] .rx-stage-img .rx-cat-shot { width: 100%; height: auto; padding: 0; margin: 0; overflow: visible; display: grid; place-items: center; transition: none; }
  :root[data-rows="stage"] .rx-stage-img .rx-cat-shot img { width: auto; height: auto; max-width: 100%; max-height: min(52svh, 46rem); aspect-ratio: auto; object-fit: contain; border-radius: var(--r-card); }

  /* ── full: the whole UI unfolds under the row (size comparison) ───────────── */
  :root[data-rows="full"] { --rx-peek-h: 52rem; --rx-peek-more: 0rem; }
  :root[data-rows="full"] .rx-cat-shot,
  :root[data-rows="full"] .rx-cat.is-open .rx-cat-shot:hover { width: min(70rem, 62%); }
  :root[data-rows="full"] .rx-cat-shot img { border-radius: var(--r-card) var(--r-card) 0 0; }
}


/* ── scroll: pinned scroll-through (≥64em, hover devices). rows-lab.js wraps the list
   in .rx-pinwrap > .rx-pin and moves the stage beside it; scroll progress picks the
   active plugin (sets .is-open on its row, so the existing bar/fill styling lights it)
   and the stage crossfades to its UI. The page is pinned for ~55svh per plugin. ── */
@media (hover: hover) and (min-width: 64em) {
  :root[data-rows="scroll"] .rx-pinwrap { position: relative; height: calc(100svh - 14rem + var(--n, 4) * 55svh * var(--rx-runway-boost)); }
  :root[data-rows="scroll"] .rx-pin { position: sticky; top: 14rem; height: calc(100svh - 14rem); display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); gap: var(--s6); padding-right: var(--s6); overflow: hidden; }
  :root[data-rows="scroll"] .rx-pin .rx-cat-list { display: grid; grid-template-rows: repeat(var(--n, 4), minmax(0, 1fr)); height: 100%; min-height: 0; }
  :root[data-rows="scroll"] .rx-pin .rx-cat { min-height: 0; overflow: hidden; }
  :root[data-rows="scroll"] .rx-pin .rx-badge { display: none; }
  :root[data-rows="scroll"] .rx-pin .rx-cat:not(.is-open) .rx-cat-tag { display: none; }
  :root[data-rows="scroll"][data-rx-hover="combo"] .rx-pin .rx-cat { grid-template-columns: 1fr auto; grid-template-areas: "word price" "id id"; align-content: center; padding: var(--s2) var(--s6); }
  :root[data-rows="scroll"] .rx-pin .rx-cat-word { font-size: clamp(4.4rem, 9.5svh, 8.8rem); padding-block: 0; }
  :root[data-rows="scroll"] .rx-pin :is(.rx-cat-panel, .rx-go) { display: none; }
  :root[data-rows="scroll"] .rx-pin .rx-cat:not(.is-open) { opacity: .42; }
  :root[data-rows="scroll"] .rx-pin .rx-cat { transition: opacity 600ms var(--rx-ease), color var(--rx-soft) ease-out 240ms; }
  :root[data-rows="scroll"] .rx-pin .rx-stage { display: block; position: relative; grid-column: 2; grid-row: auto; top: auto; align-self: stretch; height: auto; margin: 0; overflow: hidden; border: 1px solid color-mix(in srgb, var(--rule) 60%, transparent); border-radius: var(--r-tray); background: var(--surface); }
  :root[data-rows="scroll"] .rx-stage-img .rx-cat-shot { width: 100%; height: auto; padding: 0; margin: 0; overflow: visible; display: grid; place-items: center; transition: none; }
  :root[data-rows="scroll"] .rx-stage-img .rx-cat-shot img { width: auto; height: auto; max-width: 100%; max-height: calc(100svh - 30rem); aspect-ratio: auto; object-fit: contain; border-radius: var(--r-card); }
  .rx-pin-count { position: absolute; right: var(--s5); bottom: var(--s4); margin: 0; z-index: 3; font-family: var(--font-data); font-size: 1.2rem; letter-spacing: .2em; color: var(--fg-faint); }
}

/* ═══ Mobile / touch options (≤63.99em), html[data-mrows]. `now` = no rules. ═══
   tight : compact row — word + name + price left, the FULL UI small on the right.
   scroll: thumb mode, scroll-driven — the list pins, the row nearest the middle opens:
           its thumbnail fades and the full UI grows inside the row (rows-lab.js).
   full  : every row shows its whole UI at full width, text above, no cropping. */
@media (max-width: 63.99em) {
  :root[data-mrows][data-rx-hover="combo"] .rx-cat-panel,
  :root[data-mrows][data-rx-hover="combo"] .rx-cat-panel-in { display: contents; }
  :root[data-mrows][data-rx-hover="combo"] .rx-cat-shot { grid-area: shot; width: 100%; height: auto; padding: 0; margin: 0; overflow: visible; }
  :root[data-mrows][data-rx-hover="combo"] .rx-cat-shot img { aspect-ratio: 4 / 3; height: auto; object-fit: contain; background: var(--surface); border-radius: var(--r-card); border: 1px solid color-mix(in srgb, var(--fg) 16%, transparent); }

  :root[data-mrows="tight"][data-rx-hover="combo"] .rx-cat { grid-template-columns: 1fr 40%; grid-template-areas: "word shot" "id shot" "price shot"; align-items: center; padding: var(--s3) var(--s4); gap: var(--s1) var(--s4); }
  :root[data-mrows="tight"] .rx-cat-word { font-size: clamp(5rem, 15vw, 7.2rem); }
  :root[data-mrows="tight"] .rx-cat-tag,
  :root[data-mrows="tight"] .rx-go { display: none; }
  :root[data-mrows="tight"] .rx-cat-id,
  :root[data-mrows="tight"] .rx-cat-price { padding-bottom: 0; }

  /* scroll (mobile): pinned list, scroll picks the open row. Closed = word/name/price
     left + full-UI thumbnail right. Open = thumbnail fades, a full-width copy of the UI
     grows under the text (grid-template-rows 0fr → 1fr), all inside the pinned area so
     the page never jumps while you scroll. */
  :root[data-mrows="scroll"] .rx-pinwrap { position: relative; height: calc(100svh - 12rem + var(--n, 4) * 50svh * var(--rx-runway-boost)); }
  :root[data-mrows="scroll"] .rx-pin { position: sticky; top: 12rem; height: calc(100svh - 12rem); overflow: hidden; }
  :root[data-mrows="scroll"] .rx-pin .rx-cat-list { display: flex; flex-direction: column; height: 100%; transition: transform 800ms var(--rx-ease); will-change: transform; }
  :root[data-mrows="scroll"] .rx-pin.is-measuring, :root[data-mrows="scroll"] .rx-pin.is-measuring * { transition: none !important; }
  :root[data-mrows="scroll"][data-rx-hover="combo"] .rx-pin .rx-cat { flex: none; grid-template-columns: 1fr 36%; grid-template-areas: "word shot" "id shot" "big big"; grid-template-rows: auto auto 0fr; align-items: center; gap: 0 var(--s3); padding: var(--s2) var(--s4); transition: grid-template-rows 800ms var(--rx-ease); }
  :root[data-mrows="scroll"][data-rx-hover="combo"] .rx-pin .rx-cat.is-open { grid-template-rows: auto auto 1fr; box-shadow: inset .4rem 0 0 var(--p, var(--accent)); }
  :root[data-mrows="scroll"] .rx-pin .rx-cat-word { font-size: clamp(4.2rem, 12vw, 5.6rem); padding: 0; }
  :root[data-mrows="scroll"] .rx-pin :is(.rx-go, .rx-badge) { display: none; }
  :root[data-mrows="scroll"] .rx-pin .rx-cat-tag { font-size: 1rem; line-height: 1.4; }
  :root[data-mrows="scroll"] .rx-pin .rx-cat-price { grid-area: id; justify-self: end; align-self: start; }
  :root[data-mrows="scroll"] .rx-pin :is(.rx-cat-id, .rx-cat-price) { padding: 0; }
  :root[data-mrows="scroll"] .rx-pin .rx-cat-shot { transition: opacity 500ms var(--rx-ease); }
  :root[data-mrows="scroll"] .rx-pin .rx-cat.is-open .rx-cat-shot { opacity: 0; }
  :root[data-mrows="scroll"] .rx-pin .rx-cat { contain: layout style; }
  :root[data-mrows="scroll"] .rx-pin .rx-cat-big { display: block; grid-area: big; align-self: stretch; min-height: 0; overflow: hidden; }
  :root[data-mrows="scroll"] .rx-pin .rx-cat-big-in { display: block; padding-top: var(--s2); }
  :root[data-mrows="scroll"] .rx-pin .rx-cat-big img { display: block; width: 100%; height: auto; border-radius: var(--r-card); border: 1px solid color-mix(in srgb, var(--fg) 16%, transparent); }

  /* ── Mobile scroll: type & spacing variants (html[data-mtype]; `now` = no rules) ──────
     Scale (shared): verb word 4.6rem italic display → plugin name 2.4rem display →
     tagline 1.1rem mono caps, muted → price 1.3rem mono. Spacing on the --s scale;
     one left edge; name+tagline read as one group, the price is anchored to an edge.
     Open state in all three: the thumbnail collapses so the full UI gets the space.
       ledger : word / name+tagline / price stacked on one left edge; thumb 44% right.
       rail   : left = word, name, tagline; right rail = thumb with the price under it.
       split  : price sits top-right on the word's baseline (catalogue-number style),
                thumb right under it, name+tagline left. */
  :root[data-mrows="scroll"][data-mtype] .rx-pin .rx-cat-word { font-size: 4.6rem; line-height: .95; padding: 0; }
  :root[data-mrows="scroll"][data-mtype] .rx-pin .rx-cat-name { font-size: 2.4rem; line-height: 1.05; }
  :root[data-mrows="scroll"][data-mtype] .rx-pin .rx-cat-tag { font-size: 1.1rem; line-height: 1.45; color: var(--fg-muted); max-width: none; }
  :root[data-mrows="scroll"][data-mtype] .rx-pin .rx-cat-price { font-size: 1.3rem; line-height: 1; color: var(--fg); letter-spacing: .06em; justify-self: start; align-self: start; }
  :root[data-mrows="scroll"][data-mtype] .rx-pin .rx-cat-id { gap: var(--s1); align-content: start; }
  :root[data-mrows="scroll"][data-mtype] .rx-pin .rx-cat-shot { max-height: 24rem; transition: opacity 500ms var(--rx-ease), max-height 800ms var(--rx-ease); }
  :root[data-mrows="scroll"][data-mtype] .rx-pin .rx-cat.is-open .rx-cat-shot { max-height: 0; overflow: hidden; }
  :root[data-mrows="scroll"][data-mtype][data-rx-hover="combo"] .rx-pin .rx-cat { align-items: start; padding: var(--s3) var(--s4) var(--s3); row-gap: var(--s2); }

  :root[data-mrows="scroll"][data-mtype="ledger"][data-rx-hover="combo"] .rx-pin .rx-cat { grid-template-columns: 1fr 44%; grid-template-areas: "word shot" "id shot" "price shot" "big big"; grid-template-rows: auto auto auto 0fr; }
  :root[data-mrows="scroll"][data-mtype="ledger"][data-rx-hover="combo"] .rx-pin .rx-cat.is-open { grid-template-rows: auto auto auto 1fr; }
  :root[data-mrows="scroll"][data-mtype="ledger"] .rx-pin .rx-cat-id { margin-top: var(--s2); }
  :root[data-mrows="scroll"][data-mtype="ledger"] .rx-pin .rx-cat-price { grid-area: price; margin-top: var(--s1); }

  :root[data-mrows="scroll"][data-mtype="rail"][data-rx-hover="combo"] .rx-pin .rx-cat { grid-template-columns: 1fr 44%; grid-template-areas: "word shot" "id shot" "id price" "big big"; grid-template-rows: auto auto auto 0fr; }
  :root[data-mrows="scroll"][data-mtype="rail"][data-rx-hover="combo"] .rx-pin .rx-cat.is-open { grid-template-rows: auto auto auto 1fr; }
  :root[data-mrows="scroll"][data-mtype="rail"] .rx-pin .rx-cat-id { margin-top: var(--s2); }
  :root[data-mrows="scroll"][data-mtype="rail"] .rx-pin .rx-cat-price { grid-area: price; justify-self: end; align-self: end; }

  :root[data-mrows="scroll"][data-mtype="split"][data-rx-hover="combo"] .rx-pin .rx-cat { grid-template-columns: 1fr 38%; grid-template-areas: "word price" "id shot" "big big"; grid-template-rows: auto auto 0fr; }
  :root[data-mrows="scroll"][data-mtype="split"][data-rx-hover="combo"] .rx-pin .rx-cat.is-open { grid-template-rows: auto auto 1fr; }
  :root[data-mrows="scroll"][data-mtype="split"] .rx-pin .rx-cat-price { grid-area: price; justify-self: end; align-self: end; padding-bottom: .5rem; }

  :root[data-mrows="full"][data-rx-hover="combo"] .rx-cat { grid-template-columns: 1fr auto; grid-template-areas: "word word" "id price" "shot shot"; padding: var(--s3) var(--s4) var(--s4); }
  :root[data-mrows="full"] .rx-go { display: none; }
  :root[data-mrows="full"] .rx-cat-shot { margin-top: var(--s2); }
  :root[data-mrows="full"] .rx-cat-shot img { aspect-ratio: auto; }
}

/* ═══ Mobile DRAFT variants that scroll like a normal page (js/rows-mobile.js). ?mrows=reveal | settle | grow ═══
   Nothing is pinned, nothing transforms the list, scroll is never hijacked. --k (0..1) is set per row by the script
   (how close the row is to the focus line). Shared look: the same ledger type as `scroll`. */
@media (max-width: 63.99em) {
  /* shared: type + grid for all three */
  :root:is([data-mrows="reveal"], [data-mrows="settle"], [data-mrows="grow"])[data-rx-hover="combo"] .rx-cat { align-items: start; padding: var(--s3) var(--s4) var(--s4); row-gap: var(--s2); }
  :root:is([data-mrows="reveal"], [data-mrows="settle"], [data-mrows="grow"]) .rx-cat-word { font-size: 4.6rem; line-height: .95; padding: 0; }
  :root:is([data-mrows="reveal"], [data-mrows="settle"], [data-mrows="grow"]) .rx-cat-name { font-size: 2.4rem; line-height: 1.05; }
  :root:is([data-mrows="reveal"], [data-mrows="settle"], [data-mrows="grow"]) .rx-cat-tag { font-size: 1.1rem; line-height: 1.45; color: var(--fg-muted); max-width: none; }
  :root:is([data-mrows="reveal"], [data-mrows="settle"], [data-mrows="grow"]) .rx-cat-price { font-size: 1.3rem; line-height: 1; color: var(--fg); letter-spacing: .06em; justify-self: start; align-self: start; padding: 0; }
  :root:is([data-mrows="reveal"], [data-mrows="settle"], [data-mrows="grow"]) .rx-cat-id { padding: 0; gap: var(--s1); align-content: start; }
  :root:is([data-mrows="reveal"], [data-mrows="settle"], [data-mrows="grow"]) :is(.rx-go, .rx-badge) { display: none; }
  :root:is([data-mrows="reveal"], [data-mrows="settle"], [data-mrows="grow"]) .rx-cat-big { display: block; grid-area: big; align-self: stretch; min-height: 0; overflow: hidden; } /* stretch: fill the track so a 0fr row clips it */
  :root:is([data-mrows="reveal"], [data-mrows="settle"], [data-mrows="grow"]) .rx-cat-big img { display: block; width: 100%; height: auto; border-radius: var(--r-card); border: 1px solid color-mix(in srgb, var(--fg) 16%, transparent); }

  /* reveal: constant-height image bands that bloom as they pass the middle (transforms only: layout never changes) */
  :root[data-mrows="reveal"][data-rx-hover="combo"] .rx-cat { grid-template-columns: 1fr auto; grid-template-areas: "word word" "id price" "big big"; box-shadow: inset calc(var(--k, 0) * .4rem) 0 0 var(--p, var(--accent)); }
  :root[data-mrows="reveal"] .rx-cat-shot { display: none; }
  :root[data-mrows="reveal"] .rx-cat-price { grid-area: price; justify-self: end; }
  :root[data-mrows="reveal"] .rx-cat-big { aspect-ratio: 3 / 2; border-radius: var(--r-card); }
  :root[data-mrows="reveal"] .rx-cat-big-in { display: block; height: 100%; padding: 0; }
  :root[data-mrows="reveal"] .rx-cat-big img { height: 100%; object-fit: cover; object-position: 50% 0; transform-origin: 50% 0; will-change: transform;
    transform: scale(calc(1.32 - .32 * var(--k, 0))); filter: saturate(calc(.45 + .55 * var(--k, 0))); opacity: calc(.62 + .38 * var(--k, 0)); }

  /* settle + grow: thumbnail right, full UI opening underneath */
  :root:is([data-mrows="settle"], [data-mrows="grow"])[data-rx-hover="combo"] .rx-cat { grid-template-columns: 1fr 44%; grid-template-areas: "word shot" "id shot" "price shot" "big big"; }
  :root:is([data-mrows="settle"], [data-mrows="grow"]) .rx-cat-id { margin-top: var(--s2); }
  :root:is([data-mrows="settle"], [data-mrows="grow"]) .rx-cat-price { grid-area: price; margin-top: var(--s1); }
  :root:is([data-mrows="settle"], [data-mrows="grow"]) .rx-cat-big-in { display: block; padding-top: 0; }

  /* settle: smooth accordion, opens when scrolling pauses; the thumbnail melts away as the UI opens */
  :root[data-mrows="settle"][data-rx-hover="combo"] .rx-cat { grid-template-rows: auto auto auto 0fr; transition: grid-template-rows 700ms var(--rx-ease), box-shadow 500ms var(--rx-ease); }
  :root[data-mrows="settle"][data-rx-hover="combo"] .rx-cat.is-open { grid-template-rows: auto auto auto 1fr; box-shadow: inset .4rem 0 0 var(--p, var(--accent)); }
  :root[data-mrows="settle"] .rx-cat-shot { max-height: 24rem; transition: opacity 500ms var(--rx-ease), max-height 700ms var(--rx-ease); }
  :root[data-mrows="settle"] .rx-cat.is-open .rx-cat-shot { opacity: 0; max-height: 0; overflow: hidden; }
  :root[data-mrows="settle"] .rx-cat-big-in { padding-top: var(--s2); }

  /* grow: continuous, driven by --k (row height) and --bh (the image's natural height), in step with your scroll */
  :root[data-mrows="grow"][data-rx-hover="combo"] .rx-cat { grid-template-rows: auto auto auto auto; box-shadow: inset calc(var(--k, 0) * .4rem) 0 0 var(--p, var(--accent)); }
  :root[data-mrows="grow"] .rx-cat-big { height: calc(var(--k, 0) * var(--bh, 0px)); }
  :root[data-mrows="grow"] .rx-cat-big-in { padding-top: 0; }
  /* grow + plugin colour: the row's background fills with the plugin's colour as it grows (by --k), and its text
     eases to the contrast ink. Phone widths only: on desktop the same fill still comes from hover (.is-open). */
  :root[data-mrows="grow"][data-ra="field"][data-rx-hover] .rx-cat::after { opacity: var(--k, 0); transition: none; }
  :root:is([data-mrows="grow"], [data-mrows="settle"], [data-mrows="reveal"]) .rx-cat-big { position: relative; z-index: 1; }
  :root[data-mrows="grow"][data-ra="field"] .rx-cat { transition: none; color: color-mix(in srgb, var(--p-ink, var(--accent-fg)) calc(var(--k, 0) * 100%), var(--fg)); box-shadow: none; }
  :root[data-mrows="grow"][data-ra="field"] .rx-cat-tag { color: color-mix(in srgb, var(--p-ink, var(--accent-fg)) calc(var(--k, 0) * 100%), var(--fg-muted)); }
  :root[data-mrows="grow"][data-ra="field"] .rx-cat-price { color: inherit; }
  :root[data-mrows="grow"][data-ra="field"] .rx-cat-word b { color: color-mix(in srgb, var(--p-ink, var(--accent-fg)) calc(var(--k, 0) * 100%), var(--p)); }
  :root[data-mrows="grow"][data-ra="field"] .rx-cat .ed-v { color: color-mix(in srgb, var(--p-ink, var(--accent-fg)) calc(var(--k, 0) * 100%), var(--ground, #000));
    background: color-mix(in srgb, var(--p, var(--accent)) calc((1 - var(--k, 0)) * 100%), transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor calc(var(--k, 0) * 100%), transparent); }
  /* no thumbnail in grow: the UI appears once, growing under the text, so the same image is never shown twice */
  :root[data-mrows="grow"] .rx-cat-shot { display: none; }
  :root[data-mrows="grow"][data-rx-hover="combo"] .rx-cat { grid-template-columns: 1fr auto; grid-template-areas: "word word" "id price" "big big"; }
  :root[data-mrows="grow"] .rx-cat-price { grid-area: price; justify-self: end; margin-top: 0; }
  :root[data-mrows="grow"] .rx-cat-id { margin-top: 0; }
  @media (prefers-reduced-motion: reduce) { :root[data-mrows="settle"] .rx-cat, :root[data-mrows="settle"] .rx-cat-shot { transition: none; } }
}

/* ═══ Mobile `open` (the default, ?mrows=open): every card always shows its UI, scaled down so cards stay short; nothing changes
   size. As you scroll past, the card's background fills with the plugin colour (--k from js/rows-mobile.js). ═══ */
@media (max-width: 63.99em) {
  :root[data-mrows="open"][data-rx-hover="combo"] .rx-cat { grid-template-columns: 1fr 46%; grid-template-areas: "word shot" "id shot" "price shot"; align-items: start; padding: var(--s3) var(--s4); row-gap: var(--s2); column-gap: var(--s3); }
  :root[data-mrows="open"] .rx-cat-word { font-size: 4.2rem; line-height: .95; padding: 0; }
  :root[data-mrows="open"] .rx-cat-name { font-size: 2.2rem; line-height: 1.05; }
  :root[data-mrows="open"] .rx-cat-tag { font-size: 1.05rem; line-height: 1.45; color: var(--fg-muted); max-width: none; }
  :root[data-mrows="open"] .rx-cat-price { grid-area: price; font-size: 1.3rem; line-height: 1; color: var(--fg); letter-spacing: .06em; justify-self: start; align-self: start; padding: 0; }
  :root[data-mrows="open"] .rx-cat-id { padding: 0; gap: var(--s1); align-content: start; margin-top: var(--s1); }
  :root[data-mrows="open"] :is(.rx-go, .rx-badge) { display: none; }
  :root[data-mrows="open"] .rx-cat-big { display: none; }
  :root[data-mrows="open"] .rx-cat-shot { grid-area: shot; align-self: center; width: 100%; max-height: none; opacity: 1; position: relative; z-index: 1; } /* above the colour fill (.rx-cat::after, z-index 0), or the fill paints over the image */
  /* each UI keeps its own shape: the base mobile rule boxes images at 4:3 on a light background, which left white bars around the wider UIs */
  :root[data-mrows="open"][data-rx-hover="combo"] .rx-cat-shot img { aspect-ratio: auto; height: auto; object-fit: cover; background: none; }
  /* the plugin-colour fill, by --k */
  :root[data-mrows="open"][data-ra="field"][data-rx-hover] .rx-cat::after { opacity: var(--k, 0); transition: none; }
  :root[data-mrows="open"][data-ra="field"] .rx-cat { transition: none; color: color-mix(in srgb, var(--p-ink, var(--accent-fg)) calc(var(--k, 0) * 100%), var(--fg)); box-shadow: none; }
  :root[data-mrows="open"][data-ra="field"] .rx-cat-tag { color: color-mix(in srgb, var(--p-ink, var(--accent-fg)) calc(var(--k, 0) * 100%), var(--fg-muted)); }
  :root[data-mrows="open"][data-ra="field"] .rx-cat-price { color: inherit; }
  :root[data-mrows="open"][data-ra="field"] .rx-cat-word b { color: color-mix(in srgb, var(--p-ink, var(--accent-fg)) calc(var(--k, 0) * 100%), var(--p)); }
  :root[data-mrows="open"][data-ra="field"] .rx-cat .ed-v { color: color-mix(in srgb, var(--p-ink, var(--accent-fg)) calc(var(--k, 0) * 100%), var(--ground, #000));
    background: color-mix(in srgb, var(--p, var(--accent)) calc((1 - var(--k, 0)) * 100%), transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor calc(var(--k, 0) * 100%), transparent); }
  :root[data-mrows="open"][data-ra="field"] .rx-cat .kind-tag { color: inherit; }
}
@media (min-width: 64em) { .rv-m { display: none; } }
@media (max-width: 63.99em) { .rv-d { display: none; } }

/* ═══ Row accent on open (html[data-ra]) — what the plugin colour does when a row opens ═══
   `bar` = the original left-edge bar + inverted fill (no rules here). Every other option
   switches those off and uses the plugin's own colour (--p) differently. Works wherever
   .is-open is set: hover on desktop, scroll position on phones.
     led     the full stop becomes a lit hardware LED (glow swells)
     wash    the colour floods the row as light from the UI, behind the text
     marker  a highlighter stroke wipes in behind the verb word
     field   the whole row becomes a flat field of the plugin colour
     misreg  the UI gets a hard offset print-registration slab in the colour
     rules   hairlines draw outward from the centre along the top and bottom edge */
:root[data-ra]:not([data-ra="bar"]) .rx-cat::before,
:root[data-ra]:not([data-ra="bar"]) .rx-cat::after { content: none; }
:root[data-ra]:not([data-ra="bar"]) .rx-cat.is-open { color: inherit; }
:root[data-ra]:not([data-ra="bar"]) .rx-cat.is-open :is(.rx-cat-tag, .rx-cat-price) { opacity: 1; }
:root[data-ra]:not([data-ra="bar"])[data-mrows="scroll"][data-rx-hover="combo"] .rx-pin .rx-cat.is-open { box-shadow: none; }

:root[data-ra="led"] .rx-cat-word b { display: inline-block; transition: color 700ms var(--rx-ease); }
:root[data-ra="led"] .rx-cat.is-open .rx-cat-word b { color: var(--p); }

:root[data-ra="wash"][data-rx-hover] .rx-cat::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 0; transition: opacity 800ms ease; background: radial-gradient(ellipse 60% 150% at var(--wx, 40%) 50%, color-mix(in srgb, var(--p) 36%, transparent), transparent 72%); }
:root[data-ra="wash"] .rx-cat.is-open::after { opacity: 1; }
:root[data-ra="wash"][data-mrows="scroll"] .rx-cat { --wx: 82%; }

:root[data-ra="marker"] .rx-cat-word { justify-self: start; width: fit-content; background: linear-gradient(transparent 56%, color-mix(in srgb, var(--p) 60%, transparent) 56% 90%, transparent 90%) no-repeat 0 0 / 0% 100%; transition: background-size 800ms var(--rx-ease); }
:root[data-ra="marker"] .rx-cat.is-open .rx-cat-word { background-size: 100% 100%; }

:root[data-ra="field"][data-rx-hover] .rx-cat::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background: var(--p); opacity: 0; transition: opacity 600ms ease; }
:root[data-ra="field"] .rx-cat.is-open::after { opacity: 1; }
:root[data-ra="field"][data-rx-hover] .rx-cat.is-open { color: var(--p-ink, var(--accent-fg)); }
:root[data-ra="field"] .rx-cat.is-open :is(.rx-cat-word b, .rx-cat-tag, .rx-cat-price) { color: inherit; }
:root[data-ra="field"] .rx-cat { transition: color 600ms ease; }

:root[data-ra="misreg"] .rx-cat-shot img, :root[data-ra="misreg"] .rx-cat-big img { box-shadow: 0 0 0 0 var(--p); transition: box-shadow 700ms var(--rx-ease); }
:root[data-ra="misreg"] .rx-cat.is-open .rx-cat-shot img, :root[data-ra="misreg"] .rx-cat.is-open .rx-cat-big img { box-shadow: 0 0 0 1px var(--p); }
:root[data-ra="misreg"][data-mrows="scroll"] .rx-pin .rx-cat-big-in { padding-right: 1rem; padding-bottom: 1rem; }

:root[data-ra="rules"][data-rx-hover] .rx-cat::before, :root[data-ra="rules"][data-rx-hover] .rx-cat::after { content: ""; position: absolute; left: 0; right: 0; height: 2px; z-index: 3; background: var(--p); transform: scaleX(0); transform-origin: 50% 50%; transition: transform 800ms var(--rx-ease); pointer-events: none; }
:root[data-ra="rules"] .rx-cat::before { top: -1px; }
:root[data-ra="rules"] .rx-cat::after { bottom: -1px; }
:root[data-ra="rules"] .rx-cat.is-open::before, :root[data-ra="rules"] .rx-cat.is-open::after { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) { :root[data-ra] .rx-cat, :root[data-ra] .rx-cat::before, :root[data-ra] .rx-cat::after, :root[data-ra] .rx-cat-word, :root[data-ra] .rx-cat-word b, :root[data-ra] .rx-cat-shot img, :root[data-ra] .rx-cat-big img { transition: none !important; } }

:root[data-snap] .rx-cat, :root[data-snap] .rx-cat-shot, :root[data-snap] .rx-cat-big, :root[data-snap] .rx-cat-list { transition: none !important; }
.rv-sep { width: 1px; align-self: stretch; background: var(--rule); flex: none; }
@media (prefers-reduced-motion: reduce) { .rx-stage-img, :root[data-rows] .rx-cat-shot { transition: none !important; } }
