---
// SkillPackageExplorer — the four-file skill-package picker. The interactive
// version of the `data-package-file` buttons that the vanilla skills page
// shipped, rewritten for the Astro chapter surface. The four package entries
// mirror skills/app.js so the migration preserves content 1:1; the buttons
// carry `data-skill-file` and the click handler swaps the preview panel
// contents client-side.
//
// Page is `client:visible` rather than `client:load`: the picker sits below
// the hero and grid; deferring until it scrolls into view keeps initial JS
// to zero for the above-the-fold content. The page ships zero JS for the
// hero/grid/footer parts — only the picker island hydrates.

interface PackageFile {
  id: 'skill' | 'references' | 'scripts' | 'assets';
  prefix: '├── ' | '└── ';
  label: string;
  /** Small caption under the file label, mirrors the vanilla source. */
  caption: string;
  title: string;
  body: string;
  code: string;
}

const packageFiles: PackageFile[] = [
  {
    id: 'skill',
    prefix: '├── ',
    label: 'SKILL.md',
    caption: 'trigger + workflow',
    title: 'The operating contract',
    body: 'The one file that should always be loaded. Define the exact trigger, the ordered workflow, safety limits, and the evidence the agent returns.',
    code: '---\nname: review-ui\ndescription: Review a changed UI for focus, reflow, and motion.\n---\n\n1. Inspect the changed interaction.\n2. Run the UI checks.\n3. Return findings with evidence.',
  },
  {
    id: 'references',
    prefix: '├── ',
    label: 'references/',
    caption: 'conditional facts',
    title: 'Facts, only when needed',
    body: 'Keep conditional detail out of the main instruction. A dialog pattern, framework caveat, or accessibility checklist belongs here when it is not needed for every review.',
    code: 'references/\n└── accessibility.md\n    ├── keyboard interaction patterns\n    └── focus and reflow checklist',
  },
  {
    id: 'scripts',
    prefix: '├── ',
    label: 'scripts/',
    caption: 'deterministic checks',
    title: 'Mechanics that should not depend on memory',
    body: 'Turn deterministic checks into runnable tools. The agent still judges the result, but it should not have to recreate a viewport test or filename rule by hand.',
    code: 'scripts/\n└── check-reflow.mjs\n    └── checks 320px, 1280px, and 4K widths',
  },
  {
    id: 'assets',
    prefix: '└── ',
    label: 'assets/',
    caption: 'templates + examples',
    title: 'Starting material, not hidden instructions',
    body: 'Use assets for templates and examples a person or agent can copy. Keep them clearly named so package readers can choose the right starting point.',
    code: 'assets/\n├── review-report.md\n└── focus-test-fixture.html',
  },
];
---

<div class="package-workbench" data-package-workbench>
  <div class="package-tree" role="tablist" aria-label="Files in the review-ui skill package">
    <p>REVIEW-UI / SKILL PACKAGE</p>
    {
      packageFiles.map((file, index) => (
        <button
          class:list={[{ active: index === 0 }]}
          data-skill-file={file.id}
          role="tab"
          aria-selected={index === 0 ? 'true' : 'false'}
        >
          <code>{`${file.prefix}${file.label}`}</code>
          <small>{file.caption}</small>
        </button>
      ))
    }
  </div>
  <article class="package-preview" id="package-preview" aria-live="polite"></article>
</div>

<script type="application/json" data-skill-files set:html={JSON.stringify(packageFiles)} />

