/*
  /work/vtsuite — layout only, in the site's existing vocabulary.

  RULES THIS FILE KEEPS, because the first version broke all of them and read as a generic marketing
  page dropped into the site:

    · No colour literals. Every colour is a token (--accent, --text-*, --surface-*, --line*).
    · No border-radius on panels. The site's panels are square; the two radii the site DOES use are
      --radius-pill (chips, the crumb) and --radius-1 (solid badges), and those are kept.
    · No new type sizes. Sizes come from the --text-* scale, headings from .display.
    · Every label is JetBrains Mono, uppercase, at --tracking-caps, in --accent. That is how the site
      writes a label, everywhere.
    · Panels are 1px --line-strong on --surface-panel, and go --accent on hover, exactly like .post.

  .col already supplies the horizontal gutter (padding: 0 24px), so this file only ever sets
  padding-block. A padding shorthand on a .col element silently removes that gutter and runs text to
  the edge of the viewport, which is what happened the first time.

  WHAT THIS PASS ADDS: the track (a hairline spine with one node per plugin), the catalogue controls,
  the sealed name slot, the not-out mark, and the buy slot. Everything else is unchanged.
*/

/* ── reveal ──────────────────────────────────────────────────────────────────
   The page used v2.css's .rv, which is opacity:0 until v2.js adds .in. v2.js is
   the HOME PAGE's script: it dereferences #loader and other elements this page
   does not have, so it threw on every load and the three section labels stayed
   invisible. Measured in a browser console, not guessed.

   This is the idiom the sibling demo pages already use: default VISIBLE, and the
   hidden-then-animate state only exists once the script has added a class saying
   it is definitely going to run. No JS, an error, or reduced motion, and
   everything simply paints.                                                     */

.vts-rv { opacity: 1; }

@media screen and (prefers-reduced-motion: no-preference) {
  html.vts-ready .vts-rv {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
  }

  html.vts-ready .vts-rv.is-in {
    opacity: 1;
    transform: none;
  }
}

/* ── breadcrumb ──────────────────────────────────────────────────────────────
   Ported from the demo sub-pages, which are the only place .cp-crumb was ever
   defined. This page used the class from day one and rendered it unstyled: a
   bare inline link where the other sub-pages show a pill.                      */

.cp-crumb {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-mono);
  color: var(--text-secondary);
  text-decoration: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 5px 12px 5px 10px;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
    background var(--dur-fast) var(--ease-out);
}

.cp-crumb:hover {
  color: var(--text-primary);
  border-color: var(--line-strong);
  background: var(--surface-panel);
}

.cp-crumb .arr {
  color: var(--accent);
  font-style: normal;
  display: inline-flex;
  transition: transform var(--dur-base) var(--ease-out);
}

.cp-crumb:hover .arr { transform: translateX(-3px); }
.cp-crumb .sep { opacity: 0.5; }
.cp-crumb .cur { color: var(--text-primary); }

body[data-flood="3"] .cp-crumb .arr { color: var(--text-primary); }

/* ── header ──────────────────────────────────────────────────────────────────
   The suite-level stat row is gone. It counted the roadmap ("1 shipping, 4 in
   development"), which made the page's subject the schedule rather than the
   products, and it hoisted per-plugin facts (test counts, dependency claims) to
   a level where nothing can prove them. Those facts now sit on the plugin that
   owns them.                                                                   */

.vts-head {
  padding-block: 128px 40px;
}

.vts-kicker {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 18px;
}

body[data-flood="3"] .vts-kicker { color: var(--text-primary); }

.vts-title {
  font-size: clamp(48px, 9vw, 104px);
  margin-bottom: 24px;
}

.vts-lede {
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  max-width: 40ch;
  color: var(--text-primary);
  margin: 0 0 18px;
}

.vts-sub {
  max-width: 62ch;
  line-height: var(--leading-body);
  color: var(--text-secondary);
  margin: 0;
}

