/* ============================================================
   Product lineup. Ported from the mockup's .spec-table / .spec-table--lineup
   (styles/photoheads.css), including its frozen Model column and the phone
   card layout the lens table already uses.

   Four presets, the same four names the spec and lens blocks use, so three
   tables on one page can be set to read as one surface. `striped` is the
   mockup's, and the default.

   THE CLASS SUFFIXES ARE A CONTRACT, not a naming preference: __table, __sort,
   __sortlabel, __arrows, __sortbar(-label|-select) and __status are what
   assets/js/table-sort.js builds its selectors from, off the prefix in
   data-vt-sort. The lens table's stylesheet carries the same set under its own
   prefix. Renaming one here silently disables sorting.

   WHERE THIS TABLE DIFFERS FROM THE LENS TABLE, and why: almost every cell is
   PROSE, not a measurement. So cells wrap, they align left and top instead of
   right and middle, and the model column is frozen while the rest scrolls —
   eight columns of sentences do not fit any screen, and the mockup's own answer
   (Petter 2026-06-22) was to freeze the identifier rather than shrink the text.
   ============================================================ */
.vt-lineup {
  /* The block spans its column: a section's stack is a flex column with
     align-items: flex-start. See BLOCKS.md trap 9. */
  width: 100%;
  /* One knob for cell gutters, so a preset changes it in one line instead of
     restating padding on three selectors. */
  --vt-lineup-pad-x: 16px;
  /* What a frozen cell slides over. Every row and state that changes its own
     background re-declares this, or the frozen cell would show the row
     underneath through it. */
  --vt-lineup-frozen-bg: var(--color-surface);
}

/* The table scrolls inside its OWN container, never the page. Eight columns of
   prose fit no screen, and a page that scrolls sideways is broken in a way a
   table that scrolls is not. */
.vt-lineup__scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.vt-lineup__table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  /* The mockup's 13.5px. A comparison table is read by scanning across, and the
     15px the lens table uses costs a column at this width. */
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--vt-fg, var(--color-text));
  /* the mockup's own minimum: below this the columns collapse into unreadable
     slivers, so the container scrolls instead */
  min-width: 1100px;
}

.vt-lineup__caption {
  caption-side: top;
  text-align: left;
  padding: 16px var(--vt-lineup-pad-x) 4px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--vt-fg-muted, var(--color-text-muted));
  text-wrap: pretty;
}

.vt-lineup__head {
  padding: 14px var(--vt-lineup-pad-x);
  text-align: left;
  vertical-align: bottom;
  font-size: max(11px, var(--fs-floor, 0px));
  font-weight: var(--fw-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vt-fg-muted, var(--color-text-muted));
  border-bottom: 1px solid var(--color-border);
  /* HEADS WRAP, where the mockup's nowrap, and this is the difference between
     the table fitting a desktop and not. Measured at 1440 in the 1146px content
     column: eight nowrapped heads want 1230px of table against 1144px of column,
     so the whole comparison sits behind a sideways scroll on every desktop
     there is — the widest cells being the LABELS ("TYPICAL APPLICATIONS",
     "ALIGNMENT CAMERA"), not the data. Letting them take two lines costs 17px of
     table height and brings the table to exactly 1144. The mockup gets away with
     nowrap because it accepts the scroll; the frozen Model column is still here
     for the viewports that genuinely need it. */
  white-space: normal;
}

/* ------------------------------------------------------------
   Sortable heads. A real <button> in the <th>, so it is focusable and
   Enter/Space-operable; the state lives in the <th>'s aria-sort and the
   triangles are decoration. Kept visually identical to the lens table's BY HAND
   — both sheets say so, and both are the same 8x15px pair of bordered
   pseudo-elements with EMPTY content, so a screen reader is told nothing a
   `content: "▾"` glyph would have exposed.
   ------------------------------------------------------------ */
