/* ============================================================================
 * Text prompt listing — v4 type variant
 * Ported from Sigrix_new/marketplace/Marketplace - Listing Prompt v4.html
 *
 * The fourth page on the shared v4 shell, after the graphic prompt, the skill
 * and the persona. The shell is `css/sx-listing-v4.css`, which the page loads
 * first; that prototype's stylesheet is the same shell as its three siblings'
 * and adds one type-variant block, and this file is that block minus the parts
 * of it the live listing has no data behind (see docs/design_sync_log.md for
 * what was refused and why).
 *
 * What the prototype declares and this file does *not* is the point worth
 * knowing before adding to it: the chat card (`.pv-*`) and the guarantees row
 * (`.ig-guards`) are in the **shell**, not here. They arrived with the persona
 * page and moved down when this one landed, because a selector declared in two
 * variant sheets resolves by whichever sheet the browser parsed last — so a
 * page loading only one gets whichever half its variant happens to hold.
 * `test_no_selector_is_declared_in_two_variant_sheets` holds that line. The
 * item manifest (`.ig-file*`) and owner stats are in the shell for the same
 * reason, one port earlier.
 *
 * The accent is the one thing every v4 type restates. It is declared at
 * (0,2,1) — `body.listing-v4-page.prompt-listing-page` — rather than at the
 * shell's (0,1,1), so it wins on specificity and not on which sheet the
 * browser happened to parse last. CLAUDE.md's admin.css note is the reason:
 * a same-specificity override that depends on load order is a rule nobody can
 * read off either file.
 * ==========================================================================*/

body.listing-v4-page.prompt-listing-page {
  /* The prototype's prompt accent is #5B7CFF, and that value is not arbitrary:
     it is exactly `--sx-lt-prompt`, the theme-invariant identity colour this
     platform already gives prompt listings on every card and quicklink dot. So
     the *dot* below keeps it verbatim — identity, not state.

     The ink cannot. Like every v4 prototype this page is authored at
     data-theme="dark", and the shell writes `--ig-accent` as *text* in seven
     places (.ig-kind, .ig-sig .ico, .ig-editable, .pv-msg--ai .pv-who, the
     mono captions) — 3.64:1 on white, which is the `--sx-brand-2` split in
     CLAUDE.md arriving through a design file rather than a token.

     Light is the same hue (228°) taken down to #274FEC: 6.15 / 5.89 / 5.79:1
     on --sx-surface / --sx-bg / --sx-surface-2, and 4.96 / 4.77 / 4.69:1 on
     its own 14% tint over each. Measured against all three and against the
     tints, not just white — see the contrast test, and CLAUDE.md's note on the
     near-miss a white-only check would have shipped. */
  --ig-accent: #274fec;
  --ig-accent-soft: color-mix(in srgb, var(--ig-accent) 14%, transparent);
  --ig-accent-line: color-mix(in srgb, var(--ig-accent) 34%, transparent);
  --ig-accent-ink: #ffffff;
  --ig-hero-glow-b: color-mix(in srgb, var(--ig-accent) 8%, transparent);

  /* The identity colour, kept theme-invariant because that is what it is. Its
     only consumer is the kind dot, which is a 7px fill beside the word
     "Prompt" — a fill, so it is not bound by the ink ratios above. */
  --tp-kind-dot: #5b7cff;
}

[data-theme="dark"] body.listing-v4-page.prompt-listing-page {
  /* Only the two literals restate here. `--ig-accent-soft` / `-line` /
     `--ig-hero-glow-b` are written as `var(--ig-accent)` above, so they
     re-resolve against whichever value wins on this same element — the
     `--pp-accent` rule in CLAUDE.md, verified in Chromium there.

     This is the one v4 variant whose dark value is *not* the prototype's own,
     and the reason is worth keeping: #5B7CFF measures 4.12:1 on its own 14%
     tint over --sx-surface and 3.80:1 over --sx-surface-2, so the design's
     value is sub-AA as ink in its *own* theme — the case CLAUDE.md warns is
     invisible to a check that only looks at dark. #7591FF is the same hue at
     the same full saturation, five points lighter: 6.14 / 6.71 / 5.71:1 on the
     three dark surfaces and 4.98 / 5.63 / 4.59:1 on its tints. Beside the
     design it reads as the same blue. */
  --ig-accent: #7591ff;
  --ig-accent-ink: #050914;
}

