/* ============================================================================
 * Persona listing — v4 type variant
 * Ported from Sigrix_new/marketplace/Marketplace - Listing Persona v4.html
 *
 * The shell this sits on is `css/sx-listing-v4.css`, which the page loads
 * first. That prototype's stylesheet is byte-identical to the skill one for
 * all 427 lines of the shell, and adds one "Type variants — persona" block —
 * 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).
 *
 * The accent is the one thing every v4 type restates. It is declared at
 * (0,2,1) — `body.listing-v4-page.persona-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.
 *
 * Four blocks the prototype declares are deliberately absent, because the live
 * page renders nothing that would use them:
 *
 *   .pv-tbl      a table inside the persona's reply. Scenarios store the
 *                assistant's answer as plain text, so there is no structured
 *                reply to lay out — a rule with no markup is a rule the next
 *                reader has to work out is dead.
 *   .mono-title  declared in the prototype and used by nothing in it. The
 *                persona hero's <h1> is `.ig-title`, not the skill page's mono
 *                directory name.
 *   .ig-ba*      the before/after transform, which is the *skill* prototype's
 *                proof slot; the persona file keeps the rules but renders a
 *                chat exchange instead.
 *   .ig-cfg      the config-flag table, likewise inherited and unrendered.
 * ==========================================================================*/

body.listing-v4-page.persona-listing-page {
  /* The prototype's persona accent is #E0A03C, which is a *dark theme* value —
     that page is authored at data-theme="dark". At 2.27:1 on white it is
     unreadable in light mode, and the shell writes `--ig-accent` as text in
     seven places (.ig-kind, .ig-sig .ico, .ig-editable, the mono captions).
     So the light value is the same hue (37°) taken down to #8C5600, at full
     saturation so it still reads as the prototype's amber rather than as a
     brown: 6.09 / 5.84 / 5.74:1 on --sx-surface / --sx-bg / --sx-surface-2,
     and 4.97 / 4.79 / 4.70:1 on its own 14% tint over each. Measured against
     all three, 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: #8c5600;
  --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 prototype's `.ig-kind--persona` modifier is deliberately absent from the
   markup. It exists there because that file has no token layer and has to
   recolour the chip by hand; here the shell's `.ig-kind` already reads
   `--ig-accent`, which the block above overrides, so the modifier would be a
   class that styles nothing — and a no-op class reads as load-bearing to
   whoever meets it next. The same goes for `.ig-rel-tag--persona`. */

[data-theme="dark"] body.listing-v4-page.persona-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. */
  --ig-accent: #e0a03c;
  --ig-accent-ink: #241701;
}

/* The item manifest is entirely the shell's here — including `.ig-file .n`,
   whose prose typeface is the shell's default. The skill variant is the one
   that restates it, because a filename is set in mono; a persona row names an
   authored block ("When responding") and wants nothing of its own. */

/* ── the tagline ─────────────────────────────────────────────────────────
   A persona's one-line promise, above the description rather than instead of
   it. Italic and wider-set than `.ig-desc` so the two do not read as one
   paragraph broken in half. */
.pv-tagline {
  margin: 0 0 14px;
  font-size: 19px;
  line-height: 1.42;
  font-style: italic;
  color: var(--sx-text);
  max-width: 36ch;
  text-wrap: pretty;
}

/* ── the chat card (hero proof, and section 02) ──────────────────────────
   The type-specific *proof* renderer. A persona's argument is neither imagery
   nor a file — it is how it talks — so the proof is a real exchange in its own
   voice: the hero shows the stored greeting (the first message of every
   session, which is what the card claims), and section 02 shows a stored
   scenario in full. Both are quotations of seller-authored text, never the
   deliverable; the system prompt itself is section 01's business. */
.pv-chat {
  border: 1px solid var(--sx-line);
  border-radius: 16px;
  background: var(--sx-surface);
  overflow: hidden;
}
.pv-chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--sx-line);
  font-family: var(--ig-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sx-text-3);
}
.pv-msg {
  padding: 17px 19px;
}
.pv-msg + .pv-msg {
  border-top: 1px solid var(--sx-line);
}
.pv-msg--user {
  background: var(--sx-bg-2);
}
.pv-who {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 10px;
  font-family: var(--ig-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sx-text-3);
}
.pv-msg--ai .pv-who {
  color: var(--ig-accent);
}
.pv-who .av {
  width: 19px;
  height: 19px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--ig-accent-soft);
  color: var(--ig-accent);
  font-size: 9.5px;
  font-weight: 700;
  flex: none;
}
/* `white-space: pre-wrap` where the prototype has one <p> per paragraph: a
   stored greeting or scenario answer is a single seller-authored string, and
   the line breaks they typed are the shape of the reply. */
