{
  "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": "selectionindicator",
  "name": "SelectionIndicator",
  "category": "Primitives",
  "contract_status": "preview",
  "contract_kind": "source-derived",
  "review": {
    "local_status": "not-reviewed",
    "source_approval": null,
    "imported_spec_status": null,
    "spec_origin": "local-authored",
    "local_spec_source_status": "preview",
    "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-primitives-selectionindicator--playground",
        "name": "Playground",
        "title": "Cloaked Design System/Primitives/SelectionIndicator",
        "exportName": "Playground",
        "source_path": "packages/design-system/src/components/primitives/SelectionIndicator/SelectionIndicator.stories.tsx",
        "source_digest": "425be15fe9b395b00b78feb2e109bcfc7294285358df5822e7a48807b72c3504",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-primitives-selectionindicator--playground&viewMode=story"
      },
      {
        "id": "cloaked-design-system-primitives-selectionindicator--states",
        "name": "States",
        "title": "Cloaked Design System/Primitives/SelectionIndicator",
        "exportName": "States",
        "source_path": "packages/design-system/src/components/primitives/SelectionIndicator/SelectionIndicator.stories.tsx",
        "source_digest": "425be15fe9b395b00b78feb2e109bcfc7294285358df5822e7a48807b72c3504",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-primitives-selectionindicator--states&viewMode=story"
      },
      {
        "id": "cloaked-design-system-primitives-selectionindicator--dark-theme",
        "name": "Dark Theme",
        "title": "Cloaked Design System/Primitives/SelectionIndicator",
        "exportName": "DarkTheme",
        "source_path": "packages/design-system/src/components/primitives/SelectionIndicator/SelectionIndicator.stories.tsx",
        "source_digest": "425be15fe9b395b00b78feb2e109bcfc7294285358df5822e7a48807b72c3504",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-primitives-selectionindicator--dark-theme&viewMode=story"
      }
    ],
    "name": "SelectionIndicator",
    "id": "selectionindicator",
    "category": "Primitives"
  },
  "stories_source": {
    "path": "packages/design-system/src/components/primitives/SelectionIndicator/SelectionIndicator.stories.tsx",
    "code": "import type { Meta, StoryObj } from '@storybook/react-vite';\nimport React from 'react';\nimport { selectArgType } from '../../../storybook/controlOptions';\nimport { HStack } from '../../layout/HStack/HStack';\nimport { VStack } from '../../layout/VStack/VStack';\nimport { Text } from '../Text/Text';\nimport { SelectionIndicator, type SelectionGlyph } from './SelectionIndicator';\n\nconst GLYPHS = ['check', 'dot'] as const satisfies readonly SelectionGlyph[];\n\nconst meta: Meta<typeof SelectionIndicator> = {\n    title: 'Cloaked Design System/Primitives/SelectionIndicator',\n    component: SelectionIndicator,\n    parameters: {\n        docs: {\n            description: {\n                component:\n                    'Shared DS 4.5 selection chip — a round 32px control that renders grey when off and a filled ' +\n                    '`--cds-bg-bold` chip when on, with a `check` glyph for checkboxes and a `dot` for radios. This is ' +\n                    'an internal building block used by `Checkbox`, `Radio`, and `RadioGroup`; it is not exported from ' +\n                    'the package. Reach for `Checkbox` or `Radio` in app code — they wrap this with the correct ' +\n                    'interaction and accessibility semantics.',\n            },\n        },\n    },\n    args: { selected: true, glyph: 'check' },\n    argTypes: {\n        selected: { control: 'boolean', description: 'Renders the filled (selected) treatment.' },\n        glyph: { ...selectArgType(GLYPHS), description: 'Glyph shown when selected: `check` or `dot`.' },\n        disabled: { control: 'boolean', description: 'Dims the chip to the disabled treatment.' },\n    },\n};\nexport default meta;\ntype Story = StoryObj<typeof SelectionIndicator>;\n\nexport const Playground: Story = {};\n\n/** Every glyph × selected × disabled combination the chip can render. */\nexport const States: Story = {\n    render: () => (\n        <VStack gap={16}>\n            {GLYPHS.map(glyph => (\n                <HStack key={glyph} gap={16} align='center'>\n                    <ChipState label={`${glyph} · off`} glyph={glyph} selected={false} />\n                    <ChipState label={`${glyph} · on`} glyph={glyph} selected />\n                    <ChipState label={`${glyph} · off disabled`} glyph={glyph} selected={false} disabled />\n                    <ChipState label={`${glyph} · on disabled`} glyph={glyph} selected disabled />\n                </HStack>\n            ))}\n        </VStack>\n    ),\n};\n\nexport const DarkTheme: Story = {\n    globals: { theme: 'dark' },\n    parameters: { docs: { description: { story: 'The chip fills and glyph tokens on the dark theme.' } } },\n};\n\nfunction ChipState({\n    label,\n    glyph,\n    selected,\n    disabled = false,\n}: {\n    label: string;\n    glyph: SelectionGlyph;\n    selected: boolean;\n    disabled?: boolean;\n}) {\n    return (\n        <VStack gap={8} align='center'>\n            <SelectionIndicator glyph={glyph} selected={selected} disabled={disabled} />\n            <Text variant='body-small' color='secondary'>\n                {label}\n            </Text>\n        </VStack>\n    );\n}\n"
  },
  "specification": {
    "$schema": "../../../specs/component-spec.schema.json",
    "identity": {
      "name": "SelectionIndicator",
      "status": "preview",
      "version": "0.1.0-preview.1",
      "summary": "An internal, presentational selection mark shared by public Checkbox, Radio, RadioGroup and list selection rows. It is not a package-root export and must not be used as an interactive control."
    },
    "parts": [
      {
        "id": "chip",
        "label": "Circular container",
        "description": "Hosts the selected or unselected fill.",
        "required": true
      },
      {
        "id": "glyph",
        "label": "Selection mark",
        "description": "Check icon for multiple choice or a small filled dot for single choice; absent when unselected.",
        "required": false
      }
    ],
    "allowedDesignChoices": {
      "variants": {
        "check": {
          "label": "Check",
          "description": "Multiple-choice visual."
        },
        "dot": {
          "label": "Dot",
          "description": "Single-choice visual."
        }
      },
      "sizes": {}
    },
    "variants": [
      {
        "id": "check",
        "label": "Check",
        "description": "selected=true renders a 24px check icon with stroke width 2.",
        "platforms": [
          "web"
        ]
      },
      {
        "id": "dot",
        "label": "Dot",
        "description": "selected=true renders an 8px filled circle.",
        "platforms": [
          "web"
        ]
      }
    ],
    "sizes": [],
    "measurements": [
      {
        "id": "default-diameter",
        "label": "Default chip diameter",
        "kind": "exact",
        "token": "--cds-size-32",
        "value": 32,
        "unit": "px",
        "appliesTo": [
          "chip"
        ],
        "notes": "A private --selection-indicator-size hook lets owning controls replace an existing visual footprint; this is not a public size prop."
      },
      {
        "id": "dot-diameter",
        "label": "Selected dot diameter",
        "kind": "exact",
        "token": "--cds-size-8",
        "value": 8,
        "unit": "px",
        "appliesTo": [
          "glyph"
        ]
      },
      {
        "id": "radius",
        "label": "Circular shape",
        "kind": "exact",
        "token": "--cds-radius-full",
        "value": 9999,
        "unit": "px",
        "appliesTo": [
          "chip"
        ],
        "notes": "The radius token keeps the chip circular at its host-controlled size."
      }
    ],
    "layout": {
      "alignment": "The mark is centered inside the nonshrinking circular chip.",
      "flow": "One container and at most one visible mark.",
      "notes": [
        "Owning controls determine hit area, layout, focus and input semantics. The 32px visual is not a claim about the interactive target size."
      ]
    },
    "typographyAndColor": {
      "typography": [],
      "colors": [
        {
          "label": "Unselected container",
          "description": "Theme-specific empty selection fill.",
          "token": "--cds-selection-off-container"
        },
        {
          "label": "Selected container",
          "description": "Bold selection fill.",
          "token": "--cds-bg-bold"
        },
        {
          "label": "Selected mark",
          "description": "Check or dot foreground.",
          "token": "--cds-text-on-bold"
        }
      ]
    },
    "states": [
      {
        "id": "unselected",
        "label": "Unselected",
        "description": "Empty circular container; no check or dot is rendered."
      },
      {
        "id": "selected",
        "label": "Selected",
        "description": "Bold container and the requested check or dot."
      },
      {
        "id": "disabled",
        "label": "Disabled",
        "description": "Applies disabled opacity to either selected state. It does not block events because this helper owns no interaction."
      }
    ],
    "behavior": [
      {
        "label": "Pure visual state",
        "description": "selected and glyph are required. The helper has no event callbacks and keeps no selection state."
      },
      {
        "label": "Internal composition only",
        "description": "Public consumers should use Checkbox, Radio, RadioGroup or List.Item.Selection. Owning components may supply the private size hook and className."
      }
    ],
    "accessibility": [
      {
        "label": "Hidden decoration",
        "description": "The outer span is always aria-hidden=true. It provides no role, accessible name, focus stop or keyboard handling."
      },
      {
        "label": "Owner responsibilities",
        "description": "The public control must expose its checked and disabled states, accessible name, focus indicator and input behavior. Do not put this helper alone in a user flow."
      }
    ],
    "contentAdaptation": [
      {
        "label": "No text content",
        "description": "This helper does not render a label. Label and explanatory copy belong to its owning control."
      }
    ],
    "motionHaptics": {
      "motion": [
        {
          "label": "Current transition",
          "description": "The local stylesheet transitions background over a literal 0.15s with ease. It has no helper-level reduced-motion override; include this in motion review rather than claiming complete reduced-motion parity."
        }
      ],
      "haptics": [
        {
          "label": "None",
          "description": "The visual helper requests no haptic feedback. Owning controls may do so on valid input."
        }
      ]
    },
    "platformDifferences": [
      {
        "platforms": [
          "ios",
          "android"
        ],
        "description": "Native implementations and platform parity are not verified. Vue also has no local implementation.",
        "rationale": "This preview was authored from the local React types, implementation, styles and documentation. Native unit, typography, interaction and accessibility mappings require platform review."
      }
    ]
  },
  "specification_source": "packages/design-system/src/components/primitives/SelectionIndicator/SelectionIndicator.spec.json",
  "guidance": {
    "summary": "An internal, presentational selection mark shared by public Checkbox, Radio, RadioGroup and list selection rows. It is not a package-root export and must not be used as an interactive control.",
    "guidance": [
      {
        "heading": "Overview",
        "body": "The shared DS 4.5 selection chip — the round check/dot mark that `Checkbox`, `Radio`, and\n`RadioGroup` render. Presentational only (`aria-hidden`); it owns no interaction."
      },
      {
        "heading": "When to use",
        "body": "Effectively never from app code — this is a DS-internal building block and is not exported from\nthe package root. Reach for `Checkbox` (a `check` glyph) or `Radio` / `RadioGroup` (a `dot`), which\nwrap this chip with the correct role, keyboard, and accessibility semantics. It lives here only so\nthe three controls share one visual source of truth; render it directly only when authoring a new\nselection primitive inside the design system itself."
      }
    ],
    "usage": [],
    "examples": [],
    "source": "packages/design-system/src/components/primitives/SelectionIndicator/SelectionIndicator.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-selectionindicator",
    "json": "/data/visual/components/selectionindicator.json",
    "storybook": "/storybook/?path=/story/cloaked-design-system-primitives-selectionindicator--playground"
  }
}