/* ── sections ────────────────────────────────────────────────────────────────
   THE GUTTER. v2.css sets .col { padding: 0 24px } at line 7 and .sec { padding:
   110px 0 0 } at line 116. Equal specificity, later wins, so ANY element that
   carries both classes loses its inline gutter — the home page included, which is
   why v2.css line 2071 puts it back by hand for .sec.col under 760px. Between
   761px and 1280px a .sec.col element sits flush against the viewport.

   This page cannot inherit that: its header is a plain .col (24px) while its
   sections are .sec.col (0px), so the two would disagree and the track would run
   past the title. The gutter is restored here for .vts-sec only, at the same 24px
   / 18px the site uses, so header, sections and footer share one edge.          */

.vts-sec { padding-block: 0 24px; padding-inline: 24px; }

.vts-idx {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--accent);
}

body[data-flood="3"] .vts-idx { color: var(--text-primary); }

/* ── catalogue controls ──────────────────────────────────────────────────────
   Chips keep --radius-pill, like every other chip on the site. The active chip
   is the only filled one; --accent-soft is the runtime-derived accent + "22", so
   it tracks the palette instead of hard-coding a tint.                         */

.vts-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 18px 32px;
  align-items: center;
  justify-content: space-between;
  margin-top: 32px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
}

.vts-filter,
.vts-sort {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.vts-ctl-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-right: 4px;
}

.vts-chip {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-secondary);
  text-decoration: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 5px 11px;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
    background var(--dur-fast) var(--ease-out);
}

.vts-chip b { font-weight: 400; opacity: 0.55; margin-left: 4px; }

.vts-chip:hover { color: var(--text-primary); border-color: var(--line-strong); }

.vts-chip.is-on {
  color: var(--text-primary);
  border-color: var(--accent);
  background: var(--accent-soft);
}

body[data-flood="3"] .vts-chip.is-on { border-color: var(--text-primary); background: none; }

.vts-sortlink {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-secondary);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.vts-sortlink:hover { color: var(--text-primary); border-color: var(--line-strong); }
.vts-sortlink.is-on { color: var(--text-primary); border-color: var(--accent); }

body[data-flood="3"] .vts-sortlink.is-on { border-color: var(--text-primary); }

/* ── the track ───────────────────────────────────────────────────────────────
   One list, ship order, hairline spine. The spine is drawn by each entry rather
   than by the container so a filtered list never leaves a line hanging past the
   last visible row: every entry paints its own segment, and the last one stops
   at its node.                                                                 */

.vts-track {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.vts-entry {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  align-items: start;
}

.vts-entry[hidden] { display: none; }

/* The node: filled ring for something you can install today, hollow for
   something you cannot yet. That ring is the ENTIRE status language on this
   page — there is no badge row, no "in development" label, no wave. */

.vts-node {
  position: relative;
  align-self: stretch;
  display: block;
}

.vts-node::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 26px;
  bottom: -1px;
  width: 1px;
  background: var(--line);
}

.vts-node::after {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  width: 11px;
  height: 11px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: none;
}

.vts-entry--out .vts-node::after {
  border-color: var(--accent);
  background: var(--accent);
}

body[data-flood="3"] .vts-entry--out .vts-node::after {
  border-color: var(--text-primary);
  background: var(--text-primary);
}

.vts-node--last::before { display: none; }

/* ── entry 01: the product card ──────────────────────────────────────────── */

.vts-card {
  margin: 0 0 16px;
  background: var(--surface-panel);
  border: 1px solid var(--line-strong);
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.vts-card:hover {
  background: var(--surface-raise);
  border-color: var(--accent);
}

body[data-flood="3"] .vts-card:hover { border-color: var(--text-primary); }

.vts-card-head {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  border-bottom: 1px solid var(--line);
}

/* The one solid badge on the page, so it keeps --radius-1 rather than the pill. */
.vts-badge {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--accent-ink);
  background: var(--accent);
  border-radius: var(--radius-1);
  padding: 4px 9px;
}

.vts-card-body {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 36px;
  align-items: start;
  padding: 28px 24px;
}

.vts-shots { display: flex; flex-direction: column; gap: 8px; }