.pv-msg p {
  margin: 0;
  font-size: 14px;
  line-height: 1.65;
  color: var(--sx-text-2);
  white-space: pre-wrap;
  text-wrap: pretty;
}
.pv-msg--ai p {
  color: var(--sx-text);
}

/* ── the block list (section 01) ─────────────────────────────────────────
   What a persona ships: one row per authored block, each with what that block
   is for and what it weighs. This is the whole disclosure the listing makes
   before the prompt itself — which is why the row carries a description and
   not just a name. */
.pv-blocks {
  display: grid;
  gap: 1px;
  background: var(--sx-line);
  border: 1px solid var(--sx-line);
  border-radius: 14px;
  overflow: hidden;
}
.pv-block {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  background: var(--sx-bg-2);
}
.pv-block .n {
  flex: none;
  width: 8.5ch;
  font-family: var(--ig-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sx-text-3);
  padding-top: 2px;
}
.pv-block .t {
  display: block;
  font-size: 13.5px;
  font-weight: 500;
}
.pv-block .s {
  display: block;
  margin-top: 3px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--sx-text-2);
  text-wrap: pretty;
}
.pv-block .z {
  margin-left: auto;
  flex: none;
  font-family: var(--ig-mono);
  font-size: 11.5px;
  color: var(--sx-text-3);
  padding-top: 3px;
}

/* ── the guarantees row (section 02) ─────────────────────────────────────
   The shell's `.ig-incl` list with a surface under it. What fills it is the
   seller's own Rules block, quoted line for line — see
   `persona_listing_view.persona_guards` for why it is quoted rather than
   summarised.

   The caption carries the block's top margin so the list can sit tight under
   it. It exists because the alternative was a sub-line under every row saying
   where the rule came from — the same sentence three times, which is the
   padding that makes a list stop being read. */
.pv-guards-cap {
  margin: 32px 0 12px;
}
.ig-guards {
  margin-top: 0;
  border: 1px solid var(--sx-line);
  border-radius: 14px;
  padding: 4px 18px;
  background: color-mix(in srgb, var(--sx-surface) 55%, transparent);
}
.ig-guards .ico {
  background: var(--ig-accent-soft);
  color: var(--ig-accent);
}

/* ── the gated prompt (section 01, no access) ────────────────────────────
   The fade is decoration over text the server *chose* to send: a locked view
   model carries `preview_prompt`, which is the first PREVIEW_LINES lines and
   nothing else (services/persona_listing_view). The rest of the prompt is
   absent from the response, not covered — CLAUDE.md's rule, and the reason
   this is a mask on a short <pre> rather than a max-height on a long one.

   The geometry is a floor, a cap and a fixed fade tail, and all three are
   load-bearing. The prototype fades from 52% of the box, which works only
   because its example prompt fills it — on a persona whose opening block is a
   single sentence the box is one line tall and the *published* line is what
   the fade eats, so the page hides the one thing it decided to show. Anchoring
   the fade to the last 56px instead keeps everything above it fully opaque at
   any head length; `min-height` gives a short head that 56px to fade into, so
   the panel still reads as "there is more below" rather than as a box that
   happens to end. `max-height` is the cap, for a listing whose opening block
   runs long. */
.pv-gate .ig-pre {
  min-height: 132px;
  max-height: 250px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(#000 calc(100% - 56px), transparent);
  mask-image: linear-gradient(#000 calc(100% - 56px), transparent);
}
.pv-gate-foot {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 0 26px 24px;
}
.pv-gate-foot .t {
  font-size: 13px;
  line-height: 1.55;
  color: var(--sx-text-2);
  max-width: 44ch;
}
.pv-locked {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--sx-text-2);
}
/* The ink, not the fill — see the shell's `--ig-warn-text` note. */
.pv-locked svg {
  color: var(--ig-warn-text);
}

@media (max-width: 760px) {
  .pv-blocks .pv-block {
    flex-wrap: wrap;
  }
  /* The number column and the weight both go full-width rather than squeezing
     the title into a few characters — `8.5ch` plus a nowrap token count leaves
     under 20ch for the block name at 360px. */
  .pv-block .z {
    margin-left: 0;
    padding-top: 0;
  }
  .pv-gate-foot {
    padding: 0 18px 20px;
  }
}
