{
  "generatedFrom": "info-box.contract.json",
  "component": "Info box",
  "slug": "info-box",
  "group": "Settings",
  "tier": "leaf-lit",
  "summary": "A settings-only tinted callout in four tones (information / success / warning / error), optionally dismissible — a bespoke component, not Ant Alert.",
  "install": {
    "package": "@ahaslides-product/design",
    "registry": "https://npm.pkg.github.com",
    "scope": "@ahaslides-product",
    "auth": "Published to GitHub Packages — needs a GitHub token with read:packages. Configure the @ahaslides-product scope in .npmrc before installing.",
    "npmrc": "@ahaslides-product:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}   # a GitHub token with read:packages",
    "command": "npm i @ahaslides-product/design",
    "tokenLayer": "import '@ahaslides-product/design/tokens.css';",
    "import": "import '@ahaslides-product/design/aha-info-box';",
    "element": "aha-info-box",
    "registers": "aha-info-box"
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/info-box/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/info-box/info-box.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/info-box.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/info-box.llms.txt",
    "index": "https://ahaslides-product.github.io/ahaslides-design/llms.txt"
  },
  "recommendedSnippet": "html",
  "vibeCode": "Emit the HTML snippet by default — <aha-info-box> is a standard custom element that renders on open — React/Vue are thin adapters over the same element. Paste into an .html file and it renders with no build step.",
  "frameworks": {
    "react": {
      "via": "web-component",
      "ref": "aha-info-box"
    },
    "vue": {
      "via": "web-component",
      "ref": "aha-info-box"
    },
    "html": {
      "via": "web-component",
      "ref": "aha-info-box",
      "runnable": "paste-and-run — no build step, renders on open"
    }
  },
  "props": [
    {
      "name": "variant",
      "type": "information | success | warning | error",
      "default": "information",
      "desc": "The tone — sets fill, border and leading glyph"
    },
    {
      "name": "icon",
      "type": "string",
      "default": "—",
      "desc": "Override the tone's default glyph with a named DS icon"
    },
    {
      "name": "dismissible",
      "type": "boolean",
      "default": "false",
      "desc": "Show the ✕ dismiss control"
    },
    {
      "name": "dismiss",
      "type": "CustomEvent",
      "default": "—",
      "desc": "Composed event after the box fades out"
    }
  ],
  "tokens": [
    "bg-informative",
    "border-info",
    "color-info",
    "bg-positive",
    "border-success",
    "color-success",
    "bg-warning",
    "border-warning",
    "color-warning",
    "pink-20",
    "pink-60",
    "text-default",
    "icon-muted",
    "bg-hover",
    "radius-default",
    "radius-sm"
  ],
  "spec": [
    {
      "label": "Box",
      "value": "padding 12 · radius 8 · 1px tinted border + tinted fill per tone"
    },
    {
      "label": "Information",
      "value": "#F4F8FF fill · #BFD2FF border · #9BB3E9 glyph (system-info)"
    },
    {
      "label": "Success",
      "value": "#D8FAEF fill · #16C49A border/glyph (system-check-circle)"
    },
    {
      "label": "Warning",
      "value": "#FFF5F0 fill · #FF7747 border/glyph (system-warning-circle)"
    },
    {
      "label": "Error",
      "value": "#FFE3E9 fill · #FF4081 border/glyph — Radical Pink, NOT red (system-x-circle)"
    },
    {
      "label": "Dismiss",
      "value": "optional ✕ (system-x); fades out on a persistent node, emits `dismiss`"
    },
    {
      "label": "Text",
      "value": "Plus Jakarta 14/21 #1A1A1A"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "Info box",
        "when": "a settings-panel callout explaining a state or a consequence in place"
      },
      {
        "what": "Help text",
        "when": "a one-line must-see consequence attached to a single setting (≤90 chars) — not a box"
      },
      {
        "what": "Tooltip",
        "when": "secondary what/why/how elaboration on a ? glyph"
      }
    ],
    "note": "Bespoke, NOT Ant Alert — Alert renders outside the DS theme. Keep callouts rare: most explanation is a ? tooltip or nothing (SETTINGS-28). Use error/warning for a consequence, not decoration.",
    "dsv3": "COVERED — the settings-lab InfoBox control mapped into the DS. The four tinted tones reuse the DS V3 semantic bg/border/colour tokens; the settings-only callout shape + dismiss are the addition. Deliberately bespoke (not Ant Alert), which does not consume the DS theme."
  },
  "surfaces": [
    "editor",
    "settings"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step.\n     <aha-info-box> is the SAME shared custom element React and Vue consume — here in its native form.\n     Theming comes only from the --aha-* tokens in tokens.css. Bespoke, NOT Ant Alert. The dismiss ✕\n     fades the box out and emits `dismiss` — the host owns any \"don't show again\" state. -->\n<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/tokens.css\">\n<script type=\"module\">\n  import 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/aha-info-box.js';   // registers <aha-info-box>\n</script>\n\n<div style=\"display:flex; flex-direction:column; gap:8px; max-width:420px\">\n  <aha-info-box variant=\"information\">Points are awarded for correct answers only.</aha-info-box>\n  <aha-info-box variant=\"success\">Your changes are saved.</aha-info-box>\n  <aha-info-box variant=\"warning\" id=\"warn\" dismissible>Turning this off clears saved responses.</aha-info-box>\n  <aha-info-box variant=\"error\">This slide type needs at least two options.</aha-info-box>\n</div>\n\n<script>\n  document.getElementById('warn').addEventListener('dismiss', () => console.log('dismissed'));\n</script>\n",
    "react": "import '@ahaslides-product/design/aha-info-box'; // registers <aha-info-box>\nimport { useRef, useEffect } from 'react';\n\n// React 18 needs a thin wrapper; React 19 can use <aha-info-box> directly.\n// Bespoke callout (NOT Ant Alert); onDismiss fires after the box fades out.\nfunction AhaInfoBox({ variant, icon, dismissible, onDismiss, children }) {\n  const ref = useRef();\n  useEffect(() => {\n    const el = ref.current;\n    const h = () => onDismiss?.();   // composed CustomEvent\n    el.addEventListener('dismiss', h);\n    return () => el.removeEventListener('dismiss', h);\n  }, [onDismiss]);\n  return (\n    <aha-info-box\n      ref={ref}\n      {...(variant ? { variant } : {})}\n      {...(icon ? { icon } : {})}\n      {...(dismissible ? { dismissible: '' } : {})}\n    >{children}</aha-info-box>\n  );\n}\n\n// usage\n<AhaInfoBox variant=\"warning\" dismissible onDismiss={() => setSeen(true)}>\n  Turning this off clears saved responses.\n</AhaInfoBox>\n",
    "vue": "// main.ts — register the element + mark aha-* as custom elements\nimport '@ahaslides-product/design/aha-info-box';   // registers <aha-info-box>\napp.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');\n\n// Component.vue\n<script setup>\nimport { ref } from 'vue';\nconst seen = ref(false);\n</script>\n\n<template>\n  <!-- bespoke callout (NOT Ant Alert); @dismiss fires after the box fades out -->\n  <aha-info-box\n    v-if=\"!seen\"\n    variant=\"warning\"\n    dismissible\n    @dismiss=\"seen = true\"\n  >Turning this off clears saved responses.</aha-info-box>\n</template>\n"
  }
}