.vts-shot { margin: 0; }

.vts-shot img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--line);
}

.vts-shot-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }  /* two, since the third was the same render as the figure above it */

.vts-shot--sm img { aspect-ratio: 4 / 3; object-fit: cover; }
/* A photograph survives being cropped to the tile; a diagram does not, because the parts it
   crops away are the labels that make it a diagram. */
.vts-shot--sm img[src$=".svg"] { object-fit: contain; background: var(--surface-page); }

.vts-plug-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.vts-plug-title {
  font-size: clamp(28px, 3.4vw, var(--text-2xl));
  margin: 0;
}

.vts-plug-tag {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--accent);
  letter-spacing: var(--tracking-mono);
}

body[data-flood="3"] .vts-plug-tag { color: var(--text-primary); }

.vts-plug-copy {
  margin: 0;
  line-height: var(--leading-body);
  color: var(--text-secondary);
}

.vts-plug-copy code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  color: var(--text-primary);
}

.vts-feat {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 7px;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  line-height: 1.45;
}

.vts-feat li { padding-left: 18px; position: relative; }

.vts-feat li::before {
  content: "▪";
  position: absolute;
  left: 0;
  color: var(--accent);
}

body[data-flood="3"] .vts-feat li::before { color: var(--text-primary); }

/* Same chip treatment the work cards use for their skill pool. */
.vts-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}

.vts-chips span {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--text-secondary);
  border: 1px solid var(--line);
  padding: 3px 7px;
}

/* ── the action pair: docs (live) + buy (reserved) ───────────────────────────
   Both children are the same height and sit on one baseline, so when the Fab
   listing goes live and .vts-buy becomes an <a href>, the only thing that
   changes is the border and the cursor. Nothing reflows, nothing moves down the
   page, and no layout work is owed at launch.                                  */

.vts-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  margin-top: 8px;
}

.vts-link {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--text-primary);
  text-decoration: none;
  border-bottom: 1px solid var(--accent);
  padding-bottom: 3px;
}

.vts-link i { font-style: normal; color: var(--accent); }

.vts-link:hover { color: var(--accent); }

body[data-flood="3"] .vts-link { border-color: var(--text-primary); }
body[data-flood="3"] .vts-link i { color: var(--text-primary); }

.vts-buy {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  text-decoration: none;
  border: 1px dashed var(--line-strong);
  padding: 7px 13px;
  cursor: default;
  user-select: none;
}

.vts-buy i {
  font-style: normal;
  letter-spacing: var(--tracking-mono);
  opacity: 0.7;
}

/* The live state, for the day the listing exists: an <a class="vts-buy"> picks
   this up automatically and the dashed slot becomes a solid button. */
a.vts-buy {
  color: var(--accent-ink);
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius-1);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}

a.vts-buy i { opacity: 1; }

a.vts-buy:hover { background: var(--hot); border-color: var(--hot); }

/* ── entries 02-05: the same list, one row each ───────────────────────────────
   Full-strength type: these are products that are not purchasable yet, not
   placeholders. The row carries no status vocabulary — a sealed name slot and a
   quiet mark are the whole of it.                                              */

.vts-row {
  margin: 0 0 12px;
  padding: 16px 20px;
  background: var(--surface-panel);
  border: 1px solid var(--line);
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.vts-row:hover {
  background: var(--surface-raise);
  border-color: var(--line-strong);
}

.vts-row-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  margin-bottom: 10px;
}

.vts-row-meta {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
}

/* The sealed slot: the name's own place, held open and visibly empty, so the
   page never pretends the product is nameless — only that the name is not
   public yet. */
.vts-slot {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-secondary);
  border: 1px dashed var(--line-strong);
  padding: 4px 10px;
}

.vts-domain {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--text-secondary);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 3px 9px;
}

.vts-mark {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-secondary);
  opacity: 0.8;
}

.vts-row-copy {
  margin: 0;
  max-width: 78ch;
  color: var(--text-primary);
  line-height: var(--leading-body);
  font-size: var(--text-sm);
}

