---
// PreviewPane — the dark code/markdown preview block in the review panel.
//
// The pane has three body modes (source / rendered Markdown / diff / lens)
// plus the file-tab strip. The lens view is rendered by ChangeLens instead,
// so this component only owns the source and rendered-markdown bodies. The
// toggle between them is task 16's job; this component ships zero JS.
//
// CSS hooks asserted by scripts/verify.mjs that live in the legacy
// stylesheet and must survive in the new architecture:
//   .preview         — the section wrapper
//   .preview-title   — the upper-left title cluster
//   .preview-markdown— the "Preview Markdown" / "View source" toggle
//   .markdown-preview— the rendered-HTML container
//   max-height:540px — the bounded reading surface
//   .markdown-table-wrap, .markdown-frontmatter, .markdown-toc
//                    — sub-blocks inside the rendered Markdown

interface Props {
  /** Label rendered above the file name. Source: "FILE PREVIEW". */
  title: string;
  /** Smaller subtitle that names the version. Source: e.g.
   *  "ORIGINAL / SAFETY-REDACTED WHERE NEEDED". */
  subtitle: string;
  /** True when the "Preview Markdown" toggle is active — the body should
   *  render the slot as HTML, otherwise the slot is treated as plain
   *  source. */
  rendered: boolean;
}

const { title, subtitle, rendered } = Astro.props;
---

<section class="preview" aria-label="File preview">
  <header>
    <div class="preview-title">
      <span>{title}</span>
      <small>{subtitle}</small>
    </div>
    <div class="preview-actions">
      <slot name="actions" />
      <button type="button" class="preview-markdown" aria-pressed={rendered} data-render>
        {rendered ? 'View source' : 'Preview Markdown'}
      </button>
    </div>
  </header>
  <slot name="tabs" />
  {
    rendered ? (
      <div class="markdown-preview" aria-label="Rendered Markdown preview">
        <slot name="rendered" />
      </div>
    ) : (
      <pre>
        <code>
          <slot name="source" />
        </code>
      </pre>
    )
  }
</section>

