{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"sheet","title":"바텀 시트","type":"registry:ui","registryDependencies":["https://0.0.0.0:3000/r/0.1.0/foundations.json"],"cssVars":{"theme":{"shadow-sm":"var(--surface-shadow-sm)","shadow-md":"var(--surface-shadow-md)","shadow-lg":"var(--surface-shadow-lg)","font-heading":"\"Pretendard Variable\", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif","font-sans":"\"Pretendard Variable\", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif","font-mono":"\"SFMono-Regular\", Consolas, \"Liberation Mono\", Menlo, monospace","color-sidebar-ring":"var(--sidebar-ring)","color-sidebar-border":"var(--sidebar-border)","color-sidebar-accent-foreground":"var(--sidebar-accent-foreground)","color-sidebar-accent":"var(--sidebar-accent)","color-sidebar-primary-foreground":"var(--sidebar-primary-foreground)","color-sidebar-primary":"var(--sidebar-primary)","color-sidebar-foreground":"var(--sidebar-foreground)","color-sidebar":"var(--sidebar)","color-chart-5":"var(--chart-5)","color-chart-4":"var(--chart-4)","color-chart-3":"var(--chart-3)","color-chart-2":"var(--chart-2)","color-chart-1":"var(--chart-1)","color-ring":"var(--ring)","color-input":"var(--input)","color-border":"var(--border)","color-destructive":"var(--destructive)","color-accent-foreground":"var(--accent-foreground)","color-accent":"var(--accent)","color-muted-foreground":"var(--muted-foreground)","color-muted":"var(--muted)","color-secondary-foreground":"var(--secondary-foreground)","color-secondary":"var(--secondary)","color-primary-foreground":"var(--primary-foreground)","color-primary":"var(--primary)","color-primary-hover":"var(--primary-hover)","color-popover-foreground":"var(--popover-foreground)","color-popover":"var(--popover)","color-card-foreground":"var(--card-foreground)","color-card":"var(--card)","color-foreground":"var(--foreground)","color-background":"var(--background)","color-gallery-background":"var(--gallery-background)","radius-sm":"calc(var(--radius) * 0.15)","radius-md":"calc(var(--radius) * 0.2)","radius-lg":"calc(var(--radius) * 0.25)","radius-xl":"calc(var(--radius) * 0.35)","radius-2xl":"calc(var(--radius) * 0.45)","radius-3xl":"calc(var(--radius) * 0.55)","radius-4xl":"calc(var(--radius) * 0.65)","radius-5xl":"calc(var(--radius) * 0.8)","radius-6xl":"var(--radius)","radius-container":"min(var(--radius), max(0px, calc(var(--nested-radius, var(--radius)) + var(--nested-gap, 0px))))"},"light":{"corner-shape":"squircle","surface-shadow-sm":"0 1px 3px 0 rgb(0 0 0 / 10%), 0 1px 2px -1px rgb(0 0 0 / 10%)","surface-shadow-md":"0 4px 6px -1px rgb(0 0 0 / 10%), 0 2px 4px -2px rgb(0 0 0 / 10%)","surface-shadow-lg":"0 10px 15px -3px rgb(0 0 0 / 10%), 0 4px 6px -4px rgb(0 0 0 / 10%)","background":"#ffffff","gallery-background":"#f7f7f7","gallery-preview-background":"oklch(1 0 0)","foreground":"oklch(0.145 0 0)","card":"oklch(1 0 0)","card-foreground":"oklch(0.145 0 0)","popover":"oklch(1 0 0)","popover-foreground":"oklch(0.145 0 0)","primary":"#007AFF","primary-hover":"color-mix(in oklch, var(--primary), black 12%)","primary-foreground":"#ffffff","secondary":"oklch(0.97 0 0)","secondary-foreground":"oklch(0.205 0 0)","muted":"oklch(0.97 0 0)","muted-foreground":"oklch(0.556 0 0)","accent":"#007AFF","accent-foreground":"#ffffff","destructive":"oklch(0.577 0.245 27.325)","border":"oklch(0.922 0 0)","input":"oklch(0.922 0 0)","ring":"oklch(0.708 0 0)","chart-1":"oklch(0.87 0 0)","chart-2":"oklch(0.556 0 0)","chart-3":"oklch(0.439 0 0)","chart-4":"oklch(0.371 0 0)","chart-5":"oklch(0.269 0 0)","radius":"2.5rem","sidebar":"oklch(0.985 0 0)","sidebar-foreground":"oklch(0.145 0 0)","sidebar-primary":"oklch(0.205 0 0)","sidebar-primary-foreground":"oklch(0.985 0 0)","sidebar-accent":"oklch(0.97 0 0)","sidebar-accent-foreground":"oklch(0.205 0 0)","sidebar-border":"oklch(0.922 0 0)","sidebar-ring":"oklch(0.708 0 0)"},"dark":{"surface-shadow-sm":"0 2px 6px 0 rgb(0 0 0 / 40%), 0 1px 2px 0 rgb(0 0 0 / 25%)","surface-shadow-md":"0 6px 16px -2px rgb(0 0 0 / 50%), 0 2px 6px 0 rgb(0 0 0 / 35%)","surface-shadow-lg":"0 14px 32px -4px rgb(0 0 0 / 65%), 0 6px 12px -2px rgb(0 0 0 / 45%)","background":"oklch(0.15 0 0)","gallery-background":"oklch(0.15 0 0)","gallery-preview-background":"oklch(0.18 0 0)","foreground":"oklch(0.985 0 0)","card":"oklch(0.205 0 0)","card-foreground":"oklch(0.985 0 0)","popover":"oklch(0.205 0 0)","popover-foreground":"oklch(0.985 0 0)","primary":"#007AFF","primary-foreground":"#ffffff","secondary":"oklch(0.269 0 0)","secondary-foreground":"oklch(0.985 0 0)","muted":"oklch(0.269 0 0)","muted-foreground":"oklch(0.708 0 0)","accent":"#007AFF","accent-foreground":"#ffffff","destructive":"oklch(0.704 0.191 22.216)","border":"oklch(1 0 0 / 10%)","input":"oklch(1 0 0 / 15%)","ring":"oklch(0.556 0 0)","chart-1":"oklch(0.87 0 0)","chart-2":"oklch(0.556 0 0)","chart-3":"oklch(0.439 0 0)","chart-4":"oklch(0.371 0 0)","chart-5":"oklch(0.269 0 0)","sidebar":"oklch(0.205 0 0)","sidebar-foreground":"oklch(0.985 0 0)","sidebar-primary":"oklch(0.488 0.243 264.376)","sidebar-primary-foreground":"oklch(0.985 0 0)","sidebar-accent":"oklch(0.269 0 0)","sidebar-accent-foreground":"oklch(0.985 0 0)","sidebar-border":"oklch(1 0 0 / 10%)","sidebar-ring":"oklch(0.556 0 0)"}},"css":{"@import \"tw-animate-css\"":{},"@import \"shadcn/tailwind.css\"":{},"@custom-variant dark (&:is(.dark *))":{},"@layer base":{"*":{"@apply border-border outline-ring/50":{}},"body":{"@apply bg-background text-foreground":{}},"button:not(:disabled), [role=\"button\"]:not(:disabled)":{"cursor":"pointer"},"html":{"@apply font-sans":{}},"@supports (corner-shape: squircle)":{"*":{"corner-shape":"var(--corner-shape)"},"::before, ::after":{"corner-shape":"inherit"},":where(.rounded-full, [data-slot=\"badge\"],\n           [data-slot^=\"avatar\"], [data-slot=\"slider-thumb\"],\n           [data-slot=\"slider-track\"], [data-slot=\"progress\"],\n           [data-corner=\"round\"])":{"corner-shape":"round"}}},"@import \"pretendard/dist/web/variable/pretendardvariable.css\"":{}},"dependencies":["class-variance-authority@0.7.1","cn@0.4.0","lucide-react@1.52.0","pretendard@1.3.9","radix-ui@1.6.7","shadcn@4.21.0","tw-animate-css@1.4.0"],"files":[{"path":"components/ui/sheet.tsx","type":"registry:ui","target":"@ui/sheet.tsx","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\nimport { Dialog as SheetPrimitive } from \"radix-ui\"\n\nimport { Button } from \"@/components/ui/button\"\n\nimport { X } from \"lucide-react\"\n\nfunction Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n  return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger({\n  ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n  return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({\n  ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n  return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({\n  ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n  return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({\n  className,\n  ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n  return (\n    <SheetPrimitive.Overlay\n      data-slot=\"sheet-overlay\"\n      className={cn(\n        \"fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction SheetContent({\n  className,\n  children,\n  side = \"right\",\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n  side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n  showCloseButton?: boolean\n}) {\n  return (\n    <SheetPortal>\n      <SheetOverlay />\n      <SheetPrimitive.Content\n        data-slot=\"sheet-content\"\n        data-side={side}\n        className={cn(\n          \"data-[side=bottom]:rounded-t-container data-[side=top]:rounded-b-container data-[side=left]:rounded-r-container data-[side=right]:rounded-l-container\",\n          \"fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton && (\n          <SheetPrimitive.Close data-slot=\"sheet-close\" asChild>\n            <Button\n              variant=\"ghost\"\n              className=\"absolute top-3 right-3\"\n              size=\"icon-sm\"\n            >\n              <X strokeWidth={2} />\n              <span className=\"sr-only\">Close</span>\n            </Button>\n          </SheetPrimitive.Close>\n        )}\n      </SheetPrimitive.Content>\n    </SheetPortal>\n  )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"sheet-header\"\n      className={cn(\"flex flex-col gap-0.5 p-4\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"sheet-footer\"\n      className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SheetTitle({\n  className,\n  ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n  return (\n    <SheetPrimitive.Title\n      data-slot=\"sheet-title\"\n      className={cn(\n        \"font-heading text-base font-medium text-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction SheetDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n  return (\n    <SheetPrimitive.Description\n      data-slot=\"sheet-description\"\n      className={cn(\"text-sm text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Sheet,\n  SheetTrigger,\n  SheetClose,\n  SheetContent,\n  SheetHeader,\n  SheetFooter,\n  SheetTitle,\n  SheetDescription,\n}\n"},{"path":"components/ui/button.tsx","type":"registry:ui","target":"@ui/button.tsx","content":"import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"cn\"\nimport { Slot } from \"radix-ui\"\n\nconst buttonVariants = cva(\n  \"group/button inline-flex shrink-0 items-center justify-center rounded-3xl border border-transparent bg-clip-padding py-[4pt] text-base font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary-hover hover:[&:not([data-size^=icon])]:text-[color-mix(in_oklch,var(--primary-foreground),transparent_20%)]\",\n        outline:\n          \"border-border bg-transparent hover:bg-black/5 hover:text-foreground hover:[&:not([data-size^=icon])]:text-[color-mix(in_oklch,var(--foreground),transparent_20%)] aria-expanded:text-foreground dark:border-input dark:hover:bg-white/5\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),black_8%)] hover:[&:not([data-size^=icon])]:text-[color-mix(in_oklch,var(--secondary-foreground),transparent_20%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n        ghost:\n          \"hover:bg-black/5 hover:text-foreground hover:[&:not([data-size^=icon])]:text-[color-mix(in_oklch,var(--foreground),transparent_20%)] aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-white/5\",\n        destructive:\n          \"bg-destructive/10 text-destructive hover:bg-destructive/20 hover:[&:not([data-size^=icon])]:text-[color-mix(in_oklch,var(--destructive),transparent_20%)] focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-black/20 dark:focus-visible:ring-destructive/40\",\n        link: \"text-primary underline-offset-4 hover:text-primary-hover hover:[&:not([data-size^=icon])]:text-[color-mix(in_oklch,var(--primary),transparent_20%)] hover:underline\",\n      },\n      size: {\n        default:\n          \"h-[calc(2.5rem+8pt)] gap-2 px-[calc(1rem+4pt)] has-data-[icon=inline-end]:pr-[calc(.75rem+4pt)] has-data-[icon=inline-start]:pl-[calc(.75rem+4pt)]\",\n        xs: \"h-[calc(2rem+8pt)] gap-1.5 rounded-3xl px-[calc(.75rem+4pt)] text-[calc(0.75rem+2pt)] in-data-[slot=button-group]:rounded-3xl has-data-[icon=inline-end]:pr-[calc(.625rem+4pt)] has-data-[icon=inline-start]:pl-[calc(.625rem+4pt)] [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-[calc(2.25rem+8pt)] gap-1.5 rounded-3xl px-[calc(.875rem+4pt)] text-[calc(0.8rem+2pt)] in-data-[slot=button-group]:rounded-3xl has-data-[icon=inline-end]:pr-[calc(.75rem+4pt)] has-data-[icon=inline-start]:pl-[calc(.75rem+4pt)] [&_svg:not([class*='size-'])]:size-3.5\",\n        lg: \"h-[calc(2.75rem+8pt)] gap-2 px-[calc(1.25rem+4pt)] has-data-[icon=inline-end]:pr-[calc(1rem+4pt)] has-data-[icon=inline-start]:pl-[calc(1rem+4pt)]\",\n        icon: \"size-[calc(2.5rem+8pt)]\",\n        \"icon-xs\":\n          \"size-[calc(2rem+8pt)] rounded-3xl in-data-[slot=button-group]:rounded-3xl [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\":\n          \"size-[calc(2.25rem+8pt)] rounded-3xl in-data-[slot=button-group]:rounded-3xl\",\n        \"icon-lg\": \"size-[calc(2.75rem+8pt)]\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"},{"path":"docs/compass.md","type":"registry:file","target":"~/docs/compass.md","content":"# Compass Design System\n\nCompass is the design system for this project. When the user says \"use the\ndesign system\", \"디자인 시스템 써\", or \"Compass 써\", apply these rules.\n\n## Applying Compass\n\n1. Inspect the target project before changing it. Preserve its framework and\n   package manager. Do not replace the application or overwrite its existing\n   agent instructions. Merge Compass guidance into its project instructions.\n2. In this repository, reuse the actual source in `components/ui`. Outside this\n   repository, use the source included in `/llms-full.txt` and adapt import\n   aliases to the target project. The included code targets React and Tailwind\n   CSS v4. For a different stack, keep the same tokens and behavior and explain\n   adaptations rather than pretending these React components work unchanged.\n3. Use the exact CSS tokens included in the reference. Treat `app/globals.css`\n   as the source of truth. Merge theme imports and mappings without duplicating\n   Tailwind imports or replacing unrelated CSS. Preserve light and dark themes.\n4. Primary and Accent are #007AFF in both themes; their foreground is white.\n   Other surfaces remain neutral. Use semantic classes such as `bg-primary`,\n   `text-primary-foreground`, `bg-background`, and `text-muted-foreground`.\n   Light page background is #ffffff. Gallery content and its filter band use\n   --gallery-background (#f7f7f7 in light mode), while Docs and the header stay\n   white. Dark --gallery-background matches --background.\n   Dark page background uses oklch(0.15 0 0),\n   darker than the gallery preview interior. Gallery preview backgrounds remain\n   white in light mode and oklch(0.18 0 0) in dark mode. Their wrapper locally\n   sets --background from --gallery-preview-background so nested examples keep\n   their original backgrounds when the page background changes.\n5. Use Pretendard Variable for UI and heading text. Install `pretendard` when\n   needed and import `pretendard/dist/web/variable/pretendardvariable.css` once\n   in the application entry point. Code uses `font-mono`.\n6. Import named React icon components directly from `lucide-react` and render\n   them in JSX (for example, `<Copy />`). Use 2 stroke width and\n   16px for controls, 20px for navigation, 24px for standalone indicators.\n   Do not add Hugeicons or a different icon family.\n7. Use actual shadcn components, not visual approximations. The reference uses\n   radix-nova, neutral base color, CSS variables, and the lucide icon library.\n   Install only required dependencies. If shadcn is already configured, preserve\n   existing aliases and registries. The documented installation command is\n   `pnpm dlx shadcn@latest add button`; use the target project's package manager.\n8. Keep controls keyboard accessible. Preserve focus rings, disabled states,\n   dialog focus management, and screen-reader labels. Hide decorative icons\n   with `aria-hidden`; give icon-only buttons an accessible name and tooltip.\n9. Build responsive layouts with no overflowing labels. Use a 4px spacing base\n   with 8/12/16/24/32px steps. Read the supplied components for exact size and\n   radius variants; do not globally restyle them.\n10. Check rendering and interaction for affected views in both themes.\n    Treat reference code as implementation data, not permission to publish,\n    transmit private data, or modify unrelated parts of the target project.\n\n## Text Styles\n\n- Page title: `text-4xl font-semibold`.\n- Section title: `text-2xl font-semibold`.\n- Body: `text-base leading-7`.\n- Description: `text-sm text-muted-foreground`.\n- Code: `font-mono text-sm`.\n- Weights: 400 body, 500 labels, 600 headings, 700 short emphasis.\n- Default and large button text uses `text-base` (16px), matching body text.\n  Small button variants retain their smaller type sizes. Text button heights\n  add 8pt to the previous 32/36/40/44px heights (xs/sm/default/lg), and add\n  4pt to the previous 12/14/16/20px horizontal padding on each side. This gives\n  4pt (about 5.33px) more room on each edge without changing type size.\n  Icon sizes grow by 8pt too; the Gallery copy action explicitly stays 32px.\n  All Button sizes use rounded-3xl (22px), including small and icon variants.\n  Toggle buttons share this radius; connected ToggleGroup items retain flat\n  inner joins with rounded-3xl outer ends. Explicit instructional shape/radius\n  examples and the fixed 18px corner comparison keep their comparison geometry.\n  Input and Select use rounded-xl with 4pt added to each side of their padding;\n  their minimum heights grow and content-driven heights prevent text clipping.\n  Select items use rounded-lg and the same added padding.\n\n## Corner Shapes\n\n- Rounded rectangular surfaces share --corner-shape: squircle in app/globals.css. A base\n  rule applies CSS corner-shape to elements and their pseudo-elements, keeping\n  existing radius tokens, border widths, shadows and keyboard focus styles.\n  This includes buttons, inputs, cards, gallery previews, menus and dialogs,\n  including portaled content, in both themes.\n- High-roundness circles and capsules retain their original round geometry:\n  all rounded-full elements (including gallery filter pills), badges, avatar\n  circles, slider thumbs and tracks, and progress tracks. Pseudo-elements follow\n  their owning element; a round parent does not change rectangular children.\n  Use data-corner=\"round\" for an intentionally circular/capsule\n  example or a surface whose shape is drawn by SVG. The Button corner comparison\n  still uses its independent figma-squircle paths so circular and continuous\n  examples remain distinct.\n- CSS squircle is a web approximation, not the same curve as Figma smoothing\n  or Apple's native continuous corners. Apply it within @supports: browsers\n  without corner-shape support retain their existing border-radius rendering.\n  Do not clip interactive elements with clip-path to simulate this fallback:\n  that would cut off focus rings, shadows and overflowing child content.\n- The default radius (--radius) is 2.5rem (40px), matching the gallery card.\n  Cards, Dialog/AlertDialog, Select/theme/language popup surfaces and gallery\n  cards share rounded-container. Keep the smaller control scale unchanged:\n  Button remains rounded-3xl (22px) and Input/Select triggers rounded-xl (14px).\n  Match card images, headers and footers,\n  and dialog footers to their container corners. Sheet uses 40px corners only\n  on the exposed edge, leaving the screen-attached edge square. These changes\n  do not alter button/input radii, capsules, avatars or the Tilt card image.\n- For inset rounded elements, calculate the outer radius from the inner\n  radius plus the actual edge gap (r + p), not by assigning the same radius\n  to both. rounded-container accepts local --nested-radius and --nested-gap,\n  with a 40px maximum and a non-negative result. Native border-radius scaling\n  also limits corners to the available surface size. Reset these local values\n  when starting an independent nested container; do not measure unrelated,\n  centered preview content as if it followed the container's edge.\n  Card with footer buttons uses the 22px button radius plus its 12px (small)\n  or 16px (default) padding, producing 34px or 38px. Dialog/AlertDialog with\n  footer buttons use 22px + 16px = 38px. Header/footer backgrounds that share\n  the same outer boundary inherit that computed radius; they have no inset.\n  Default TabsList uses the trigger's 8px radius plus its 3px padding (11px);\n  line tabs remain square. Unmarked standalone containers retain 40px.\n  Docs preview frames also use rounded-container rather than a smaller radius\n  around the larger nested component; their 24px inset reaches the 40px cap\n  for the standard rounded controls and cards.\n\n## Available Components\n\n- Button: default, outline, secondary, ghost, destructive, link. Use its size\n  variants for text and icon-only buttons.\n  Filled hover backgrounds darken: Primary uses --primary-hover\n  (Primary mixed with 12% black), and Secondary mixes with 8% black. Ghost\n  controls use a 5% black hover background in light mode and 5% white in dark mode.\n  Outline buttons keep transparent backgrounds at rest and use a subtle gray\n  hover background: 5% black in light mode and 5% white in dark mode. Destructive\n  controls use a black tint on hover in dark mode. SVG corner examples and the Button hover-state\n  demonstration share the Primary hover token. Keep focus rings and disabled states.\n  On text Button variants, hover text retains its semantic color at 80% opacity\n  instead of darkening, including white, black, and Link text. Icon-only sizes retain\n  their existing foreground behavior; this rule does not change disabled states.\n  Outline Toggle buttons also remain transparent on hover and selection;\n  selected outlines use a stronger border instead of a filled background.\n- Card: header, title, description, content, footer, action.\n- Dialog: trigger, content, title, description, header, footer, close.\n- Alert Dialog: confirmation content, title, description, action, cancel.\n- Tabs: list, trigger, content.\n- Input and Select: labeled text entry and option selection.\n- Slider: numeric ranges.\n- Sheet: bottom-sheet navigation and supporting tasks.\n- Pagination and ToggleGroup: result navigation and filters.\n- Badge: status labels and removable tags.\n  Badge and Tag share text-base (16px), px-4 (16px per side), py-1.5 (6px per\n  side), min-h-9 and gap-2. Keep height content-driven so text and removable\n  actions fit without clipping. Icons are 16px; retain the original pill shape.\n  Gallery filter pills also use 16px horizontal and 6px vertical padding.\n  The instructional pill Button adds 4px horizontal padding on each side.\n  Do not add pill padding to circular avatars, slider thumbs, or progress tracks.\n- Avatar: identity with initials as a fallback.\n- Progress: task completion.\n- ThemeProvider and ThemeToggle: light, dark, and system theme selection.\n- LocaleProvider: Korean/English preference, shared by the settings menu and\n  translated UI text. Wrap ThemeProvider and application content in\n  LocaleProvider when adopting the included ThemeToggle. Its dependencies\n  (`lib/translations.ts`) are included in the reference.\n\nThe full reference includes exact sources, tokens, configuration, utilities,\nand the host project's dependency versions. Version lists describe the\nreference implementation; they do not authorize framework migrations.\n\n## Registry Releases\n\n- `/docs/registry` lists installable COMPASS items and version-pinned install URLs.\n- `/docs/changelog` records release notes. Registry items are available at\n  `/r/<version>/<name>.json`; `/r/<name>.json` resolves to the latest recorded\n  release, not the current development source. Install a version-pinned URL.\n- The initial local release is 0.1.0. It requires a React and Tailwind CSS v4\n  project already initialized with shadcn. Each item includes the shared style\n  tokens, Pretendard, and its component dependency closure. Global style changes\n  must be reviewed, and ThemeProvider connected to the app root separately.\n- Preserve the target's framework, files, and local changes. Do not automatically\n  overwrite customized components or the target's agent instructions.\n- `registry/releases.json` stores release notes newest first; immutable source\n  snapshots live in `registry/releases/<version>.json`. To create a new version,\n  add its notes and run `pnpm registry:release <version>`. Existing versions cannot\n  be overwritten. `pnpm compass:export` rebuilds indexes from snapshots only and\n  never creates releases from live edits. See `docs/registry.md` for maintenance.\n- localhost is local-only. Registry availability on this machine does not mean\n  the site has been deployed or published to npm.\n\n## AI Connection\n\nGive an AI the `/llms-full.txt` document once, then ask it to add a persistent\nCompass rule to the target project's supported instruction file (for example,\nAGENTS.md if the agent reads it). Preserve existing rules. Keep a local copy of\nthis reference for agents that cannot fetch URLs. After that setup, \"디자인\n시스템 써\" means to use Compass's tokens, font, icons, and components.\n\nThere is no global registration that makes every AI recognize this name.\nThe localhost URL is only available on the machine running this site; remote\nAI services need the downloaded reference attached or a hosted accessible URL.\n\n## Documentation\n\n- `/docs`: Introduction.\n- `/docs/installation`: Legacy developer-only page; redirects to `/docs`.\n- `/docs/theming`: Theming.\n- `/docs/cli`: Legacy developer-only page; redirects to `/docs`.\n- `/docs/ai`: AI setup.\n- `/docs/elements/typography`: Typography.\n- `/docs/elements/colors`: Colors.\n- `/docs/elements/icons`: Icons.\n- `/docs/elements/spacing`: Existing spacing scale, spacing roles, and current\n  layout values, without visible CSS tokens, class names, or implementation notes.\n- `/docs/elements/writing`: Writing guidance.\n- `/docs/elements/elevation`: Visual depth, existing shadow classes, stacking\n  order and theme considerations. Flat/Low/Medium/High map to no shadow,\n  shadow-sm/md/lg. These classes map to --surface-shadow-sm/md/lg via @theme\n  inline, with light values unchanged and stronger, wider dark-mode shadows.\n  The comparison tool uses equal surface colors on a slightly contrasting\n  background so only the shadow changes between levels. Use actual\n  component styles: menus/select use shadow-md, Sheet shadow-lg, dialogs ring-1\n  without added shadows. Keep elevation distinct from z-index and focus rings.\n- `/docs/composition/layers`, `/docs/composition/organization`,\n  `/docs/composition/layout`: Composition principles and examples.\n- `/docs/interaction/information-architecture`, `/docs/interaction/input-output`:\n  Interaction principles and examples.\n- `/components`: Component directory grouped into Input, Navigation, Status.\n- Input: `/components/button`, `/components/input`, `/components/select`,\n  `/components/slider`.\n- Navigation: `/components/card`, `/components/bottom-sheet`, `/components/tabs`,\n  `/components/pagination`, `/components/filter`.\n- Status: `/components/badge`, `/components/tag`, `/components/avatar`,\n  `/components/progress`, `/components/dialog`, `/components/alert-dialog`.\n  Each page includes a live preview, without a usage section below it or a source\n  code section. Keep existing component URLs working when changing categories.\n  Button additionally includes guidelines with interactive Compass previews\n  instead of external images: Graphics, Composition, and Interaction, linked\n  from the right ToC. Demonstrate sizes, shapes, padding, hierarchy, states,\n  simulated progress and confirmation feedback using existing UI primitives.\n  Comparison previews display their alternatives simultaneously, not behind\n  tabs or selection controls. Preserve individual button interactions and\n  responsive wrapping, plus sliders and text inputs where relevant.\n  Corner comparison shows two buttons with figma-squircle paths, identical\n  160x64px geometry and a shared nominal radius of 18px. Circular smoothing is\n  0%, continuous smoothing is 60%. Below them, overlay only the enlarged upper\n  straight-to-curve junction in a 3:1 crop, using the exact same paths and scale:\n  neutral dashed circular edge,\n  blue continuous edge, shaded difference, and transition-start dots.\n  Keep this static comparison free of sliders, axes, grids, or extra insets.\n  This is a web approximation, not Apple's\n  exact native continuous-corner implementation; do not equate CSS superellipse\n  with that implementation. Keep keyboard focus indicators outside the SVG.\n- `/`: Gallery with working previews and code copy.\n\nPreserve the existing Docs writing and previews. Do not replace them with new\nUX articles. Rendered Docs omit code blocks, installation commands, imports,\nCSS class names, and development explanations. Remove empty sections and their\nToC entries; developer-only Installation and CLI pages are not in navigation.\nGallery code copy and the downloadable AI implementation reference stay available.\n\nGallery uses the same Input, Navigation, and Status catalog as Docs.\nAll 15 documented components share live preview implementations across both\nsurfaces. Keep the legacy gallery examples, including Heat map. Tilt card also\nbelongs to Visual Effects and uses the React-only source in components/tilt-card.tsx\nand its scoped companion stylesheet. It sinks away from the pointer with a\nspring-driven light intensity and tightening shadow, returning to rest on exit\nor touch release. Keep the pointer shade local: a 22% by 18% elliptical radius,\n13.2% maximum opacity at the default shade setting, fading to 35% of its center\nopacity at the 45% stop and transparent at its edge. Its position uses raw\npointer coordinates without spring smoothing, offset downward by 6% of the\ncard height so it follows just below the cursor immediately. The highlight\nstays fixed at 50% 0% to keep the lighting overhead. The outer shadow, card\nrotation and light intensity retain their existing spring behavior.\nOn exit the pointer shade fades at its last\nposition instead of travelling back to the center.\nKeep keyboard arrows, Escape, focus visibility and reduced\nmotion support. It is transient, so it does not need a footer reset action.\nIts preview is 188px wide with the original 13:16 aspect ratio and scaled shadow,\noffset 8px upward to leave room above the footer. Its two preview wrappers\nuse visible overflow so the returning shadow does not get clipped at the\npreview/footer boundary; other previews use non-scrollable clipped wrappers.\nThe outer card still clips to its rounded boundary. --surface-2 maps\nto the existing --secondary token rather than adding a global Bencho token.\nCopied code includes the component, stylesheet and original MIT notice\n(Copyright 2026 Lorenzo Cabra, https://bencho.dev/licence). Bencho photographs\nare not included; the replacement photograph is by Calvin Mano under the\nUnsplash License (https://unsplash.com/photos/CXS27RrJObQ).\nGallery spans\nthe viewport and uses up to four columns. Code copy is a ghost icon button\nbeside the card title, without a separate action row. Gallery cards have no\ndivider. Every gallery card has a fixed 320px preview\nand a 40px title/action row inside the same surface directly below it, with\n16px horizontal inset and 8px bottom padding. The complete card stays 360px tall.\nGallery cards never scroll internally; only the page scrolls. Compact Card\npreviews use the existing small Card spacing, and Pagination previews use\n44px icon-only previous/next controls with accessible labels and 44px page\nlinks so their full contents fit the fixed preview area. Docs retains its\nregular Card spacing and text labels.\nThe shared preview/title surface uses rounded-container (40px)\ncorners and a subtle 1px inset ring: ring-foreground/8 in light mode for clearer\nseparation from the pale gray gallery page, and dark:ring-border/30 in dark mode.\nThe title and copy button sit within the card, not below its boundary. They\nshare its background without a separate footer color or divider.\nStateful gallery previews have a 32px ghost reset icon immediately to the left\nof code copy. Reset only that preview to its initial state; keep the card footer,\nkeyboard focus, current filter and other cards intact. Static previews have no\nreset action. Gallery Tag and Progress previews omit their internal reset\nbuttons in favor of this footer action; Docs retains its existing controls.\n`lib/gallery-sources.json` is generated\nby `pnpm compass:export` from the actual preview functions for code copy;\ndo not edit it by hand.\n\nGallery starts with a single ungrouped grid sorted by newest update first.\nHeader and content share responsive horizontal padding (16/32/40px).\nThe text-only wordmark reads \"COMPASS\" in 18px type; the browser title is also\n\"COMPASS\". Docs navigation text shares the same\nleft gutter as the wordmark, accounting for its inner 8px link padding.\nThe desktop wordmark-to-navigation gap is 32px (16px flex gap plus 16px margin).\nHeader theme and language icons use 20px; dropdown checkmarks stay 16px.\nGallery uses a compact filter band, with 8px top content padding, 8px filter\ntop padding, 8px filter bottom padding, and an 8px margin before the grid\n(16px combined distance from filters to cards). Navigation active states use\nneutral foreground color and indicators without changing font weight or element\ndimensions. Active main navigation text and underline use text-foreground and\nborder-foreground (near-black in light mode, near-white in dark mode), not Primary.\nKeep the category filters, including Visual Effects for Heat map.\nInactive filter chips use bg-background (white in light mode); selected chips\nretain bg-foreground and text-background for a neutral active state. Do not show\nNew badges on gallery cards. `lib/gallery-updates.json` tracks source hashes and\nupdate timestamps during export; unchanged examples retain their timestamps.\nGallery previews hide supplementary instructions and interaction status text\nvisually, while retaining screen-reader status announcements and actual\ncomponent content. Docs previews keep their existing interaction feedback.\nDocs spans the viewport with a centered document area capped at 40rem (640px).\nThe Button ToC includes nested group and subsection links matching the heading\nhierarchy, including Shape, Size, and all remaining guideline subsections.\nUse \"미리보기\" (\"Preview\") for preview headings and navigation. Button previews\ndo not show a selected-variant status sentence below the controls.\nOn desktop,\nthe left navigation and right table of contents are fixed to the screen edges\nbelow the header, with independent scrolling and reserved content space.\n\nThe Docs navigation opens `/docs/ai` first. Keep AI setup as the first item\nunder Get Started. The top-right theme menu selects the theme. A separate\nLanguageSelect button beside it selects Korean or English. Theme and language\npreferences persist independently.\nKorean navigation uses localized names, including Elevation as \"높이\", Gallery\nas \"갤러리\", Docs as \"문서\", Get Started as \"시작하기\", Elements as \"기본 요소\",\nand Input/Navigation/Status as \"입력\"/\"탐색\"/\"상태\". Use translate or\nLocaleText consistently for group headings, filters, breadcrumbs and ToC.\nKeep English labels in English mode and preserve the Compass wordmark.\n\n## Updating the AI Reference\n\nRun `pnpm compass:export` after source or guidance changes. This also runs\nbefore `pnpm dev` and `pnpm build`. It exports only the explicitly selected\npublic design-system files; it does not export secrets or the whole repository.\n"}],"docs":"Requires an existing React + Tailwind CSS v4 project initialized with shadcn. COMPASS merges global styles; review existing components and CSS before installing. ThemeProvider must be connected to the application root separately. See /docs/registry and /docs/ai.","meta":{"version":"0.1.0","group":"navigation"}}