.vts-empty {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 20px 0 0;
}

.vts-empty a { color: var(--text-primary); text-decoration: none; border-bottom: 1px solid var(--accent); }

/* ── grids of smaller panels ─────────────────────────────────────────────── */

.vts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin-top: 36px;
}

.vts-grid--three { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }

.vts-mini {
  background: var(--surface-panel);
  border: 1px solid var(--line-strong);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.vts-mini:hover {
  background: var(--surface-raise);
  border-color: var(--accent);
}

body[data-flood="3"] .vts-mini:hover { border-color: var(--text-primary); }

.vts-mini h3 {
  margin: 0;
  font-family: var(--font-display);
  font-stretch: 125%;
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(18px, 1.7vw, 24px);
  line-height: 1.05;
  color: var(--text-primary);
}

.vts-mini p {
  margin: 0;
  color: var(--text-secondary);
  line-height: var(--leading-body);
  font-size: var(--text-sm);
}

/* ── closing ─────────────────────────────────────────────────────────────── */

.vts-cta { padding-block: 40px 96px; }

.vts-cta h2 {
  font-size: clamp(28px, 4vw, var(--text-2xl));
  margin: 18px 0;
}

.vts-cta-lede {
  max-width: 58ch;
  line-height: var(--leading-body);
  color: var(--text-secondary);
  margin: 0;
}

/* One baseline, same as the card's action row, so the page has one way of presenting a pair of
   actions rather than two. */
.vts-cta-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px 22px;
  margin-top: 26px;
}

.vts-cta-mail {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-mono);
  color: var(--text-secondary);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding-bottom: 3px;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.vts-cta-mail:hover {
  color: var(--text-primary);
  border-color: var(--line-strong);
}

/* The signature line. Mono and uppercase like every other label on the site, separated by the
   site's own hairline rather than by punctuation. */
.vts-cta-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  margin: 34px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-secondary);
}

.vts-cta-who { color: var(--text-primary); }

/* --ok, not --accent: this is a promise being kept, and the site already uses the ok colour for a
   settled state. In Carbon dark the two happen to be the same lime; in light they are not. */
.vts-cta-ok { color: var(--green); }

body[data-flood="3"] .vts-cta-who,
body[data-flood="3"] .vts-cta-ok { color: var(--text-primary); }

/* ── narrow ──────────────────────────────────────────────────────────────── */

@media screen and (max-width: 900px) {
  .vts-head { padding-block: 96px 28px; }
  .vts-card-body { grid-template-columns: 1fr; gap: 24px; padding: 20px; }
  .vts-card-head { padding: 12px 20px; }
  .vts-controls { justify-content: flex-start; }
  .vts-entry { grid-template-columns: 22px minmax(0, 1fr); }
  .vts-row-meta { margin-left: 0; }
}

/* The site's own narrow gutter (v2.css line 2071), matched. */
@media screen and (max-width: 760px) {
  .vts-sec { padding-inline: 18px; }
}

/* light theme, 2026-09-05: labels are --accent everywhere in this file (rule 4). The accent is lime in both
   themes now, and lime on the light paper is 1.04:1, so in light every accent LABEL and accent HAIRLINE takes
   the text colour. Lime surfaces (.vts-badge, a.vts-buy) are unchanged: their text is --accent-ink, which the
   runtime sets to the text colour in light. The filled node keeps its lime fill and gains an ink border. */
html[data-theme="light"] .cp-crumb .arr,
html[data-theme="light"] .vts-kicker,
html[data-theme="light"] .vts-idx,
html[data-theme="light"] .vts-plug-tag,
html[data-theme="light"] .vts-feat li::before,
html[data-theme="light"] .vts-link i,
html[data-theme="light"] .vts-link:hover { color: var(--text-primary); }
html[data-theme="light"] .vts-link,
html[data-theme="light"] .vts-empty a { border-bottom-color: var(--text-primary); }
html[data-theme="light"] .vts-entry--out .vts-node::after { border-color: var(--text-primary); }