/* The kind chip's dot is the only place the type's identity colour outranks
   the accent. Everywhere else on the page — the chip's own label included —
   reads `--ig-accent`, so this is one declaration rather than a
   `.ig-kind--prompt` modifier: the prototype needs that modifier because it
   has no token layer and recolours the chip by hand. */
body.listing-v4-page.prompt-listing-page .ig-kind .ig-dot {
  background: var(--tp-kind-dot);
}

/* ── the tagline ─────────────────────────────────────────────────────────
   A prompt listing's `subtitle` is the one line that says what the thing is
   *for*, and the prototype sets it in italic above the description at a size
   between the two. Rendered only when the seller wrote one — see the template;
   there is no synthesised fallback here, because the backfill that fills an
   empty subtitle writes the generated "<name> is a Prompt for <category> on
   Sigrix." sentence, and setting that in 19px italic as the page's second line
   would be the page shouting a sentence nobody authored. */
.tp-tagline {
  margin: 0 0 14px;
  font-size: 19px;
  line-height: 1.42;
  font-style: italic;
  color: var(--sx-text);
  max-width: 38ch;
  text-wrap: pretty;
}

/* ── the variables table (section 01) ────────────────────────────────────
   The prompt's interface: what a buyer fills in per run. This is the half of
   section 01 that is published *before* purchase — the tokens, their labels
   and the seller's own worked example — while the prompt they sit in stays
   gated. That split is the whole argument of the panel, so the table is
   deliberately as legible as the locked block above it rather than dimmed to
   look like a teaser.

   The rows come from `prompt_listing_view.prompt_variables`, which reads the
   same definitions the run form does, so the table cannot promise a field the
   prompt has no placeholder for. */
.tp-vars {
  display: grid;
  gap: 1px;
  background: var(--sx-line);
  border: 1px solid var(--sx-line);
  border-radius: 14px;
  overflow: hidden;
  margin-top: 22px;
}
.tp-var {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 16px;
  background: var(--sx-bg-2);
}
.tp-var .k {
  /* `min-width` rather than the prototype's flat `width: 16ch`, and the
     difference is visible on real data. A token is one unbroken string with no
     space to wrap at, so a fixed column breaks it mid-word:
     `{{primary_concer` / `n}}` — which is worse than a ragged column, because
     the buyer has to reassemble the thing they are meant to type. The
     prototype's own variable list would do the same (`{{primary_concern}}` is
     19 characters against its 16ch column); it just never rendered.

     So short tokens still align at 16ch, and a long one takes the room it
     needs on its own row. `nowrap` is what makes that a widening rather than a
     break. */
  flex: 0 0 auto;
  min-width: 16ch;
  white-space: nowrap;
  font-family: var(--ig-mono);
  font-size: 11.5px;
  color: var(--ig-accent);
  padding-top: 1px;
}
.tp-var .b {
  min-width: 0;
}
.tp-var .t {
  display: block;
  font-size: 13px;
  font-weight: 500;
}
.tp-var .s {
  display: block;
  margin-top: 3px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--sx-text-2);
  text-wrap: pretty;
}
.tp-var .z {
  margin-left: auto;
  flex: none;
  font-family: var(--ig-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sx-text-3);
  padding-top: 3px;
}

/* ── the clipped reply (hero proof) ──────────────────────────────────────
   The hero shows the recorded answer alone; section 02 shows it again with the
   input that produced it. The fade is decoration on text that was deliberately
   sent — `prompt_proof_exchange` has already cut the string server-side — not
   a lid over something withheld. Same posture as the persona page's gated
   prompt: a body the buyer cannot read is absent from the response, never
   present and covered. */
.pv-fade {
  position: relative;
  max-height: 352px;
  overflow: hidden;
}
.pv-fade::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 120px;
  background: linear-gradient(to bottom, transparent, var(--sx-surface));
  pointer-events: none;
}

@media (max-width: 640px) {
  /* Narrow enough that a 16ch column plus a label plus the required/optional
     chip cannot share a line — so the token takes its own row and the label
     drops under it. */
  .tp-var {
    flex-wrap: wrap;
  }
  .tp-var .k {
    min-width: 0;
  }
}
