{
  "version": "0.2.0-preview.1",
  "content_digest": "70ac710f4d22dce040e7ac593379ba8aca9dcb59a0b9c0f839819cae0e2bb721",
  "status": "preview",
  "authority": {
    "repository": "cloakedinc/design",
    "path": "packages/design-system",
    "catalog": "packages/design-system/catalog.json",
    "status": "preview"
  },
  "provenance": {
    "repo": "cloakedinc/automation",
    "commit": "f96f416e1c3bfbfaffcd155a88b87b18b8bb25f1",
    "path": "packages/design-system",
    "imported_spec_status": "approved"
  },
  "adaptations": [
    {
      "id": "button-content-gap",
      "status": "preview",
      "description": "Use the specification's 4px content gap instead of the inherited 8px implementation gap."
    },
    {
      "id": "keyboard-focus",
      "status": "preview",
      "description": "Add visible Button and Input keyboard focus and an overridable inset focus default for shared button resets, including FAQ cards and ListItem rows."
    },
    {
      "id": "supporting-text-contrast",
      "status": "preview",
      "description": "Map light secondary text to the existing grey-04-strong primitive for readable helper text on white and cream."
    },
    {
      "id": "danger-text-contrast",
      "status": "preview",
      "description": "Separate readable danger text/borders from destructive fills; preserve the primary danger-button fill and label pair."
    },
    {
      "id": "preview-status",
      "status": "preview",
      "description": "Local components, specs and token adaptations await human sign-off; upstream approved status is provenance only."
    },
    {
      "id": "motion-comparison-accessibility",
      "status": "preview",
      "description": "Preserve the original MotionShowcase comparisons while requiring explicit replay, responding to live reduced-motion changes, and keeping duration tracks usable on small screens."
    },
    {
      "id": "list-item-ownership",
      "status": "preview",
      "description": "List owns listitem wrappers for its content rows, while section labels stay outside the row count and standalone rows retain their existing semantics."
    },
    {
      "id": "card-delta-text-contrast",
      "status": "preview",
      "description": "Mix Card.Delta foregrounds from 60% existing tone solid and 40% primary text for readable contrast in both themes; preserve the four original tone fills."
    },
    {
      "id": "carousel-keyboard-access",
      "status": "preview",
      "description": "Keep all native-scrolling carousel slide controls exposed to assistive technology and keyboard navigation; pause autoplay while focus is inside the carousel."
    }
  ],
  "id": "accordion",
  "name": "Accordion",
  "category": "Organization",
  "contract_status": "preview",
  "contract_kind": "source-derived",
  "review": {
    "local_status": "not-reviewed",
    "source_approval": null,
    "imported_spec_status": "approved",
    "spec_origin": "imported-adapted",
    "local_spec_source_status": "approved",
    "imported_source_revision": "f96f416e1c3bfbfaffcd155a88b87b18b8bb25f1",
    "note": "Inherited specification status is provenance, not approval of the current local implementation or extracted contract."
  },
  "approval": "required",
  "visual_reference": {
    "stories": [
      {
        "id": "cloaked-design-system-organization-accordion--playground",
        "name": "Playground",
        "title": "Cloaked Design System/Organization/Accordion",
        "exportName": "Playground",
        "source_path": "packages/design-system/src/components/organization/Accordion/Accordion.stories.tsx",
        "source_digest": "a40422c09fb39a8bc152ede951eecdd1ba390683f7a2e6c63c3badbbc71ff5a2",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-organization-accordion--playground&viewMode=story"
      },
      {
        "id": "cloaked-design-system-organization-accordion--initially-open",
        "name": "Initially Open",
        "title": "Cloaked Design System/Organization/Accordion",
        "exportName": "InitiallyOpen",
        "source_path": "packages/design-system/src/components/organization/Accordion/Accordion.stories.tsx",
        "source_digest": "a40422c09fb39a8bc152ede951eecdd1ba390683f7a2e6c63c3badbbc71ff5a2",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-organization-accordion--initially-open&viewMode=story"
      },
      {
        "id": "cloaked-design-system-organization-accordion--single-open",
        "name": "Single Open",
        "title": "Cloaked Design System/Organization/Accordion",
        "exportName": "SingleOpen",
        "source_path": "packages/design-system/src/components/organization/Accordion/Accordion.stories.tsx",
        "source_digest": "a40422c09fb39a8bc152ede951eecdd1ba390683f7a2e6c63c3badbbc71ff5a2",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-organization-accordion--single-open&viewMode=story"
      },
      {
        "id": "cloaked-design-system-organization-accordion--with-leading",
        "name": "With Leading",
        "title": "Cloaked Design System/Organization/Accordion",
        "exportName": "WithLeading",
        "source_path": "packages/design-system/src/components/organization/Accordion/Accordion.stories.tsx",
        "source_digest": "a40422c09fb39a8bc152ede951eecdd1ba390683f7a2e6c63c3badbbc71ff5a2",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-organization-accordion--with-leading&viewMode=story"
      },
      {
        "id": "cloaked-design-system-organization-accordion--with-disabled-item",
        "name": "With Disabled Item",
        "title": "Cloaked Design System/Organization/Accordion",
        "exportName": "WithDisabledItem",
        "source_path": "packages/design-system/src/components/organization/Accordion/Accordion.stories.tsx",
        "source_digest": "a40422c09fb39a8bc152ede951eecdd1ba390683f7a2e6c63c3badbbc71ff5a2",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-organization-accordion--with-disabled-item&viewMode=story"
      },
      {
        "id": "cloaked-design-system-organization-accordion--many-items",
        "name": "Many Items",
        "title": "Cloaked Design System/Organization/Accordion",
        "exportName": "ManyItems",
        "source_path": "packages/design-system/src/components/organization/Accordion/Accordion.stories.tsx",
        "source_digest": "a40422c09fb39a8bc152ede951eecdd1ba390683f7a2e6c63c3badbbc71ff5a2",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-organization-accordion--many-items&viewMode=story"
      },
      {
        "id": "cloaked-design-system-organization-accordion--long-text",
        "name": "Long Text",
        "title": "Cloaked Design System/Organization/Accordion",
        "exportName": "LongText",
        "source_path": "packages/design-system/src/components/organization/Accordion/Accordion.stories.tsx",
        "source_digest": "a40422c09fb39a8bc152ede951eecdd1ba390683f7a2e6c63c3badbbc71ff5a2",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-organization-accordion--long-text&viewMode=story"
      },
      {
        "id": "cloaked-design-system-organization-accordion--dark-theme",
        "name": "Dark Theme",
        "title": "Cloaked Design System/Organization/Accordion",
        "exportName": "DarkTheme",
        "source_path": "packages/design-system/src/components/organization/Accordion/Accordion.stories.tsx",
        "source_digest": "a40422c09fb39a8bc152ede951eecdd1ba390683f7a2e6c63c3badbbc71ff5a2",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-organization-accordion--dark-theme&viewMode=story"
      }
    ],
    "name": "Accordion",
    "id": "accordion",
    "category": "Organization"
  },
  "stories_source": {
    "path": "packages/design-system/src/components/organization/Accordion/Accordion.stories.tsx",
    "code": "import React from 'react';\nimport type { Meta, StoryObj } from '@storybook/react-vite';\nimport { Avatar } from '../../primitives/Avatar/Avatar';\nimport { Text } from '../../primitives/Text/Text';\nimport { disabledControl, hapticArgType } from '../../../storybook/controlOptions';\nimport { Accordion } from './Accordion';\n\nconst ITEMS = [\n    {\n        id: 'monitoring',\n        title: 'Monitoring',\n        description: 'What Cloaked watches for you',\n        content: (\n            <Text variant='body-small' color='secondary' as='p'>\n                We monitor broker sites, dark web exposure, and account activity.\n            </Text>\n        ),\n    },\n    {\n        id: 'notifications',\n        title: 'Notifications',\n        content: (\n            <Text variant='body-small' color='secondary' as='p'>\n                You will receive alerts when something needs your attention.\n            </Text>\n        ),\n    },\n];\n\nconst ITEMS_WITH_DISABLED = [\n    ...ITEMS,\n    {\n        id: 'disabled',\n        title: 'Locked section',\n        description: 'Available after setup',\n        content: 'Locked content',\n        disabled: true,\n    },\n];\n\nconst ITEMS_WITH_LEADING = [\n    {\n        id: 'accudata',\n        leading: <Avatar type='initials' size='md' initial='A' ariaLabel='AccuData' />,\n        title: 'AccuData',\n        description: '1 record removed',\n        content: 'Sent on August 11, 2026.',\n    },\n    {\n        id: 'americaphonebook',\n        leading: <Avatar type='initials' size='md' initial='A' ariaLabel='AmericaPhoneBook' />,\n        title: 'AmericaPhoneBook',\n        description: '2 records removed',\n        content: 'Sent on August 11, 2026.',\n    },\n];\n\nconst MANY_ITEMS = [\n    ...ITEMS,\n    {\n        id: 'data',\n        title: 'Data sources',\n        description: 'Where the scan looks',\n        content: 'Public records, broker sites, and known exposure sources.',\n    },\n    {\n        id: 'support',\n        title: 'Support',\n        description: 'How to get help',\n        content: 'Contact support if you need help with a removal request.',\n    },\n];\n\nconst meta: Meta<typeof Accordion> = {\n    title: 'Cloaked Design System/Organization/Accordion',\n    component: Accordion,\n    parameters: {\n        a11y: { test: 'error' },\n        docs: {\n            description: {\n                component:\n                    'Standalone grouped disclosure — independent expandable sections with their own chrome, ' +\n                    'driven by an `items` array (FAQ panels, settings groups). Reach for `List.Disclosure` ' +\n                    'instead when you need a single \"show more\" row that reveals extra `List.Item`s inside an ' +\n                    'existing `List` and shares its separators. `multiple` (the default) lets several panels ' +\n                    'stay open at once; set it `false` for radio-style single-open.',\n            },\n        },\n    },\n    args: {\n        items: ITEMS,\n        testId: 'accordion',\n    },\n    argTypes: {\n        items: {\n            ...disabledControl,\n            description:\n                'Ordered `AccordionItem[]` — each has an `id`, `title`, optional `leading`, `description`, `content`, and `disabled`.',\n        },\n        openItemIds: {\n            ...disabledControl,\n            description: 'Controlled set of open item ids. Pair with `onOpenChange`; omit for uncontrolled use.',\n        },\n        defaultOpenItemIds: {\n            ...disabledControl,\n            description: 'Item ids expanded on mount for uncontrolled usage.',\n        },\n        multiple: {\n            control: 'boolean',\n            description:\n                'Allow multiple panels open at once. `false` collapses siblings when a row opens. Defaults to `true`.',\n        },\n        onOpenChange: {\n            ...disabledControl,\n            description: 'Fires with the next open-id array whenever a row toggles.',\n        },\n        haptic: {\n            ...hapticArgType,\n            description: 'Haptic fired on row toggle. Defaults to `true` (`selection`).',\n        },\n    },\n    decorators: [\n        Story => (\n            <div\n                style={{\n                    width: 'min(calc(100vw - var(--cds-space-32)), calc(var(--cds-size-240) + var(--cds-size-80)))',\n                }}\n            >\n                {Story()}\n            </div>\n        ),\n    ],\n};\nexport default meta;\ntype Story = StoryObj<typeof Accordion>;\n\nexport const Playground: Story = {};\n\nexport const InitiallyOpen: Story = {\n    args: {\n        items: ITEMS,\n        defaultOpenItemIds: ['monitoring'],\n    },\n    parameters: {\n        docs: { description: { story: 'Uncontrolled, with `defaultOpenItemIds` expanding a panel on mount.' } },\n    },\n};\n\nexport const SingleOpen: Story = {\n    args: {\n        items: ITEMS,\n        multiple: false,\n        defaultOpenItemIds: ['monitoring'],\n    },\n    parameters: {\n        docs: { description: { story: '`multiple={false}` — opening a panel collapses the others (radio-style).' } },\n    },\n};\n\nexport const WithLeading: Story = {\n    args: {\n        items: ITEMS_WITH_LEADING,\n        defaultOpenItemIds: ['accudata'],\n    },\n    parameters: {\n        docs: {\n            description: {\n                story: 'A `leading` element identifies each row. It holds its width, so a long title wraps beside it rather than squeezing it.',\n            },\n        },\n    },\n};\n\nexport const WithDisabledItem: Story = {\n    args: {\n        items: ITEMS_WITH_DISABLED,\n    },\n    parameters: {\n        docs: { description: { story: 'A `disabled` item reads as inert and cannot be toggled.' } },\n    },\n};\n\nexport const ManyItems: Story = {\n    args: {\n        items: MANY_ITEMS,\n        defaultOpenItemIds: ['monitoring', 'data'],\n    },\n    parameters: {\n        docs: { description: { story: 'Multiple panels open at once (the default `multiple` behavior).' } },\n    },\n};\n\nexport const LongText: Story = {\n    parameters: {\n        docs: { description: { story: 'Long titles and body copy wrap without widening the container.' } },\n    },\n    args: {\n        items: [\n            {\n                id: 'long',\n                title: 'A longer disclosure title that should wrap without resizing the sheet horizontally',\n                description: 'Long supporting copy should wrap naturally.',\n                content: (\n                    <Text variant='body-small' color='secondary' as='p'>\n                        Long panel content should remain readable inside the mobile-width container and should not push\n                        the accordion wider than its parent surface.\n                    </Text>\n                ),\n            },\n        ],\n        defaultOpenItemIds: ['long'],\n    },\n};\n\nexport const DarkTheme: Story = {\n    globals: { theme: 'dark' },\n    args: {\n        items: ITEMS,\n        defaultOpenItemIds: ['monitoring'],\n    },\n    parameters: {\n        docs: { description: { story: 'Rows and animated panels on the dark theme surface.' } },\n    },\n};\n"
  },
  "specification": {
    "$schema": "../../../specs/component-spec.schema.json",
    "identity": {
      "name": "Accordion",
      "status": "preview",
      "version": "1.0.0",
      "summary": "Grouped disclosure of independent expandable sections driven by an items array, with animated panels."
    },
    "parts": [
      {
        "id": "root",
        "label": "Root",
        "description": "Edge-to-edge surface stacking disclosure items with separators; carries no radius or inset of its own.",
        "required": true
      },
      {
        "id": "item",
        "label": "Item",
        "description": "A single expandable section."
      },
      {
        "id": "trigger",
        "label": "Trigger",
        "description": "Row button that toggles its panel and rotates the chevron."
      },
      {
        "id": "leading",
        "label": "Leading",
        "description": "Optional element before the trigger copy, such as an avatar or brand logo."
      },
      {
        "id": "panel",
        "label": "Panel",
        "description": "Animated region revealed when the item is open."
      }
    ],
    "allowedDesignChoices": {
      "variants": {
        "grouped": {
          "label": "Grouped",
          "description": "The single grouped-disclosure treatment."
        }
      },
      "sizes": {}
    },
    "variants": [
      {
        "id": "grouped",
        "label": "Grouped",
        "description": "Independent expandable sections with shared chrome.",
        "platforms": [
          "ios",
          "android",
          "web"
        ]
      }
    ],
    "sizes": [],
    "measurements": [
      {
        "id": "trigger-gap",
        "label": "Trigger content gap",
        "kind": "exact",
        "token": "--cds-space-12",
        "value": 12,
        "unit": "px",
        "appliesTo": [
          "trigger"
        ]
      },
      {
        "id": "trigger-min-height",
        "label": "Trigger minimum height",
        "kind": "at-least",
        "token": "--cds-size-48",
        "value": 48,
        "unit": "px",
        "appliesTo": [
          "trigger"
        ]
      },
      {
        "id": "trigger-inset",
        "label": "Trigger horizontal inset",
        "kind": "exact",
        "token": "--cds-space-20",
        "value": 20,
        "unit": "px",
        "appliesTo": [
          "trigger",
          "panel"
        ]
      }
    ],
    "layout": {
      "alignment": "An optional leading element sits first at a fixed width, trigger copy is flexible, and the chevron stays trailing.",
      "flow": "Items stack vertically with a hairline between adjacent rows and an animated panel per item.",
      "notes": [
        "Use List.Disclosure for a single show-more row that shares a list's separators.",
        "Edge to edge like ListRoot: the enclosing Screen.Section or Card owns radius and inset. Rows match List.Item padding='card' metrics."
      ]
    },
    "typographyAndColor": {
      "typography": [
        {
          "label": "Title",
          "description": "Trigger titles use the body ramp.",
          "token": "--cds-type-body-size"
        },
        {
          "label": "Description",
          "description": "Trigger descriptions use the body-small ramp.",
          "token": "--cds-type-body-small-size"
        }
      ],
      "colors": [
        {
          "label": "Surface",
          "description": "The accordion paints the raised surface edge to edge; the parent owns shape and inset.",
          "token": "--cds-bg-surface"
        },
        {
          "label": "Separator",
          "description": "Adjacent items are divided with the shared list divider tone.",
          "token": "--cds-divider"
        },
        {
          "label": "Chevron",
          "description": "The chevron uses secondary text color.",
          "token": "--cds-text-secondary"
        }
      ]
    },
    "states": [
      {
        "id": "closed",
        "label": "Closed",
        "description": "Collapsed item with a downward chevron."
      },
      {
        "id": "open",
        "label": "Open",
        "description": "Expanded item, aria-expanded true, chevron rotated."
      },
      {
        "id": "disabled",
        "label": "Disabled",
        "description": "Inert item that cannot be toggled."
      }
    ],
    "behavior": [
      {
        "label": "Multiple open",
        "description": "multiple (default) lets several panels stay open; false collapses siblings."
      },
      {
        "label": "Controlled or uncontrolled",
        "description": "Drive openItemIds for controlled use or defaultOpenItemIds for uncontrolled."
      }
    ],
    "accessibility": [
      {
        "label": "Disclosure semantics",
        "description": "Each trigger sets aria-expanded and aria-controls; the panel is a labelled region."
      },
      {
        "label": "Keyboard",
        "description": "Triggers are buttons reachable and toggleable by keyboard."
      }
    ],
    "contentAdaptation": [
      {
        "label": "Wrapping copy",
        "description": "Long titles and descriptions wrap without widening the container."
      },
      {
        "label": "Optional description",
        "description": "The description line renders only when provided."
      },
      {
        "label": "Optional leading element",
        "description": "The leading slot renders only when provided and never shrinks under long copy."
      }
    ],
    "motionHaptics": {
      "motion": [
        {
          "label": "Expand and collapse",
          "description": "Panels open on a 500ms decelerating curve and close on a 400ms ease-in; disabled under reduced motion."
        }
      ],
      "haptics": [
        {
          "label": "Toggle haptic",
          "description": "Toggling a row requests the selection haptic."
        }
      ]
    },
    "platformDifferences": []
  },
  "specification_source": "packages/design-system/src/components/organization/Accordion/Accordion.spec.json",
  "guidance": {
    "summary": "Grouped disclosure of independent expandable sections driven by an items array, with animated panels.",
    "guidance": [
      {
        "heading": "Overview",
        "body": "Standalone grouped disclosure — independent collapsible sections, each with its own chrome, driven\nby an `items` array."
      },
      {
        "heading": "When to use",
        "body": "Reach for `Accordion` when you have several sections whose bodies should stay hidden until tapped —\nFAQ panels, settings groups, \"learn more\" blocks. `multiple` (the default) lets panels open\nindependently; set it `false` for radio-style single-open.\n\n-   Rows that are always visible and just stack flat? Use `List` — the container owns the hairlines.\n-   One \"show more\" row that reveals extra rows _inside_ an existing `List`? Use `List.Disclosure`,\n    which shares the list's separators instead of adding its own chrome.\n-   Peer panels the user switches between (only one shown at a time, no stacking)? Use `Tabs`."
      }
    ],
    "usage": [],
    "examples": [],
    "source": "packages/design-system/src/components/organization/Accordion/Accordion.mdx",
    "status": "local-preview",
    "note": "Guidance is read from local documentation, originally imported from the frozen source. Platform assertions in guidance are not parity verification."
  },
  "links": {
    "human": "/component-accordion",
    "json": "/data/visual/components/accordion.json",
    "storybook": "/storybook/?path=/story/cloaked-design-system-organization-accordion--playground"
  }
}
