{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "base",
  "type": "registry:lib",
  "title": "Dualkit base",
  "description": "Tokens, component styles, icons and the direction helpers every Dualkit component shares.",
  "files": [
    {
      "path": "generated/tokens.css",
      "type": "registry:file",
      "target": "components/dualkit/tokens.css",
      "content": "/* Dualkit Starter tokens. Generated from tokens/dualkit.resolver.json by scripts/build.mjs. Do not edit by hand. */\n\n:root {\n  --dk-color-neutral-0: #ffffff;\n  --dk-color-neutral-50: #fafafa;\n  --dk-color-neutral-100: #f4f4f5;\n  --dk-color-neutral-200: #e4e4e7;\n  --dk-color-neutral-300: #d4d4d8;\n  --dk-color-neutral-400: #a1a1aa;\n  --dk-color-neutral-500: #71717a;\n  --dk-color-neutral-600: #52525b;\n  --dk-color-neutral-700: #3f3f46;\n  --dk-color-neutral-800: #27272a;\n  --dk-color-neutral-900: #18181b;\n  --dk-color-neutral-950: #09090b;\n  --dk-color-alpha-black-4: rgb(0 0 0 / 0.04);\n  --dk-color-alpha-black-8: rgb(0 0 0 / 0.08);\n  --dk-color-alpha-black-45: rgb(0 0 0 / 0.45);\n  --dk-color-alpha-black-60: rgb(0 0 0 / 0.6);\n  --dk-color-alpha-white-6: rgb(255 255 255 / 0.06);\n  --dk-color-alpha-white-12: rgb(255 255 255 / 0.12);\n  --dk-color-alpha-white-50: rgb(255 255 255 / 0.5);\n  --dk-color-alpha-white-70: rgb(255 255 255 / 0.7);\n  --dk-color-green-400: #4ade80;\n  --dk-color-green-600: #16a34a;\n  --dk-color-red-400: #f87171;\n  --dk-color-red-600: #dc2626;\n  --dk-space-0: 0px;\n  --dk-space-1: 4px;\n  --dk-space-2: 8px;\n  --dk-space-3: 12px;\n  --dk-space-4: 16px;\n  --dk-space-6: 24px;\n  --dk-space-8: 32px;\n  --dk-space-12: 48px;\n  --dk-space-16: 64px;\n  --dk-space-20: 80px;\n  --dk-radius-0: 0px;\n  --dk-radius-4: 4px;\n  --dk-radius-10: 10px;\n  --dk-radius-full: 9999px;\n  --dk-font-family-latin: 'Switzer', ui-sans-serif, system-ui, sans-serif;\n  --dk-font-family-arabic: 'IBM Plex Sans Arabic', 'Geeza Pro', 'Noto Sans Arabic', sans-serif;\n  --dk-font-family-mono: 'IBM Plex Mono', ui-monospace, 'Menlo', monospace;\n  --dk-font-size-13: 13px;\n  --dk-font-size-14: 14px;\n  --dk-font-size-15: 15px;\n  --dk-font-size-16: 16px;\n  --dk-font-size-18: 18px;\n  --dk-font-size-20: 20px;\n  --dk-font-size-22: 22px;\n  --dk-font-size-24: 24px;\n  --dk-font-size-32: 32px;\n  --dk-font-size-36: 36px;\n  --dk-font-size-48: 48px;\n  --dk-font-size-64: 64px;\n  --dk-font-size-72: 72px;\n  --dk-font-weight-regular: 400;\n  --dk-font-weight-medium: 500;\n  --dk-font-weight-semibold: 600;\n  --dk-font-line-height-110: 1.1;\n  --dk-font-line-height-120: 1.2;\n  --dk-font-line-height-130: 1.3;\n  --dk-font-line-height-140: 1.4;\n  --dk-font-line-height-155: 1.55;\n  --dk-font-line-height-170: 1.7;\n  --dk-font-tracking-tighter: -0.03em;\n  --dk-font-tracking-tight: -0.015em;\n  --dk-font-tracking-none: 0em;\n  --dk-color-surface-ground: var(--dk-color-neutral-50);\n  --dk-color-surface-raised: var(--dk-color-neutral-0);\n  --dk-color-surface-sunken: var(--dk-color-neutral-100);\n  --dk-color-surface-inverse: var(--dk-color-neutral-950);\n  --dk-color-surface-scrim: var(--dk-color-alpha-black-45);\n  --dk-color-text-primary: var(--dk-color-neutral-950);\n  --dk-color-text-secondary: var(--dk-color-alpha-black-60);\n  --dk-color-text-tertiary: var(--dk-color-alpha-black-45);\n  --dk-color-text-inverse: var(--dk-color-neutral-0);\n  --dk-color-border-subtle: var(--dk-color-alpha-black-8);\n  --dk-color-border-strong: var(--dk-color-neutral-300);\n  --dk-color-border-focus: var(--dk-color-neutral-950);\n  --dk-color-state-hover: var(--dk-color-alpha-black-4);\n  --dk-color-state-success: var(--dk-color-green-600);\n  --dk-color-state-danger: var(--dk-color-red-600);\n  --dk-space-inline-xs: var(--dk-space-1);\n  --dk-space-inline-sm: var(--dk-space-2);\n  --dk-space-inline-md: var(--dk-space-3);\n  --dk-space-inline-lg: var(--dk-space-4);\n  --dk-space-stack-xs: var(--dk-space-1);\n  --dk-space-stack-sm: var(--dk-space-2);\n  --dk-space-stack-md: var(--dk-space-4);\n  --dk-space-stack-lg: var(--dk-space-6);\n  --dk-space-stack-xl: var(--dk-space-12);\n  --dk-space-inset-control: var(--dk-space-4);\n  --dk-space-inset-surface: var(--dk-space-6);\n  --dk-radius-control: var(--dk-radius-full);\n  --dk-radius-media: var(--dk-radius-4);\n  --dk-radius-surface: var(--dk-radius-4);\n  --dk-radius-window: var(--dk-radius-10);\n  --dk-motion-duration-fast: 120ms;\n  --dk-motion-duration-base: 200ms;\n  --dk-motion-duration-slow: 400ms;\n  --dk-motion-easing-standard: cubic-bezier(0.2, 0, 0, 1);\n  --dk-motion-easing-out: cubic-bezier(0.16, 1, 0.3, 1);\n  --dk-type-display-family: var(--dk-font-family-latin);\n  --dk-type-display-size: var(--dk-font-size-64);\n  --dk-type-display-weight: var(--dk-font-weight-medium);\n  --dk-type-display-leading: var(--dk-font-line-height-110);\n  --dk-type-display-tracking: var(--dk-font-tracking-tighter);\n  --dk-type-heading-family: var(--dk-font-family-latin);\n  --dk-type-heading-size: var(--dk-font-size-32);\n  --dk-type-heading-weight: var(--dk-font-weight-medium);\n  --dk-type-heading-leading: var(--dk-font-line-height-120);\n  --dk-type-heading-tracking: var(--dk-font-tracking-tight);\n  --dk-type-title-family: var(--dk-font-family-latin);\n  --dk-type-title-size: var(--dk-font-size-20);\n  --dk-type-title-weight: var(--dk-font-weight-medium);\n  --dk-type-title-leading: var(--dk-font-line-height-130);\n  --dk-type-title-tracking: var(--dk-font-tracking-none);\n  --dk-type-body-family: var(--dk-font-family-latin);\n  --dk-type-body-size: var(--dk-font-size-15);\n  --dk-type-body-weight: var(--dk-font-weight-regular);\n  --dk-type-body-leading: var(--dk-font-line-height-155);\n  --dk-type-body-tracking: var(--dk-font-tracking-none);\n  --dk-type-label-family: var(--dk-font-family-latin);\n  --dk-type-label-size: var(--dk-font-size-14);\n  --dk-type-label-weight: var(--dk-font-weight-medium);\n  --dk-type-label-leading: var(--dk-font-line-height-140);\n  --dk-type-label-tracking: var(--dk-font-tracking-none);\n  --dk-type-caption-family: var(--dk-font-family-latin);\n  --dk-type-caption-size: var(--dk-font-size-13);\n  --dk-type-caption-weight: var(--dk-font-weight-regular);\n  --dk-type-caption-leading: var(--dk-font-line-height-140);\n  --dk-type-caption-tracking: var(--dk-font-tracking-none);\n}\n\n@media (prefers-color-scheme: dark) {\n  :root:not([data-theme=\"light\"]) {\n    --dk-color-surface-ground: var(--dk-color-neutral-950);\n    --dk-color-surface-raised: var(--dk-color-neutral-900);\n    --dk-color-surface-sunken: var(--dk-color-neutral-800);\n    --dk-color-surface-inverse: var(--dk-color-neutral-50);\n    --dk-color-surface-scrim: var(--dk-color-alpha-black-60);\n    --dk-color-text-primary: var(--dk-color-neutral-50);\n    --dk-color-text-secondary: var(--dk-color-alpha-white-70);\n    --dk-color-text-tertiary: var(--dk-color-alpha-white-50);\n    --dk-color-text-inverse: var(--dk-color-neutral-950);\n    --dk-color-border-subtle: var(--dk-color-alpha-white-12);\n    --dk-color-border-strong: var(--dk-color-neutral-700);\n    --dk-color-border-focus: var(--dk-color-neutral-50);\n    --dk-color-state-hover: var(--dk-color-alpha-white-6);\n    --dk-color-state-success: var(--dk-color-green-400);\n    --dk-color-state-danger: var(--dk-color-red-400);\n  }\n}\n\n:root[data-theme=\"dark\"] {\n  --dk-color-surface-ground: var(--dk-color-neutral-950);\n  --dk-color-surface-raised: var(--dk-color-neutral-900);\n  --dk-color-surface-sunken: var(--dk-color-neutral-800);\n  --dk-color-surface-inverse: var(--dk-color-neutral-50);\n  --dk-color-surface-scrim: var(--dk-color-alpha-black-60);\n  --dk-color-text-primary: var(--dk-color-neutral-50);\n  --dk-color-text-secondary: var(--dk-color-alpha-white-70);\n  --dk-color-text-tertiary: var(--dk-color-alpha-white-50);\n  --dk-color-text-inverse: var(--dk-color-neutral-950);\n  --dk-color-border-subtle: var(--dk-color-alpha-white-12);\n  --dk-color-border-strong: var(--dk-color-neutral-700);\n  --dk-color-border-focus: var(--dk-color-neutral-50);\n  --dk-color-state-hover: var(--dk-color-alpha-white-6);\n  --dk-color-state-success: var(--dk-color-green-400);\n  --dk-color-state-danger: var(--dk-color-red-400);\n}\n\n:lang(ar) {\n  --dk-type-display-family: var(--dk-font-family-arabic);\n  --dk-type-display-size: var(--dk-font-size-72);\n  --dk-type-display-weight: var(--dk-font-weight-medium);\n  --dk-type-display-leading: var(--dk-font-line-height-130);\n  --dk-type-display-tracking: var(--dk-font-tracking-none);\n  --dk-type-heading-family: var(--dk-font-family-arabic);\n  --dk-type-heading-size: var(--dk-font-size-36);\n  --dk-type-heading-weight: var(--dk-font-weight-medium);\n  --dk-type-heading-leading: var(--dk-font-line-height-140);\n  --dk-type-heading-tracking: var(--dk-font-tracking-none);\n  --dk-type-title-family: var(--dk-font-family-arabic);\n  --dk-type-title-size: var(--dk-font-size-22);\n  --dk-type-title-weight: var(--dk-font-weight-medium);\n  --dk-type-title-leading: var(--dk-font-line-height-155);\n  --dk-type-title-tracking: var(--dk-font-tracking-none);\n  --dk-type-body-family: var(--dk-font-family-arabic);\n  --dk-type-body-size: var(--dk-font-size-16);\n  --dk-type-body-weight: var(--dk-font-weight-regular);\n  --dk-type-body-leading: var(--dk-font-line-height-170);\n  --dk-type-body-tracking: var(--dk-font-tracking-none);\n  --dk-type-label-family: var(--dk-font-family-arabic);\n  --dk-type-label-size: var(--dk-font-size-14);\n  --dk-type-label-weight: var(--dk-font-weight-medium);\n  --dk-type-label-leading: var(--dk-font-line-height-155);\n  --dk-type-label-tracking: var(--dk-font-tracking-none);\n  --dk-type-caption-family: var(--dk-font-family-arabic);\n  --dk-type-caption-size: var(--dk-font-size-14);\n  --dk-type-caption-weight: var(--dk-font-weight-regular);\n  --dk-type-caption-leading: var(--dk-font-line-height-155);\n  --dk-type-caption-tracking: var(--dk-font-tracking-none);\n}\n\n:lang(ar) :not(:lang(ar)) {\n  --dk-type-display-family: var(--dk-font-family-latin);\n  --dk-type-display-size: var(--dk-font-size-64);\n  --dk-type-display-weight: var(--dk-font-weight-medium);\n  --dk-type-display-leading: var(--dk-font-line-height-110);\n  --dk-type-display-tracking: var(--dk-font-tracking-tighter);\n  --dk-type-heading-family: var(--dk-font-family-latin);\n  --dk-type-heading-size: var(--dk-font-size-32);\n  --dk-type-heading-weight: var(--dk-font-weight-medium);\n  --dk-type-heading-leading: var(--dk-font-line-height-120);\n  --dk-type-heading-tracking: var(--dk-font-tracking-tight);\n  --dk-type-title-family: var(--dk-font-family-latin);\n  --dk-type-title-size: var(--dk-font-size-20);\n  --dk-type-title-weight: var(--dk-font-weight-medium);\n  --dk-type-title-leading: var(--dk-font-line-height-130);\n  --dk-type-title-tracking: var(--dk-font-tracking-none);\n  --dk-type-body-family: var(--dk-font-family-latin);\n  --dk-type-body-size: var(--dk-font-size-15);\n  --dk-type-body-weight: var(--dk-font-weight-regular);\n  --dk-type-body-leading: var(--dk-font-line-height-155);\n  --dk-type-body-tracking: var(--dk-font-tracking-none);\n  --dk-type-label-family: var(--dk-font-family-latin);\n  --dk-type-label-size: var(--dk-font-size-14);\n  --dk-type-label-weight: var(--dk-font-weight-medium);\n  --dk-type-label-leading: var(--dk-font-line-height-140);\n  --dk-type-label-tracking: var(--dk-font-tracking-none);\n  --dk-type-caption-family: var(--dk-font-family-latin);\n  --dk-type-caption-size: var(--dk-font-size-13);\n  --dk-type-caption-weight: var(--dk-font-weight-regular);\n  --dk-type-caption-leading: var(--dk-font-line-height-140);\n  --dk-type-caption-tracking: var(--dk-font-tracking-none);\n}\n"
    },
    {
      "path": "components/styles.css",
      "type": "registry:file",
      "target": "components/dualkit/styles.css",
      "content": "/*\n * Dualkit Starter components. Load after @dualkit/starter/tokens.css.\n * Every value comes from a --dk- token; the few raw numbers are geometry from the Figma frames\n * (1px hairlines, the 2px focus gap and ring, 44x52 code boxes, 32px close button).\n * Logical properties throughout, so dir=\"rtl\" mirrors everything with no extra rules,\n * except the few things that move: directional icons and the sheet's slide, both on :dir(), which follows\n * the nearest dir attribute (an [dir=\"rtl\"] ancestor selector would also match an LTR block nested inside).\n */\n\n/* Type roles. :lang(ar) swaps the family, size, leading and tracking in tokens.css. */\n.dk-label { font-family: var(--dk-type-label-family); font-size: var(--dk-type-label-size); font-weight: var(--dk-type-label-weight); line-height: var(--dk-type-label-leading); letter-spacing: var(--dk-type-label-tracking); }\n.dk-body { font-family: var(--dk-type-body-family); font-size: var(--dk-type-body-size); font-weight: var(--dk-type-body-weight); line-height: var(--dk-type-body-leading); letter-spacing: var(--dk-type-body-tracking); }\n.dk-caption { margin: 0; font-family: var(--dk-type-caption-family); font-size: var(--dk-type-caption-size); font-weight: var(--dk-type-caption-weight); line-height: var(--dk-type-caption-leading); letter-spacing: var(--dk-type-caption-tracking); }\n.dk-title { margin: 0; font-family: var(--dk-type-title-family); font-size: var(--dk-type-title-size); font-weight: var(--dk-type-title-weight); line-height: var(--dk-type-title-leading); letter-spacing: var(--dk-type-title-tracking); }\n.dk-mono { font-family: var(--dk-font-family-mono); font-size: var(--dk-font-size-14); font-weight: var(--dk-font-weight-regular); line-height: var(--dk-font-line-height-140); }\n.dk-secondary { color: var(--dk-color-text-secondary); }\n.dk-tertiary { color: var(--dk-color-text-tertiary); }\n.dk-danger { color: var(--dk-color-state-danger); }\n\n.dk-icon { flex: none; display: block; }\n.dk-icon--directional:dir(rtl) { transform: scaleX(-1); }\n\n/* Button: a pill. The focus ring is offset: a ground-coloured gap, then the ink ring, zero blur. */\n.dk-button {\n  display: inline-flex; align-items: center; gap: var(--dk-space-inline-sm);\n  padding-block: var(--dk-space-inline-md); padding-inline: var(--dk-space-stack-lg);\n  border: 0; border-radius: var(--dk-radius-control); cursor: pointer;\n  font-family: var(--dk-type-label-family); font-size: var(--dk-type-label-size); font-weight: var(--dk-type-label-weight); line-height: var(--dk-type-label-leading); letter-spacing: var(--dk-type-label-tracking);\n  transition: background-color var(--dk-motion-duration-fast) var(--dk-motion-easing-standard), scale var(--dk-motion-duration-base) var(--dk-motion-easing-out);\n}\n.dk-button--primary { background: var(--dk-color-surface-inverse); color: var(--dk-color-text-inverse); }\n.dk-button--secondary { background: var(--dk-color-surface-raised); color: var(--dk-color-text-primary); box-shadow: inset 0 0 0 1px var(--dk-color-border-subtle); }\n@media (hover: hover) { .dk-button--secondary:hover:not(:disabled) { background-image: linear-gradient(var(--dk-color-state-hover), var(--dk-color-state-hover)); } }\n.dk-button:active:not(:disabled) { scale: 0.97; }\n.dk-button:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--dk-color-surface-ground), 0 0 0 4px var(--dk-color-border-focus); }\n.dk-button--secondary:focus-visible { box-shadow: inset 0 0 0 1px var(--dk-color-border-subtle), 0 0 0 2px var(--dk-color-surface-ground), 0 0 0 4px var(--dk-color-border-focus); }\n.dk-button:disabled { opacity: 0.4; cursor: not-allowed; }\n\n/* Field */\n.dk-field { display: flex; flex-direction: column; align-items: stretch; gap: var(--dk-space-stack-sm); color: var(--dk-color-text-primary); }\n.dk-field__input {\n  inline-size: 100%; box-sizing: border-box; margin: 0; border: 0; border-radius: var(--dk-radius-surface);\n  padding-block: var(--dk-space-inline-md); padding-inline: var(--dk-space-inline-lg);\n  background: var(--dk-color-surface-raised); color: var(--dk-color-text-primary); box-shadow: inset 0 0 0 1px var(--dk-color-border-subtle);\n  font-family: var(--dk-type-body-family); font-size: max(16px, var(--dk-type-body-size)); line-height: var(--dk-type-body-leading);\n}\n/* A left-to-right value, such as an email, keeps Latin type inside an Arabic form. */\n.dk-field__input:dir(ltr) { font-family: var(--dk-font-family-latin); }\n.dk-field__input::placeholder { color: var(--dk-color-text-tertiary); }\n.dk-field__input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--dk-color-border-focus); }\n.dk-field--error .dk-field__input { box-shadow: inset 0 0 0 1px var(--dk-color-state-danger); }\n.dk-field--error .dk-field__input:focus-visible { box-shadow: inset 0 0 0 2px var(--dk-color-state-danger); }\n\n/* Digit input: 44 by 52 boxes, always left to right. */\n.dk-digits { display: flex; flex-direction: column; align-items: flex-start; gap: var(--dk-space-stack-sm); color: var(--dk-color-text-primary); }\n.dk-digits__boxes { display: flex; gap: var(--dk-space-inline-sm); }\n.dk-digits__box {\n  inline-size: 44px; block-size: 52px; box-sizing: border-box; padding: 0; margin: 0; border: 0; text-align: center;\n  border-radius: var(--dk-radius-surface); background: var(--dk-color-surface-raised); color: var(--dk-color-text-primary);\n  box-shadow: inset 0 0 0 1px var(--dk-color-border-subtle); caret-color: var(--dk-color-text-primary);\n  font-family: var(--dk-font-family-mono); font-size: var(--dk-font-size-24); font-weight: var(--dk-font-weight-regular); line-height: var(--dk-font-line-height-120);\n}\n/* Plex Mono has no Arabic-Indic digits, so Arabic codes use the Arabic title style. */\n.dk-digits--arab .dk-digits__box { font-family: var(--dk-type-title-family); font-size: var(--dk-type-title-size); font-weight: var(--dk-type-title-weight); line-height: var(--dk-type-title-leading); }\n.dk-digits__box:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--dk-color-border-focus); }\n.dk-digits--error .dk-digits__box { box-shadow: inset 0 0 0 1px var(--dk-color-state-danger); }\n\n/* Amount */\n.dk-amount { display: flex; flex-direction: column; align-items: flex-start; gap: var(--dk-space-stack-xs); color: var(--dk-color-text-primary); }\n.dk-amount__figure { font-family: var(--dk-type-heading-family); font-size: var(--dk-type-heading-size); font-weight: var(--dk-type-heading-weight); line-height: var(--dk-type-heading-leading); letter-spacing: var(--dk-type-heading-tracking); font-variant-numeric: tabular-nums; }\n\n/* Date */\n.dk-date { display: flex; flex-direction: column; align-items: stretch; gap: var(--dk-space-stack-sm); color: var(--dk-color-text-primary); }\n.dk-date__box {\n  display: flex; align-items: center; gap: var(--dk-space-inline-md);\n  padding-block: var(--dk-space-inline-md); padding-inline: var(--dk-space-inline-lg);\n  border-radius: var(--dk-radius-surface); background: var(--dk-color-surface-raised); box-shadow: inset 0 0 0 1px var(--dk-color-border-subtle);\n}\n.dk-date__lines { display: flex; flex-direction: column; align-items: flex-start; flex: 1; min-inline-size: 0; }\n.dk-date__line { display: block; }\n\n/* Tabs: the indicator sits under the active tab, the rule runs under the row. */\n.dk-tabs { color: var(--dk-color-text-primary); }\n.dk-tabs__list { display: flex; gap: var(--dk-space-inline-xs); box-shadow: inset 0 -1px 0 var(--dk-color-border-subtle); }\n.dk-tabs__tab {\n  position: relative; margin: 0; border: 0; background: none; cursor: pointer; color: var(--dk-color-text-secondary);\n  padding-block: var(--dk-space-inline-md); padding-inline: var(--dk-space-inline-lg);\n  font-family: var(--dk-type-label-family); font-size: var(--dk-type-label-size); font-weight: var(--dk-type-label-weight); line-height: var(--dk-type-label-leading); letter-spacing: var(--dk-type-label-tracking);\n  transition: color var(--dk-motion-duration-fast) var(--dk-motion-easing-standard);\n}\n.dk-tabs__tab::after { content: ''; position: absolute; inset-inline: 0; inset-block-end: 0; block-size: 2px; background: var(--dk-color-border-focus); scale: 0 1; transition: scale var(--dk-motion-duration-base) var(--dk-motion-easing-out); }\n.dk-tabs__tab[aria-selected=\"true\"] { color: var(--dk-color-text-primary); }\n.dk-tabs__tab[aria-selected=\"true\"]::after { scale: 1 1; }\n@media (hover: hover) { .dk-tabs__tab:hover { color: var(--dk-color-text-primary); } }\n.dk-tabs__tab:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--dk-color-border-focus); border-radius: var(--dk-radius-surface); }\n.dk-tabs__panel:focus-visible { outline: 2px solid var(--dk-color-border-focus); outline-offset: 2px; }\n\n/* Sheet: comes in from the inline end. */\n.dk-sheet { position: fixed; inset: 0; z-index: 50; }\n.dk-sheet__scrim { position: absolute; inset: 0; background: var(--dk-color-surface-scrim); animation: dk-fade var(--dk-motion-duration-base) var(--dk-motion-easing-standard); }\n.dk-sheet__panel {\n  position: absolute; inset-block: var(--dk-space-stack-md); inset-inline-end: var(--dk-space-stack-md);\n  display: flex; flex-direction: column; inline-size: min(400px, calc(100% - 2 * var(--dk-space-stack-md))); max-block-size: calc(100% - 2 * var(--dk-space-stack-md)); block-size: fit-content;\n  border-radius: var(--dk-radius-surface); background: var(--dk-color-surface-raised); color: var(--dk-color-text-primary);\n  box-shadow: inset 0 0 0 1px var(--dk-color-border-subtle); overflow: hidden; touch-action: pan-y;\n  --dk-sheet-from: 24px;\n  animation: dk-sheet-in var(--dk-motion-duration-slow) var(--dk-motion-easing-out);\n  transition: translate var(--dk-motion-duration-base) var(--dk-motion-easing-out);\n}\n.dk-sheet__panel:dir(rtl) { --dk-sheet-from: -24px; }\n.dk-sheet__header { display: flex; align-items: center; justify-content: space-between; gap: var(--dk-space-inline-md); padding-block: var(--dk-space-stack-md); padding-inline: var(--dk-space-inset-surface); box-shadow: inset 0 -1px 0 var(--dk-color-border-subtle); }\n.dk-sheet__close {\n  display: grid; place-items: center; flex: none; inline-size: 32px; block-size: 32px; padding: 0; border: 0; cursor: pointer;\n  border-radius: var(--dk-radius-control); background: none; color: var(--dk-color-text-secondary); box-shadow: inset 0 0 0 1px var(--dk-color-border-subtle);\n}\n@media (hover: hover) { .dk-sheet__close:hover { background: var(--dk-color-state-hover); } }\n.dk-sheet__close:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--dk-color-surface-ground), 0 0 0 4px var(--dk-color-border-focus); }\n.dk-sheet__body { display: flex; flex-direction: column; gap: var(--dk-space-stack-md); padding: var(--dk-space-inset-surface); overflow-y: auto; }\n.dk-sheet__row { display: flex; align-items: center; justify-content: space-between; gap: var(--dk-space-inline-lg); }\n.dk-sheet__footer { display: flex; justify-content: flex-end; gap: var(--dk-space-inline-sm); padding-block: var(--dk-space-stack-md); padding-inline: var(--dk-space-inset-surface); box-shadow: inset 0 1px 0 var(--dk-color-border-subtle); }\n\n/* Toast */\n.dk-toast-region { position: fixed; z-index: 60; inset-block-end: var(--dk-space-stack-md); inset-inline-end: var(--dk-space-stack-md); display: flex; flex-direction: column; align-items: flex-end; gap: var(--dk-space-stack-sm); inline-size: min(400px, calc(100% - 2 * var(--dk-space-stack-md))); }\n.dk-toast {\n  display: flex; align-items: center; gap: var(--dk-space-inline-md); box-sizing: border-box; inline-size: min(400px, 100%);\n  padding-block: var(--dk-space-inline-md); padding-inline: var(--dk-space-inline-lg);\n  border-radius: var(--dk-radius-surface); background: var(--dk-color-surface-inverse); color: var(--dk-color-text-inverse);\n  touch-action: pan-y; transition: translate var(--dk-motion-duration-base) var(--dk-motion-easing-out);\n  animation: dk-toast-in var(--dk-motion-duration-base) var(--dk-motion-easing-out);\n}\n.dk-toast__message { flex: 1; min-inline-size: 0; margin: 0; }\n.dk-toast__action { flex: none; margin: 0; padding: 0; border: 0; background: none; color: inherit; cursor: pointer; border-radius: var(--dk-radius-media); }\n.dk-toast__action:focus-visible { outline: 2px solid var(--dk-color-text-inverse); outline-offset: 2px; }\n\n.dk-is-dragging { transition: none; }\n\n@keyframes dk-fade { from { opacity: 0; } }\n@keyframes dk-sheet-in { from { opacity: 0; translate: var(--dk-sheet-from) 0; } }\n@keyframes dk-toast-in { from { opacity: 0; translate: 0 8px; } }\n\n@media (prefers-reduced-motion: reduce) {\n  .dk-button, .dk-tabs__tab, .dk-tabs__tab::after, .dk-sheet__panel, .dk-toast { transition: none; }\n  .dk-sheet__scrim, .dk-sheet__panel, .dk-toast { animation-duration: 1ms; }\n  .dk-button:active:not(:disabled) { scale: none; }\n}\n"
    },
    {
      "path": "components/direction.ts",
      "type": "registry:lib",
      "target": "components/dualkit/direction.ts",
      "content": "// The reading direction of an element, read when it is needed (on a key press or a drag), never during render.\nexport type Direction = 'ltr' | 'rtl'\n\nexport function directionOf(el: Element | null): Direction {\n  const attr = el?.closest('[dir]')?.getAttribute('dir')\n  if (attr === 'rtl' || attr === 'ltr') return attr\n  if (el && typeof getComputedStyle === 'function') return getComputedStyle(el).direction === 'rtl' ? 'rtl' : 'ltr'\n  return 'ltr'\n}\n\n/** +1 when the inline end is to the right, -1 when it is to the left. */\nexport const inlineSign = (el: Element | null): 1 | -1 => (directionOf(el) === 'rtl' ? -1 : 1)\n\nexport const cx = (...names: Array<string | false | null | undefined>) => names.filter(Boolean).join(' ')\n"
    },
    {
      "path": "components/icons.tsx",
      "type": "registry:ui",
      "target": "components/dualkit/icons.tsx",
      "content": "// 16px icons, 1.5 stroke, coloured by currentColor. Directional ones carry a class that CSS flips in right to left.\nconst PATHS = {\n  forward: 'M3 8h10M9.5 4.5L13 8l-3.5 3.5',\n  back: 'M13 8H3M7.5 3.5L3 8l4.5 4.5',\n  close: 'M4.5 4.5l7 7M11.5 4.5l-7 7',\n  check: 'M3.5 8.5l3 3 6-7',\n  calendar: 'M3 4h10v9H3zM3 6.75h10M5.75 2.5v3M10.25 2.5v3',\n  alert: 'M8 5v3.5M8 10.75v.25M14 8A6 6 0 1 1 2 8a6 6 0 0 1 12 0z',\n  info: 'M8 7.25v4M8 5v.25M14 8A6 6 0 1 1 2 8a6 6 0 0 1 12 0z',\n} as const\n\nexport type IconName = keyof typeof PATHS\nconst DIRECTIONAL: ReadonlySet<IconName> = new Set(['forward', 'back'])\n\nexport function Icon({ name }: { name: IconName }) {\n  return (\n    <svg className={DIRECTIONAL.has(name) ? 'dk-icon dk-icon--directional' : 'dk-icon'} width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\">\n      <path d={PATHS[name]} stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n    </svg>\n  )\n}\n"
    },
    {
      "path": "components/useSwipeDismiss.ts",
      "type": "registry:hook",
      "target": "components/dualkit/useSwipeDismiss.ts",
      "content": "import { useRef, useState, type PointerEvent } from 'react'\nimport { inlineSign } from './direction'\n\nconst THRESHOLD = 64\n\n/**\n * Drag towards the inline end to dismiss: right in English, left in Arabic.\n * The direction is read when the drag starts, so it follows the element's own dir.\n */\nexport function useSwipeDismiss(onDismiss: (() => void) | undefined) {\n  const start = useRef<{ x: number; sign: 1 | -1; id: number } | null>(null)\n  const [offset, setOffset] = useState(0)\n\n  const distance = (e: PointerEvent) => (start.current ? (e.clientX - start.current.x) * start.current.sign : 0)\n\n  const handlers = {\n    onPointerDown(e: PointerEvent<HTMLElement>) {\n      if (!onDismiss || e.button !== 0) return\n      if ((e.target as Element).closest('button, a, input, textarea, select')) return\n      start.current = { x: e.clientX, sign: inlineSign(e.currentTarget), id: e.pointerId }\n      e.currentTarget.setPointerCapture?.(e.pointerId)\n    },\n    onPointerMove(e: PointerEvent<HTMLElement>) {\n      if (!start.current || e.pointerId !== start.current.id) return\n      // Only the dismissing way moves freely; the other way is held at zero.\n      setOffset(Math.max(0, distance(e)) * start.current.sign)\n    },\n    onPointerUp(e: PointerEvent<HTMLElement>) {\n      if (!start.current || e.pointerId !== start.current.id) return\n      const travelled = distance(e)\n      start.current = null\n      setOffset(0)\n      if (travelled > THRESHOLD) onDismiss?.()\n    },\n    onPointerCancel() {\n      start.current = null\n      setOffset(0)\n    },\n  }\n\n  return { handlers, offset, dragging: offset !== 0 }\n}\n"
    }
  ],
  "docs": "Import components/dualkit/tokens.css, then components/dualkit/styles.css, once in your root layout. Set lang and dir on <html>: lang=\"ar\" dir=\"rtl\" switches to Arabic type and mirrors the layout."
}