.vt-lineup__sort {
  /* the head cell already owns the padding and the alignment; the button is
     only the hit area, so it inherits everything and adds nothing */
  display: inline-flex;
  /* flex-END, not centre: the label may take two lines (see .vt-lineup__head),
     and an arrow pair floating halfway up a two-line label reads as unattached.
     The head cell is bottom-aligned, so the arrows sit on the last line. */
  align-items: flex-end;
  gap: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  cursor: pointer;
}
.vt-lineup__sort:hover { color: var(--color-dark-purple); }
.vt-lineup__sort:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: 3px;
}

.vt-lineup__arrows {
  position: relative;
  flex: 0 0 auto;
  width: 8px;
  height: 15px;
  margin-left: 7px;
}
.vt-lineup__arrows::before,
.vt-lineup__arrows::after {
  content: "";
  position: absolute;
  left: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
}
.vt-lineup__arrows::before {
  top: 1px;
  border-bottom: 5px solid var(--color-light-purple-40);
}
.vt-lineup__arrows::after {
  bottom: 1px;
  border-top: 5px solid var(--color-light-purple-40);
}
.vt-lineup__sort:hover .vt-lineup__arrows::before { border-bottom-color: var(--color-light-purple-60); }
.vt-lineup__sort:hover .vt-lineup__arrows::after { border-top-color: var(--color-light-purple-60); }

/* The active column. `[aria-sort]` is the selector on purpose — the attribute IS
   the state, so the paint can never disagree with what a screen reader is told. */
.vt-lineup__head[aria-sort] .vt-lineup__sort { color: var(--color-dark-purple); }
.vt-lineup__head[aria-sort="ascending"] .vt-lineup__arrows::before,
.vt-lineup__head[aria-sort="descending"] .vt-lineup__arrows::after {
  border-bottom-color: var(--color-dark-purple);
  border-top-color: var(--color-dark-purple);
}
/* the inactive half of the active column recedes rather than disappearing —
   it is still the affordance for reversing */
.vt-lineup__head[aria-sort="ascending"] .vt-lineup__arrows::after { border-top-color: var(--color-light-purple-20); }
.vt-lineup__head[aria-sort="descending"] .vt-lineup__arrows::before { border-bottom-color: var(--color-light-purple-20); }

/* On a dark section the resting triangles need the surface's own foreground —
   light purple on ink is invisible. */