<style>
  /* The whole pane is the dark surface. The header border separates the
     action bar from the tab strip from the body. */
  .preview {
    border: 1px solid var(--ink);
    background: var(--deep);
  }

  .preview > header {
    display: flex;
    justify-content: space-between;
    gap: 20px;
    padding: 14px;
    color: var(--paper);
    border-bottom: 1px solid var(--line);
  }

  /* Title cluster: eyebrow line + subtitle. */
  .preview-title {
    display: grid;
    gap: 2px;
  }

  .preview-title span {
    color: var(--gold);
    font:
      700 10px ui-monospace,
      monospace;
    letter-spacing: 0.1em;
  }

  /* Subtitle below the eyebrow. */
  .preview-title small {
    color: var(--paper);
    /* token-gap: no --step-* covers 9px; owner design-system-keeper */
    font:
      9px / 1.35 ui-monospace,
      monospace;
    letter-spacing: 0.05em;
  }

  /* Action buttons live in the right cluster. The component lays them out;
     the call site fills the `actions` slot. */
  .preview-actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
  }

  .preview button {
    padding: 9px 11px;
    color: var(--paper);
    background: transparent;
    border: 1px solid var(--line);
    cursor: pointer;
    font:
      700 10px ui-monospace,
      monospace;
  }

  .preview button:hover {
    background: var(--muted);
  }

  /* The Markdown toggle is deliberately distinct from the other actions. */
  .preview button.preview-markdown {
    color: var(--ink);
    border-color: var(--gold);
    background: var(--gold);
  }

  .preview button.preview-markdown:hover,
  .preview button.preview-markdown[aria-pressed='true'] {
    color: var(--paper);
    background: var(--red);
    border-color: var(--red);
  }

  /* Source body: bounded scroll, monospaced, the canonical dark code
     surface. The max-height hook is the one verify.mjs asserts. */
  .preview pre {
    max-height: 540px;
    margin: 0;
    padding: 24px;
    color: var(--paper);
    background: var(--ink);
  }

  /* Code text inside the source surface. */
  .preview code {
    font:
      12px / 1.65 ui-monospace,
      monospace;
    white-space: pre-wrap;
  }

  /* Rendered Markdown body: same bounded reading surface. */
  .markdown-preview {
    max-height: 540px;
    overflow: auto;
    padding: 24px;
    color: var(--paper);
    background: var(--ink);
  }

  .markdown-preview > :first-child {
    margin-top: 0;
  }

  .markdown-preview :global(h1),
  .markdown-preview :global(h2),
  .markdown-preview :global(h3),
  .markdown-preview :global(h4),
  .markdown-preview :global(h5),
  .markdown-preview :global(h6) {
    margin: 1.5em 0 0.5em;
    color: var(--paper);
    line-height: 1.15;
  }

  .markdown-preview :global(h1) {
    font-size: 1.8em;
  }

  .markdown-preview :global(h2) {
    font-size: 1.45em;
  }

  .markdown-preview :global(h3) {
    font-size: 1.2em;
  }

  .markdown-preview :global(p),
  .markdown-preview :global(li) {
    max-width: 78ch;
  }

  .markdown-preview :global(li + li) {
    margin-top: 0.35em;
  }

  .markdown-preview :global(a) {
    color: var(--gold);
  }

  .markdown-preview :global(code) {
    padding: 0.12em 0.3em;
    color: var(--paper);
    background: var(--muted);
    white-space: break-spaces;
  }

  .markdown-preview :global(pre) {
    max-height: none;
    margin: 1em 0;
    padding: 14px;
    border: 1px solid var(--line);
  }

  .markdown-preview :global(pre code) {
    padding: 0;
    background: transparent;
  }

  .markdown-preview :global(blockquote) {
    margin: 1em 0;
    padding: 0.3em 1em;
    border-left: 3px solid var(--gold);
    color: var(--muted);
  }

  .markdown-preview :global(hr) {
    border: 0;
    border-top: 1px solid var(--line);
  }

  /* Frontmatter: the two-column key/value grid that opens the rendered
     surface when a `---` block is present. */
  .markdown-preview :global(.markdown-frontmatter) {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 3px 14px;
    margin: 0 0 24px;
    padding: 12px;
    border: 1px solid var(--line);
    font:
      11px/1.5 ui-monospace,
      monospace;
  }

  .markdown-preview :global(.markdown-frontmatter dt) {
    color: var(--gold);
  }

  .markdown-preview :global(.markdown-frontmatter dd) {
    margin: 0;
  }

  /* Table wrapper: horizontal scroll on narrow viewports. */
  .markdown-preview :global(.markdown-table-wrap) {
    max-width: 100%;
    overflow: auto;
    margin: 1em 0;
    border: 1px solid var(--line);
  }

  .markdown-preview :global(table) {
    width: 100%;
    min-width: 460px;
    border-collapse: collapse;
    font-size: var(--step-13);
  }

  .markdown-preview :global(th),
  .markdown-preview :global(td) {
    padding: 9px 11px;
    border: 1px solid var(--line);
    text-align: left;
    vertical-align: top;
  }

  .markdown-preview :global(th) {
    color: var(--gold);
    background: var(--deep);
  }

  /* Table of contents: the "ON THIS PAGE" nav that opens the body when
     the Markdown has two or more headings. */
  .markdown-preview :global(.markdown-toc) {
    margin: 0 0 24px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    background: var(--deep);
  }

  .markdown-preview :global(.markdown-toc > span) {
    color: var(--gold);
    font:
      700 10px ui-monospace,
      monospace;
    letter-spacing: 0.1em;
  }

  .markdown-preview :global(.markdown-toc ol) {
    display: flex;
    flex-wrap: wrap;
    gap: 7px 13px;
    margin: 9px 0 0;
    padding: 0;
    list-style: none;
  }

  .markdown-preview :global(.markdown-toc li.level-2) {
    margin-left: 10px;
  }

  .markdown-preview :global(.markdown-toc li.level-3) {
    margin-left: 20px;
  }

  .markdown-preview :global(.markdown-toc a) {
    font:
      12px / 1.3 Arial,
      sans-serif;
    text-decoration: none;
  }

  .markdown-preview :global(.markdown-toc a:hover) {
    text-decoration: underline;
  }

  @media (max-width: 800px) {
    .preview > header {
      flex-direction: column;
      align-items: flex-start;
    }
  }
</style>