<script is:inline>
  (function () {
    const preview = document.querySelector('#package-preview');
    const buttons = document.querySelectorAll('[data-skill-file]');
    const dataNode = document.querySelector('[data-skill-files]');
    if (!preview || !dataNode) return;
    const files = JSON.parse(dataNode.textContent || '[]');

    function renderPackage(id) {
      const item = files.find((entry) => entry.id === id);
      if (!item) return;
      preview.classList.remove('is-swapping');
      void preview.offsetWidth;
      preview.classList.add('is-swapping');
      preview.innerHTML =
        '<span>SELECTED / ' +
        item.label +
        '</span>' +
        '<h3>' +
        item.title +
        '</h3>' +
        '<p>' +
        item.body +
        '</p>' +
        '<pre><code>' +
        item.code +
        '</code></pre>';
      buttons.forEach(function (button) {
        const active = button.dataset.skillFile === id;
        button.classList.toggle('active', active);
        button.setAttribute('aria-selected', String(active));
      });
    }

    buttons.forEach(function (button) {
      button.addEventListener('click', function () {
        renderPackage(button.dataset.skillFile);
      });
    });

    renderPackage('skill');
  })();
</script>

<style>
  .package-workbench {
    display: grid;
    grid-template-columns: minmax(190px, 0.85fr) minmax(0, 1.3fr);
    min-width: 0;
    background: var(--ink);
    border: 1px solid var(--ink);
    box-shadow: 10px 10px 0 color-mix(in srgb, var(--gold) 55%, transparent);
  }

  .package-tree {
    padding: 22px 16px;
    border-right: 1px solid var(--muted);
    min-width: 0;
  }

  .package-tree > p,
  .package-preview > span {
    margin: 0 0 14px;
    color: var(--gold);
    font:
      700 var(--step-0) / 1.35 ui-monospace,
      monospace;
    letter-spacing: 0.1em;
  }

  .package-tree button {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 12px 8px;
    border: 0;
    border-left: 2px solid transparent;
    background: transparent;
    color: var(--line);
    text-align: left;
    cursor: pointer;
    transition:
      background 0.2s ease,
      border-color 0.2s ease,
      transform 0.2s ease;
  }

  .package-tree button:hover,
  .package-tree button:focus-visible,
  .package-tree button.active {
    border-left-color: var(--gold);
    background: var(--blue);
    outline: 0;
  }

  .package-tree button:hover {
    transform: translateX(3px);
  }

  .package-tree code {
    min-width: 0;
    overflow-wrap: anywhere;
    font:
      700 13px / 1.4 ui-monospace,
      monospace;
  }

  .package-tree small {
    color: var(--muted);
    font:
      11px / 1.25 Arial,
      sans-serif;
    text-align: right;
  }

  .package-preview {
    min-width: 0;
    padding: 26px;
    background: var(--ink);
    color: var(--paper);
  }

  .package-preview h3 {
    margin: 0 0 8px;
    font-size: clamp(24px, 3vw, 38px);
    line-height: 1.02;
    letter-spacing: -0.045em;
  }

  .package-preview p {
    max-width: 52ch;
    margin: 0;
    color: var(--line);
  }

  .package-preview pre {
    max-width: 100%;
    margin: 20px 0 0;
    padding: 15px;
    overflow: auto;
    border: 1px solid var(--muted);
    background: var(--deep);
    color: var(--line);
    font:
      12px / 1.55 ui-monospace,
      monospace;
  }

  .package-preview.is-swapping {
    /* purpose: review-desk detail swap on selection (state change) */
    animation: package-preview-in 200ms cubic-bezier(0.2, 0, 0, 1) both;
  }

  @keyframes package-preview-in {
    from {
      opacity: 0.25;
      transform: translateY(7px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }

  @media (max-width: 800px) {
    .package-workbench {
      grid-template-columns: 1fr;
    }
    .package-tree {
      border-right: 0;
      /* token-gap: legacy var(--muted) mobile layout rule over --ink; no token matches; design-system-keeper */
      border-bottom: 1px solid var(--muted);
    }
    .package-preview {
      padding: 22px;
    }
  }

  @media (max-width: 560px) {
    .package-tree {
      padding: 18px 10px;
    }
    .package-tree button {
      padding: 12px 6px;
    }
    .package-tree small {
      display: none;
    }
    .package-preview {
      padding: 18px;
    }
    .package-preview pre {
      font-size: var(--step-0);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      scroll-behavior: auto !important;
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
    }
  }
</style>
