{
  "name": "Neutral product component catalogue",
  "version": "1.0.0",
  "description": "Copy-ready reference markup for the twenty-one canonical Neutral interface patterns.",
  "components": [
    {
      "id": "button",
      "name": "Button",
      "use": "A clear, immediate action. Keep one primary action per action group.",
      "avoid": "Navigation, passive status or a choice that needs explanatory context.",
      "accessibility": "Use a native button, preserve a visible focus ring and keep the label explicit.",
      "markup": "<div class=\"neutral-action-group\">\n  <button class=\"neutral-button neutral-button--primary\" type=\"button\">View evidence</button>\n  <button class=\"neutral-button\" type=\"button\">Export</button>\n</div>"
    },
    {
      "id": "link",
      "name": "Link",
      "use": "Moving to another page, resource or document while preserving the reader’s place in the current flow.",
      "avoid": "Submitting, mutating or opening a local interface state; those are buttons.",
      "accessibility": "The text names the destination. External destinations are disclosed in the accessible name.",
      "markup": "<a class=\"neutral-link\" href=\"/incidents/INC-2048\">Open incident record</a>"
    },
    {
      "id": "input",
      "name": "Input",
      "use": "A single value that a person can enter, inspect and correct.",
      "avoid": "A fixed short choice set, which should use controls or a segmented selector.",
      "accessibility": "Keep a visible label, connect help and error text, and preserve the value after validation fails.",
      "markup": "<label class=\"neutral-field\">\n  <span>Incident owner</span>\n  <input type=\"text\" name=\"owner\" value=\"Provider operations\">\n  <small>Team responsible for the next action.</small>\n</label>"
    },
    {
      "id": "controls",
      "name": "Checkbox, radio and switch",
      "use": "Independent options, one-of-many choices and reversible settings respectively.",
      "avoid": "A command that takes effect immediately or a multi-step decision.",
      "accessibility": "Use native inputs inside visible labels. Do not encode selection by colour alone.",
      "markup": "<fieldset class=\"neutral-control-set\">\n  <legend>Evidence sources</legend>\n  <label><input type=\"checkbox\" checked> Metrics</label>\n  <label><input type=\"checkbox\"> Logs</label>\n  <label class=\"neutral-switch\"><input type=\"checkbox\" checked role=\"switch\"> Auto-refresh</label>\n</fieldset>"
    },
    {
      "id": "badge",
      "name": "Badge",
      "use": "A compact state attached to an object, with words as well as a semantic marker.",
      "avoid": "Navigation, actions or decorative categorisation.",
      "accessibility": "The readable label carries the state. Never rely on the dot or colour alone.",
      "markup": "<span class=\"neutral-badge neutral-badge--warning\"><i aria-hidden=\"true\"></i>Degraded</span>"
    },
    {
      "id": "pill",
      "name": "Pill",
      "use": "A short filter or selectable classification in a compact set.",
      "avoid": "Status, long labels or a primary call to action.",
      "accessibility": "Use aria-pressed for toggle pills and retain a 32px pointer or 44px touch target.",
      "markup": "<div class=\"neutral-pill-group\" aria-label=\"Filter incidents\">\n  <button class=\"neutral-pill\" type=\"button\" aria-pressed=\"true\">Active</button>\n  <button class=\"neutral-pill\" type=\"button\" aria-pressed=\"false\">Resolved</button>\n</div>"
    },
    {
      "id": "card",
      "name": "Card",
      "use": "One coherent object or choice that benefits from a bounded click or reading target.",
      "avoid": "Wrapping every paragraph, metric or adjacent region in a separate box.",
      "accessibility": "Keep heading order intact. If the whole card is interactive, use one real link over the card.",
      "markup": "<article class=\"neutral-card\">\n  <span class=\"neutral-status neutral-status--warning\">Investigating</span>\n  <h3>Training throughput degraded</h3>\n  <p>8 GPUs · 47 min · likely network fabric</p>\n  <a class=\"neutral-link\" href=\"/incidents/INC-2048\">Open incident</a>\n</article>"
    },
    {
      "id": "table",
      "name": "Table",
      "use": "Comparing many peer records with consistent fields, sorting and exact quantities.",
      "avoid": "One record, prose or a layout grid masquerading as data.",
      "accessibility": "Use a real table, scoped headers and labels for sorting. Right-align numeric columns.",
      "markup": "<div class=\"neutral-table-scroll\">\n  <table class=\"neutral-data-table\">\n    <thead><tr><th scope=\"col\">GPU</th><th scope=\"col\">State</th><th scope=\"col\" class=\"is-numeric\">Goodput</th></tr></thead>\n    <tbody><tr><td>gpu-042</td><td><span class=\"neutral-status neutral-status--warning\">Degraded</span></td><td class=\"is-numeric\">82.7%</td></tr></tbody>\n  </table>\n</div>"
    },
    {
      "id": "note",
      "name": "Note",
      "use": "A scoped warning, error or important qualification that remains near affected content.",
      "avoid": "Routine descriptions, promotional callouts or transient success confirmation.",
      "accessibility": "Use an appropriate role only when the message should be announced immediately.",
      "markup": "<div class=\"neutral-note neutral-note--warning\">\n  <strong>Action requires approval.</strong>\n  <p>Moving the workload will interrupt the current training step.</p>\n</div>"
    },
    {
      "id": "dialog",
      "name": "Dialog",
      "use": "A focused decision that must be completed or dismissed before the parent flow continues.",
      "avoid": "Supplementary detail, navigation or a non-blocking confirmation.",
      "accessibility": "Use a native dialog, label it with its heading, trap focus while open and return focus on close.",
      "markup": "<dialog class=\"neutral-dialog\" open aria-labelledby=\"dialog-title\">\n  <h2 id=\"dialog-title\">Stop remediation?</h2>\n  <p>The current safe action will finish before the process stops.</p>\n  <div class=\"neutral-action-group\"><button class=\"neutral-button\" type=\"button\">Cancel</button><button class=\"neutral-button neutral-button--primary\" type=\"button\">Stop</button></div>\n</dialog>"
    },
    {
      "id": "toast",
      "name": "Toast",
      "use": "Confirming a completed, non-blocking action and optionally offering one reversible undo.",
      "avoid": "Errors that need attention or decisions that require an answer.",
      "accessibility": "Use role=status with aria-live=polite and keep any Undo control reachable long enough.",
      "markup": "<div class=\"neutral-toast\" role=\"status\" aria-live=\"polite\">Evidence pack exported. <button type=\"button\">Undo</button></div>"
    },
    {
      "id": "empty-state",
      "name": "Empty state",
      "use": "A first run, filtered result with no matches or genuinely empty collection.",
      "avoid": "Loading, errors or hiding unavailable data behind a cheerful illustration.",
      "accessibility": "Use the correct heading level and make the single next action a real control.",
      "markup": "<div class=\"neutral-empty\">\n  <h3>No incidents in this range.</h3>\n  <p>Change the time range or clear filters to inspect earlier evidence.</p>\n  <button class=\"neutral-button\" type=\"button\">Clear filters</button>\n</div>"
    },
    {
      "id": "app-shell",
      "name": "App shell and navigation",
      "use": "The persistent frame for Neutral product routes, global navigation and page content.",
      "avoid": "The marketing website or a one-off branded document.",
      "accessibility": "Use a labelled navigation element, aria-current on the active route and main for page content.",
      "markup": "<div class=\"neutral-app-shell neutral-app-shell--preview\">\n  <nav class=\"neutral-sidebar\" aria-label=\"Product\"><a class=\"neutral-nav-item\" href=\"/overview\">Overview</a><a class=\"neutral-nav-item\" href=\"/incidents\" aria-current=\"page\">Incidents</a></nav>\n  <main class=\"neutral-page\"><h2>Incidents</h2><p>Operational records and evidence.</p></main>\n</div>"
    },
    {
      "id": "page-header",
      "name": "Page header and toolbar",
      "use": "The top of every product page or detail view: context, title, purpose and page-level actions.",
      "avoid": "A marketing hero or a local panel heading.",
      "accessibility": "Use the page’s h1, a labelled breadcrumb nav and explicit labels for toolbar controls.",
      "markup": "<header class=\"neutral-page-header\">\n  <div><nav class=\"neutral-breadcrumbs\" aria-label=\"Breadcrumb\"><a href=\"/incidents\">Incidents</a><span>INC-2048</span></nav><h2>Training throughput degraded</h2></div>\n  <div class=\"neutral-action-group\"><button class=\"neutral-button\">Export</button><button class=\"neutral-button neutral-button--primary\">View evidence</button></div>\n</header>"
    },
    {
      "id": "stat",
      "name": "Stat",
      "use": "Two to four peer metrics that materially explain an operational state.",
      "avoid": "A number that belongs in a table row or a decorative KPI without a baseline.",
      "accessibility": "Place the label before the value and spell out direction or comparison in the context text.",
      "markup": "<div class=\"neutral-stat-grid\">\n  <div class=\"neutral-stat\"><span class=\"neutral-stat__label\">Goodput</span><strong class=\"neutral-stat__value\">82.7%</strong><span class=\"neutral-stat__context\">−17.3% from baseline</span></div>\n  <div class=\"neutral-stat\"><span class=\"neutral-stat__label\">Affected</span><strong class=\"neutral-stat__value\">8 GPUs</strong><span class=\"neutral-stat__context\">one workload</span></div>\n</div>"
    },
    {
      "id": "description-list",
      "name": "Description list",
      "use": "The attributes, evidence metadata or SLA terms of one record.",
      "avoid": "More than one peer record, which should use a table.",
      "accessibility": "Use a real dl with matching dt and dd pairs; keep nested links and statuses semantic.",
      "markup": "<dl class=\"neutral-description-list\">\n  <div><dt>Confidence</dt><dd>High</dd></div>\n  <div><dt>Supporting signals</dt><dd>14</dd></div>\n  <div><dt>Owner</dt><dd>Provider operations</dd></div>\n</dl>"
    },
    {
      "id": "skeleton",
      "name": "Skeleton",
      "use": "The first useful load of a list, table, stat or card when the final geometry is known.",
      "avoid": "Actions under 300ms, background refresh, errors or missing data.",
      "accessibility": "Mark the loading region aria-busy and keep the decorative skeleton aria-hidden.",
      "markup": "<div class=\"neutral-skeleton-stack\" aria-busy=\"true\">\n  <span class=\"neutral-skeleton neutral-skeleton--wide\" aria-hidden=\"true\"></span>\n  <span class=\"neutral-skeleton\" aria-hidden=\"true\"></span>\n  <span class=\"neutral-skeleton neutral-skeleton--short\" aria-hidden=\"true\"></span>\n</div>"
    },
    {
      "id": "density",
      "name": "Density and sizes",
      "use": "Adapting controls and rows to standard, compact, dense or touch-heavy work without changing hierarchy.",
      "avoid": "Shrinking text or targets ad hoc to force more information onto a screen.",
      "accessibility": "Dense pointer controls return to 44px targets on coarse pointers. Text remains fully legible.",
      "markup": "<div class=\"neutral-density-demo\">\n  <div data-density=\"standard\"><span>Standard</span><button class=\"neutral-button\">36px control</button></div>\n  <div data-density=\"dense\"><span>Dense</span><button class=\"neutral-button\">28px control</button></div>\n  <div data-density=\"touch\"><span>Touch</span><button class=\"neutral-button\">44px control</button></div>\n</div>"
    },
    {
      "id": "tabs",
      "name": "Tabs",
      "use": "Two to six sections of one record or workspace whose content changes in place.",
      "avoid": "Steps in a flow, filters or navigation between unrelated pages.",
      "accessibility": "Use a tablist, tab buttons, aria-selected, labelled tabpanels and arrow-key navigation.",
      "markup": "<div class=\"neutral-tabs\" role=\"tablist\" aria-label=\"Incident\">\n  <button type=\"button\" role=\"tab\" aria-selected=\"true\">Overview</button>\n  <button type=\"button\" role=\"tab\" aria-selected=\"false\">Evidence</button>\n  <button type=\"button\" role=\"tab\" aria-selected=\"false\">Activity</button>\n</div>"
    },
    {
      "id": "menu-tooltip",
      "name": "Menu and tooltip",
      "use": "Menus group three or more secondary actions; tooltips label icon-only controls and concise shortcuts.",
      "avoid": "A menu with one action or a tooltip containing essential help or interactive content.",
      "accessibility": "Expose expanded state, use menu semantics, close with Escape and connect tooltips with aria-describedby.",
      "markup": "<div class=\"neutral-menu-demo\">\n  <button class=\"neutral-button\" type=\"button\" aria-haspopup=\"menu\" aria-expanded=\"true\">More actions</button>\n  <div class=\"neutral-menu\" role=\"menu\"><button role=\"menuitem\">Assign owner</button><button role=\"menuitem\">Export evidence</button><button role=\"menuitem\">Archive</button></div>\n</div>"
    },
    {
      "id": "pagination-forms",
      "name": "Pagination and forms",
      "use": "Paging long operational tables and arranging create or edit forms on a consistent grid.",
      "avoid": "Infinite scroll in data tables or a single field stretched across a wide page.",
      "accessibility": "Label pagination, mark the current page and preserve source order through responsive form layouts.",
      "markup": "<div class=\"neutral-form-example\">\n  <nav class=\"neutral-pagination\" aria-label=\"Pagination\"><button type=\"button\">Previous</button><button type=\"button\" aria-current=\"page\">1</button><button type=\"button\">2</button><button type=\"button\">Next</button></nav>\n  <div class=\"neutral-form-grid\"><label class=\"neutral-field\"><span>Owner</span><input value=\"Provider operations\"></label><label class=\"neutral-field\"><span>Priority</span><select><option>High</option></select></label></div>\n</div>"
    }
  ]
}
