{
  "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": "timeline",
  "name": "Timeline",
  "category": "Status",
  "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-status-timeline--playground",
        "name": "Playground",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "Playground",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--playground&viewMode=story"
      },
      {
        "id": "cloaked-design-system-status-timeline--default",
        "name": "Default",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "Default",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--default&viewMode=story"
      },
      {
        "id": "cloaked-design-system-status-timeline--complete",
        "name": "Complete",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "Complete",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--complete&viewMode=story"
      },
      {
        "id": "cloaked-design-system-status-timeline--with-icons",
        "name": "With Icons",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "WithIcons",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--with-icons&viewMode=story"
      },
      {
        "id": "cloaked-design-system-status-timeline--compact",
        "name": "Compact",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "Compact",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--compact&viewMode=story"
      },
      {
        "id": "cloaked-design-system-status-timeline--horizontal",
        "name": "Horizontal",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "Horizontal",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--horizontal&viewMode=story"
      },
      {
        "id": "cloaked-design-system-status-timeline--single-item",
        "name": "Single Item",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "SingleItem",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--single-item&viewMode=story"
      },
      {
        "id": "cloaked-design-system-status-timeline--long-text",
        "name": "Long Text",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "LongText",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--long-text&viewMode=story"
      },
      {
        "id": "cloaked-design-system-status-timeline--horizontal-overflow",
        "name": "Horizontal Overflow",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "HorizontalOverflow",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--horizontal-overflow&viewMode=story"
      },
      {
        "id": "cloaked-design-system-status-timeline--dark-theme",
        "name": "Dark Theme",
        "title": "Cloaked Design System/Status/Timeline",
        "exportName": "DarkTheme",
        "source_path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
        "source_digest": "09ec99f41d31a0d078b473bff7e8a36d03ec2915d8e9c5d182a3ce449395d974",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-status-timeline--dark-theme&viewMode=story"
      }
    ],
    "name": "Timeline",
    "id": "timeline",
    "category": "Status"
  },
  "stories_source": {
    "path": "packages/design-system/src/components/status/Timeline/Timeline.stories.tsx",
    "code": "import React from 'react';\nimport type { Meta, StoryObj } from '@storybook/react-vite';\nimport { Icon } from '../../primitives/Icon/Icon';\nimport { disabledControl, selectArgType } from '../../../storybook/controlOptions';\nimport { Timeline, type TimelineItem, type TimelineOrientation } from './Timeline';\n\nconst TIMELINE_ORIENTATIONS = ['vertical', 'horizontal'] as const satisfies readonly TimelineOrientation[];\n\nconst ITEMS: TimelineItem[] = [\n    {\n        id: 'scan',\n        title: 'Scan complete',\n        description: '147 brokers checked across public records and people-search sites.',\n        state: 'complete',\n        timestamp: 'Today',\n    },\n    {\n        id: 'requests',\n        title: 'Removal requests sent',\n        description: '23 broker opt-outs are in progress.',\n        state: 'active',\n        timestamp: 'Now',\n    },\n    {\n        id: 'verification',\n        title: 'Verification scan',\n        description: 'Confirm removed records and catch relisted profiles.',\n        state: 'upcoming',\n        timestamp: 'Next',\n    },\n    {\n        id: 'report',\n        title: 'Report ready',\n        description: 'Review the final summary and remaining recommendations.',\n        state: 'upcoming',\n    },\n];\n\nconst meta: Meta<typeof Timeline> = {\n    title: 'Cloaked Design System/Status/Timeline',\n    component: Timeline,\n    parameters: {\n        a11y: { test: 'error' },\n        docs: {\n            description: {\n                component:\n                    'Ordered sequence of events, each with its own title, optional description, and timestamp, ' +\n                    'connected by a line and driven by a per-item `state` (complete / active / upcoming). Use it ' +\n                    'when the stages themselves carry content — a removal journey, an activity log. Reach for ' +\n                    '`Progress.Steps` instead when you only need to show position in a short flow (step 2 of 4) ' +\n                    'with no event detail. Renders as an ordered list; set `ariaLabel` to name the sequence.',\n            },\n        },\n    },\n    args: {\n        ariaLabel: 'Removal timeline',\n    },\n    argTypes: {\n        orientation: {\n            ...selectArgType(TIMELINE_ORIENTATIONS),\n            description: 'Layout direction; `horizontal` scrolls when events overflow the width.',\n        },\n        items: { ...disabledControl, description: 'Ordered `TimelineItem[]`, each with its own `state`.' },\n        ariaLabel: { control: 'text', description: 'Accessible name for the ordered timeline.' },\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 Timeline>;\n\nexport const Playground: Story = {\n    args: {\n        items: ITEMS,\n    },\n};\n\nexport const Default: Story = {\n    args: {\n        items: ITEMS,\n    },\n};\n\nexport const Complete: Story = {\n    parameters: {\n        docs: { description: { story: 'All events at `state: \"complete\"` — the finished-journey end state.' } },\n    },\n    args: {\n        items: ITEMS.map(item => ({ ...item, state: 'complete' as const })),\n        ariaLabel: 'Completed removal timeline',\n    },\n};\n\nexport const WithIcons: Story = {\n    parameters: {\n        docs: { description: { story: 'Custom `icon` on the active event; complete events always show a check.' } },\n    },\n    args: {\n        items: ITEMS.map(item =>\n            item.state === 'active' ? { ...item, icon: <Icon name='clock' size='small' /> } : item\n        ),\n    },\n};\n\nexport const Compact: Story = {\n    parameters: {\n        docs: { description: { story: 'Titles only (no description or timestamp) for dense layouts.' } },\n    },\n    args: {\n        items: ITEMS.map(({ id, title, state }) => ({ id, title, state })),\n        ariaLabel: 'Compact timeline',\n    },\n};\n\nexport const Horizontal: Story = {\n    parameters: {\n        docs: { description: { story: '`orientation=\"horizontal\"` for a stepper laid out left-to-right.' } },\n    },\n    args: {\n        items: ITEMS.map(({ id, title, state }) => ({ id, title, state })),\n        orientation: 'horizontal',\n        ariaLabel: 'Horizontal setup timeline',\n    },\n};\n\nexport const SingleItem: Story = {\n    parameters: {\n        docs: { description: { story: 'Single event — the connector line is omitted for the last item.' } },\n    },\n    args: {\n        items: ITEMS.slice(0, 1),\n        ariaLabel: 'Single timeline item',\n    },\n};\n\nexport const LongText: Story = {\n    parameters: {\n        docs: { description: { story: 'Long title and description to check wrapping in the vertical layout.' } },\n    },\n    args: {\n        items: [\n            {\n                id: 'long',\n                title: 'A longer timeline milestone title that wraps on small screens',\n                description:\n                    'Timeline descriptions can include enough context to explain what happened without breaking the mobile layout.',\n                state: 'active',\n                timestamp: 'Today',\n            },\n            ...ITEMS.slice(2),\n        ],\n        ariaLabel: 'Timeline with long text',\n    },\n};\n\nexport const HorizontalOverflow: Story = {\n    parameters: {\n        docs: { description: { story: 'Horizontal timeline with enough events to trigger horizontal scrolling.' } },\n    },\n    args: {\n        items: [...ITEMS, { id: 'follow-up', title: 'Follow-up scan', state: 'upcoming' }],\n        orientation: 'horizontal',\n        ariaLabel: 'Horizontal overflow timeline',\n    },\n};\n\nexport const DarkTheme: Story = {\n    parameters: {\n        docs: { description: { story: 'Vertical timeline rendered against the dark theme surface.' } },\n    },\n    args: {\n        items: ITEMS,\n        ariaLabel: 'Removal timeline',\n    },\n    globals: { theme: 'dark' },\n};\n"
  },
  "specification": {
    "$schema": "../../../specs/component-spec.schema.json",
    "identity": {
      "name": "Timeline",
      "status": "preview",
      "version": "1.0.0",
      "summary": "An ordered sequence of events with per-item state, connectors, titles, timestamps, and vertical or horizontal flow."
    },
    "parts": [
      {
        "id": "root",
        "label": "Root",
        "description": "Ordered list that flows events vertically or horizontally.",
        "required": true
      },
      {
        "id": "item",
        "label": "Item",
        "description": "One event row pairing a marker column with content."
      },
      {
        "id": "node",
        "label": "Node",
        "description": "State marker showing a check, custom icon, or active dot."
      },
      {
        "id": "connector",
        "label": "Connector",
        "description": "Line joining adjacent events."
      },
      {
        "id": "content",
        "label": "Content",
        "description": "Title, timestamp, and optional description."
      }
    ],
    "allowedDesignChoices": {
      "variants": {
        "events": {
          "label": "Events",
          "description": "The single ordered-event treatment."
        }
      },
      "sizes": {},
      "orientations": {
        "vertical": {
          "label": "Vertical",
          "description": "Events stack top to bottom."
        },
        "horizontal": {
          "label": "Horizontal",
          "description": "Events flow left to right and scroll on overflow."
        }
      }
    },
    "variants": [
      {
        "id": "events",
        "label": "Events",
        "description": "Ordered event sequence with connectors.",
        "platforms": [
          "ios",
          "android",
          "web"
        ]
      }
    ],
    "sizes": [],
    "measurements": [
      {
        "id": "item-gap",
        "label": "Marker and content gap",
        "kind": "exact",
        "token": "--cds-space-12",
        "value": 12,
        "unit": "px",
        "appliesTo": [
          "item"
        ]
      },
      {
        "id": "node-size",
        "label": "Node size",
        "kind": "exact",
        "token": "--cds-size-24",
        "value": 24,
        "unit": "px",
        "appliesTo": [
          "node"
        ]
      },
      {
        "id": "content-inset",
        "label": "Content bottom inset",
        "kind": "exact",
        "token": "--cds-space-20",
        "value": 20,
        "unit": "px",
        "appliesTo": [
          "content"
        ]
      }
    ],
    "layout": {
      "alignment": "The marker column aligns with the top of each event's content.",
      "flow": "Vertical stacks a node-plus-content grid per event; horizontal lays events in a scrolling row.",
      "notes": [
        "Use Progress.Steps when you only need position in a short flow without event detail."
      ]
    },
    "typographyAndColor": {
      "typography": [
        {
          "label": "Title",
          "description": "Uses the body ramp (body-small when horizontal).",
          "token": "--cds-type-body-size"
        },
        {
          "label": "Timestamp and description",
          "description": "Use the body-small ramp.",
          "token": "--cds-type-body-small-size"
        }
      ],
      "colors": [
        {
          "label": "Complete",
          "description": "Complete nodes and connectors use the brand accent.",
          "token": "--cds-brand"
        },
        {
          "label": "Active",
          "description": "Active nodes use the subtle brand wash.",
          "token": "--cds-brand-subtle"
        },
        {
          "label": "Upcoming",
          "description": "Upcoming nodes outline with the divider color.",
          "token": "--cds-divider"
        }
      ]
    },
    "states": [
      {
        "id": "complete",
        "label": "Complete",
        "description": "Finished event with a filled node and check."
      },
      {
        "id": "active",
        "label": "Active",
        "description": "Current event, marked aria-current=step."
      },
      {
        "id": "upcoming",
        "label": "Upcoming",
        "description": "Future event with an outlined node."
      }
    ],
    "behavior": [
      {
        "label": "Per-item state",
        "description": "Each event declares complete, active, or upcoming; the active event is aria-current."
      },
      {
        "label": "Connectors",
        "description": "A connector joins each event to the next; the last event omits it."
      }
    ],
    "accessibility": [
      {
        "label": "Ordered list",
        "description": "Renders as an ordered list; set ariaLabel to name the sequence."
      },
      {
        "label": "Current step",
        "description": "The active event exposes aria-current=step."
      }
    ],
    "contentAdaptation": [
      {
        "label": "Optional detail",
        "description": "Description and timestamp render only when provided."
      },
      {
        "label": "Horizontal overflow",
        "description": "The horizontal layout scrolls when events exceed the width."
      }
    ],
    "motionHaptics": {
      "motion": [
        {
          "label": "Static",
          "description": "Timeline does not animate state transitions."
        }
      ],
      "haptics": [
        {
          "label": "No feedback",
          "description": "Timeline is non-interactive and requests no haptics."
        }
      ]
    },
    "platformDifferences": []
  },
  "specification_source": "packages/design-system/src/components/status/Timeline/Timeline.spec.json",
  "guidance": {
    "summary": "An ordered sequence of events with per-item state, connectors, titles, timestamps, and vertical or horizontal flow.",
    "guidance": [
      {
        "heading": "Overview",
        "body": "An ordered sequence of events or steps over time, connected by a line and driven by a per-item\n`state` (complete / active / upcoming)."
      },
      {
        "heading": "When to use",
        "body": "Reach for `Timeline` when the stages themselves carry content — a removal journey, an activity log,\na multi-day process — and each event has a title, optional description, and timestamp worth showing.\n\n-   Only showing position in a short flow (\"step 2 of 4\") with no per-event detail? Use\n    `Progress.Steps`, the active stepper.\n-   An unordered set of rows with no temporal sequence or connector line? Use `List`."
      }
    ],
    "usage": [],
    "examples": [],
    "source": "packages/design-system/src/components/status/Timeline/Timeline.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-timeline",
    "json": "/data/visual/components/timeline.json",
    "storybook": "/storybook/?path=/story/cloaked-design-system-status-timeline--playground"
  }
}