.vt-section.is-dark .vt-lineup__arrows::before { border-bottom-color: color-mix(in srgb, #ffffff 35%, transparent); }
.vt-section.is-dark .vt-lineup__arrows::after { border-top-color: color-mix(in srgb, #ffffff 35%, transparent); }
.vt-section.is-dark .vt-lineup__head[aria-sort] .vt-lineup__sort { color: var(--vt-fg); }
.vt-section.is-dark .vt-lineup__head[aria-sort="ascending"] .vt-lineup__arrows::before,
.vt-section.is-dark .vt-lineup__head[aria-sort="descending"] .vt-lineup__arrows::after {
  border-bottom-color: #ffffff;
  border-top-color: #ffffff;
}
.vt-section.is-dark .vt-lineup__head[aria-sort="ascending"] .vt-lineup__arrows::after { border-top-color: color-mix(in srgb, #ffffff 22%, transparent); }
.vt-section.is-dark .vt-lineup__head[aria-sort="descending"] .vt-lineup__arrows::before { border-bottom-color: color-mix(in srgb, #ffffff 22%, transparent); }

/* The phone sort control. Built by assets/js/table-sort.js and hidden here until
   the head row goes away, so there is never more than one sort affordance on
   screen. */
.vt-lineup__sortbar { display: none; }

/* ------------------------------------------------------------
   Cells
   ------------------------------------------------------------ */
.vt-lineup__name {
  padding: 14px var(--vt-lineup-pad-x);
  text-align: left;
  vertical-align: top;
  font-family: var(--font-display);
  font-weight: var(--fw-medium);
  font-size: 15px;
  /* the model is the row's identifier, and dark purple is how this design marks
     an identifier — 7.4:1 on white, 6.5:1 on the mist band */
  color: var(--color-dark-purple);
  white-space: nowrap;
}
.vt-lineup__cell {
  padding: 14px var(--vt-lineup-pad-x);
  text-align: left;
  /* Top, not the default middle: a "Typical applications" cell runs to three
     lines while "PCB" next to it runs to one, and centring the short cells
     against the tall one makes the row read as a stagger. Same fix the spec
     grid needed for the same reason (BLOCKS.md: align-items on the spec grid). */
  vertical-align: top;
  color: var(--vt-fg-muted, var(--color-text-muted));
  text-wrap: pretty;
}
.vt-lineup__cell--num {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.vt-lineup__cell.is-empty { color: var(--vt-fg-subtle, var(--color-text-subtle)); }

/* The second column is the one a reader is actually comparing on — the mockup's
   .col-em, in the body face rather than the muted one. It is keyed off position,
   not off a column key, because WHICH spec that is depends on the family: line
   and space for a photohead, resolution for an AM engine. */
.vt-lineup__row > .vt-lineup__cell:first-of-type {
  font-family: var(--font-display);
  font-weight: var(--fw-medium);
  color: var(--vt-fg, var(--color-text));
  white-space: nowrap;
}

.vt-lineup__unit {
  margin-left: 3px;
  font-size: 0.84em;
  color: var(--vt-fg-muted, var(--color-text-muted));
}

/* vt_status, badged — the honest half of the mockup's flagship treatment. Only
   coming-soon and legacy render one: `available` is the norm and a badge on
   every row says nothing. Dark purple rather than the light purple the mockup's
   status pill wears, because white on light purple measures 4.11:1 and at 10.5px
   bold this is not large text (the same number the lens badge records). */
.vt-lineup__badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 7px;
  border-radius: 100px;
  font-family: var(--font-body);
  font-size: max(10.5px, var(--fs-floor, 0px));
  font-weight: var(--fw-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: middle;
  white-space: nowrap;
}
.vt-lineup__badge--coming-soon { background: var(--color-dark-purple); color: #ffffff; }
.vt-lineup__badge--legacy {
  background: var(--color-bg-subtle);
  color: var(--color-text-muted);
  box-shadow: inset 0 0 0 1px var(--color-border);
}

/* ---- preset: carded, zebra rows (the mockup, and the default) ---- */
.vt-lineup--striped .vt-lineup__scroll,
.vt-lineup--boxed .vt-lineup__scroll {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}
.vt-lineup--striped .vt-lineup__row:nth-child(even) {
  background: var(--color-surface-alt);
  --vt-lineup-frozen-bg: var(--color-surface-alt);
}
.vt-lineup--striped .vt-lineup__row:hover,
.vt-lineup--boxed .vt-lineup__row:hover {
  background: var(--color-light-purple-10);
  --vt-lineup-frozen-bg: var(--color-light-purple-10);
}

/* ---- preset: carded, ruled rows ---- */
.vt-lineup--boxed .vt-lineup__name,
.vt-lineup--boxed .vt-lineup__cell { border-bottom: 1px solid var(--color-divider); }
.vt-lineup--boxed .vt-lineup__row:last-child .vt-lineup__name,
.vt-lineup--boxed .vt-lineup__row:last-child .vt-lineup__cell { border-bottom: 0; }

/* ---- preset: ruled rows, no card ---- */
.vt-lineup--rules .vt-lineup__name,
.vt-lineup--rules .vt-lineup__cell { border-bottom: 1px solid var(--color-divider); }
.vt-lineup--rules .vt-lineup__row:last-child .vt-lineup__name,
.vt-lineup--rules .vt-lineup__row:last-child .vt-lineup__cell { border-bottom: 0; }
/* Without a card there is no card edge to inset from, so the OUTER cells lose
   their gutter and the rules run the full width of the column. */
.vt-lineup--rules .vt-lineup__caption,
.vt-lineup--plain .vt-lineup__caption { padding-inline: 0; }
.vt-lineup--rules .vt-lineup__table :is(th, td):first-child,
.vt-lineup--plain .vt-lineup__table :is(th, td):first-child { padding-left: 0; }
.vt-lineup--rules .vt-lineup__table :is(th, td):last-child,
.vt-lineup--plain .vt-lineup__table :is(th, td):last-child { padding-right: 0; }

/* ---- preset: no card, no rules ---- */
.vt-lineup--plain .vt-lineup__name,
.vt-lineup--plain .vt-lineup__cell { padding-block: 9px; }

/* ------------------------------------------------------------
   The frozen Model column (the mockup's own answer to eight columns of prose).

   CARDED PRESETS ONLY, and that is a limitation with a cause rather than an
   oversight: a sticky cell has to be opaque or the row it slides over shows
   through it, and the only background this block can be sure of is the card's.
   A section's backdrop may be a gradient, the micromirror field or the world
   map — none of which a table cell can repaint. The Inspector says so, which is
   better than a setting that does nothing on two of four styles.
   ------------------------------------------------------------ */
.vt-lineup--frozen:is(.vt-lineup--striped, .vt-lineup--boxed) :is(.vt-lineup__head--model, .vt-lineup__name) {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--vt-lineup-frozen-bg);
  /* a separator, so the frozen column reads as fixed while content scrolls
     under it — a border would move with the cell and double up on the rules */
  box-shadow: 1px 0 0 var(--color-border);
}
/* the corner cell sits above both the head row and the frozen column */
.vt-lineup--frozen:is(.vt-lineup--striped, .vt-lineup--boxed) .vt-lineup__head--model {
  z-index: 2;
  background: var(--color-surface);
}

/* On a dark section the card is a whisper of white and the zebra inverts.
   `.vt-section.is-dark` out-specifies the base rules whatever order WordPress
   inlines the sheets in — block CSS lands BEFORE the theme's (trap 2). */
.vt-section.is-dark .vt-lineup--striped .vt-lineup__scroll,
.vt-section.is-dark .vt-lineup--boxed .vt-lineup__scroll {
  border-color: color-mix(in srgb, #ffffff 14%, transparent);
  background: color-mix(in srgb, #ffffff 4%, transparent);
}
.vt-section.is-dark .vt-lineup--striped .vt-lineup__row:nth-child(even) {
  background: color-mix(in srgb, #ffffff 4%, transparent);
}
.vt-section.is-dark .vt-lineup__row:hover { background: color-mix(in srgb, #ffffff 8%, transparent); }
.vt-section.is-dark .vt-lineup__name { color: var(--vt-fg); }
.vt-section.is-dark .vt-lineup__row > .vt-lineup__cell:first-of-type { color: var(--vt-fg); }
.vt-section.is-dark .vt-lineup__head,
.vt-section.is-dark .vt-lineup__name,
.vt-section.is-dark .vt-lineup__cell { border-color: color-mix(in srgb, #ffffff 12%, transparent); }
.vt-section.is-dark .vt-lineup__badge--legacy {
  background: color-mix(in srgb, #ffffff 8%, transparent);
  color: var(--vt-fg-muted);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #ffffff 20%, transparent);
}
/* A frozen column over a dark backdrop cannot be trusted — the only opaque
   colour available is flat ink, which paints a solid slab over an aurora or the
   micromirror field. The frozen column is therefore OFF on a dark section, and
   the table scrolls whole. */
.vt-section.is-dark .vt-lineup--frozen :is(.vt-lineup__head--model, .vt-lineup__name) {
  position: static;
  background: transparent;
  box-shadow: none;
}

/* The recommended-model hook, kept for the day a field can say which head is
   the flagship. Nothing sets it today — see render.php. */
.vt-lineup__row.is-pick {
  background: linear-gradient(90deg, var(--color-light-purple-10), transparent 82%);
  box-shadow: inset 3px 0 0 var(--color-light-purple);
}

/* ------------------------------------------------------------
   Phones: one card per product, the same call the lens table makes. An
   eight-column table on a 390px screen is a horizontal scroll nobody finds, so
   <thead> goes away and each cell prints its own column name from data-label.

   960, not the lens table's 760: this table is 1100px wide at minimum, so it is
   already scrolling sideways on a tablet where five columns of numbers still
   fit. The container query is what makes the number true in the canvas too.
   ------------------------------------------------------------ */
@container vt-section (max-width: 960px) {
  .vt-lineup .vt-lineup__scroll {
    overflow-x: visible;
    border: 0;
    border-radius: 0;
    background: transparent;
  }
  .vt-lineup .vt-lineup__table,
  .vt-lineup .vt-lineup__table tbody { display: block; min-width: 0; }
  .vt-lineup .vt-lineup__table thead { display: none; }
  .vt-lineup .vt-lineup__caption { display: block; padding: 0 0 12px; }

  /* the card IS the edge again, so the gutter comes back for every preset */
  .vt-lineup { --vt-lineup-pad-x: 0px; }

  /* <thead> is gone below here, so the sort bar is the only affordance left.
     Without it the whole feature would silently vanish on a phone. */
  .vt-lineup .vt-lineup__sortbar {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
  }
  .vt-lineup .vt-lineup__sortbar-label {
    flex: 0 0 auto;
    font-family: var(--font-body);
    font-size: max(11px, var(--fs-floor, 0px));
    font-weight: var(--fw-bold);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--vt-fg-muted, var(--color-text-muted));
  }
  .vt-lineup .vt-lineup__sortbar-select {
    flex: 1 1 auto;
    min-width: 0;
    padding: 9px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md, 6px);
    background: var(--color-surface);
    font-family: var(--font-body);
    font-size: 15px;
    color: var(--vt-fg, var(--color-text));
  }
  .vt-lineup .vt-lineup__sortbar-select:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
  }

  .vt-lineup .vt-lineup__row {
    display: block;
    margin-bottom: 12px;
    padding: 4px 16px 6px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
  }
  /* the zebra, the hover and the frozen column are all meaningless once every
     row is its own card */
  .vt-lineup .vt-lineup__row:nth-child(even),
  .vt-lineup .vt-lineup__row:hover { background: var(--color-surface); }
  .vt-lineup .vt-lineup__name {
    display: block;
    padding: 10px 0 13px;
    font-size: 18px;
    white-space: normal;
    border-bottom: 1px solid var(--color-border);
  }
  /* Undoing the freeze needs the freeze's OWN weight. The frozen rule below is
     (0,3,0) — two classes plus one inside :is() — and a (0,2,0) reset lost to it
     silently: the model cell kept painting --vt-lineup-frozen-bg, which in card
     mode is a full-width tinted strip across the top of every second card. It
     looked like a design choice, which is why it is worth a comment. Matching the
     weight and coming later in the sheet is the fix. */
  .vt-lineup--frozen .vt-lineup__table :is(.vt-lineup__head--model, .vt-lineup__name) {
    position: static;
    background: transparent;
    box-shadow: none;
  }

  /* LABEL OVER VALUE, not the lens table's label-left/number-right row. The
     lens table compares measurements — "Working dist. … 16 mm" is one short
     line. Here the value is a sentence ("Selective AP, IC substrate / glass
     build-up, mSAP SLP, HBM RDL"), and a right-aligned sentence beside a
     left-aligned label is two ragged edges facing each other. The mockup's own
     phone rule for its key/value block does the same thing (.speccommon at
     600px: one column, label over value, left aligned). */
  .vt-lineup .vt-lineup__cell {
    display: block;
    padding: 12px 0;
    font-size: 15px;
    white-space: normal;
    text-align: left;
    border-bottom: 1px solid var(--color-divider);
  }
  .vt-lineup .vt-lineup__row > .vt-lineup__cell:first-of-type { white-space: normal; }
  .vt-lineup .vt-lineup__cell:last-child { border-bottom: 0; }
  /* The column name, from the attribute render.php wrote — wearing the <thead>'s
     own type treatment, which is what makes the card read as the table it came
     from. Decorative duplication of a <thead> that is hidden here, so it is CSS
     content rather than an element: the accessible table still has its real
     headers. */
  .vt-lineup .vt-lineup__cell::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 3px;
    font-family: var(--font-body);
    font-size: max(11px, var(--fs-floor, 0px));
    font-weight: var(--fw-bold);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--vt-fg-subtle, var(--color-text-subtle));
  }

  .vt-section.is-dark .vt-lineup .vt-lineup__row,
  .vt-section.is-dark .vt-lineup .vt-lineup__row:nth-child(even) {
    border-color: color-mix(in srgb, #ffffff 14%, transparent);
    background: color-mix(in srgb, #ffffff 4%, transparent);
  }
}
