{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"cta-block","type":"registry:ui","title":"CTA block","description":"The closing call to action: the promise again, one specific next step and a reassurance line.","dependencies":["clsx","lucide-react","tailwind-merge"],"registryDependencies":["https://caliperui.site/r/styles.json"],"files":[{"path":"ui/block-concept.tsx","type":"registry:ui","target":"components/ui/block-concept.tsx","content":"import { ArrowRight } from \"lucide-react\";\nimport type { ComponentProps, ElementType, ReactNode } from \"react\";\nimport { cn } from \"./lib/cn\";\nimport { StageScope } from \"./stage-scope\";\nimport \"./block-concept.css\";\n\n/**\n * Marketing blocks share one voice: monochrome from the system tokens, Geist\n * display with two-tone titles, ink actions, ruled sections and ember only for\n * focus. Blocks follow the page theme, and the Caliper UI controls inside them too.\n */\n\nexport type BlockAction = { label: string; href?: string; onClick?: () => void };\n\n/**\n * A full-bleed band. The section is the container, so everything inside lays\n * out by the block's own width; `block-inner` holds the measure and rhythm.\n * `backdrop` paints behind the content edge to edge (grid lines, a tone).\n */\nexport function BlockRoot({\n  as: Tag = \"section\",\n  width = \"default\",\n  backdrop,\n  tone,\n  className,\n  innerClassName,\n  children,\n  ...props\n}: Omit<ComponentProps<\"section\">, \"ref\"> & {\n  /** The band's element; a site footer is a footer. */\n  as?: \"section\" | \"footer\" | \"div\";\n  /** default 1240px · narrow 960px · wide 1440px. */\n  width?: \"default\" | \"narrow\" | \"wide\";\n  backdrop?: ReactNode;\n  /** A band tone: the page colour or the sunken colour. */\n  tone?: \"page\" | \"sunken\" | \"ink\";\n  innerClassName?: string;\n}) {\n  return (\n    <Tag data-slot=\"block\" data-tone={tone} className={cn(\"@container relative isolate overflow-clip\", className)} {...props}>\n      {backdrop}\n      <div data-slot=\"block-inner\" data-width={width} className={innerClassName}>\n        {children}\n      </div>\n    </Tag>\n  );\n}\n\nexport function BlockEyebrow({ className, ...props }: ComponentProps<\"p\">) {\n  return <p data-slot=\"block-eyebrow\" className={className} {...props} />;\n}\n\n/** A display heading in the block face. size 1 is the hero headline. */\nexport function BlockTitle({\n  as: Tag = \"h2\",\n  size = 2,\n  className,\n  ...props\n}: ComponentProps<\"h2\"> & { as?: \"h1\" | \"h2\" | \"h3\"; size?: 1 | 2 | 3 }) {\n  return <Tag data-slot=\"block-title\" data-size={size} className={className} {...props} />;\n}\n\n/** The second tone of a title: these words land in grey. */\nexport function BlockEm({ className, ...props }: ComponentProps<\"em\">) {\n  return <em data-slot=\"block-em\" className={className} {...props} />;\n}\n\nexport function BlockLead({ className, ...props }: ComponentProps<\"p\">) {\n  return <p data-slot=\"block-lead\" className={className} {...props} />;\n}\n\n/**\n * The section opening every block shares: eyebrow, title and lead. `split`\n * sets the lead beside the title on wide blocks; `center` stacks it centred.\n */\nexport function BlockHeader({\n  eyebrow,\n  title,\n  lead,\n  align = \"start\",\n  aside,\n  headingLevel = 2,\n  className,\n}: {\n  eyebrow?: ReactNode;\n  title: ReactNode;\n  lead?: ReactNode;\n  align?: \"start\" | \"center\" | \"split\";\n  /** 1 when the block opens the page, e.g. a pricing page. */\n  headingLevel?: 1 | 2;\n  /** Sits at the end of the header row, e.g. a period toggle. */\n  aside?: ReactNode;\n  className?: string;\n}) {\n  return (\n    <header data-slot=\"block-header\" data-align={align} className={className}>\n      <div data-slot=\"block-header-title\">\n        {eyebrow && <BlockEyebrow>{eyebrow}</BlockEyebrow>}\n        <BlockTitle as={headingLevel === 1 ? \"h1\" : \"h2\"}>{title}</BlockTitle>\n      </div>\n      {(lead || aside) && (\n        <div data-slot=\"block-header-aside\">\n          {lead && <BlockLead>{lead}</BlockLead>}\n          {aside}\n        </div>\n      )}\n    </header>\n  );\n}\n\nexport function BlockActions({\n  primary,\n  secondary,\n  className,\n  block = false,\n}: {\n  primary?: BlockAction;\n  secondary?: BlockAction;\n  className?: string;\n  /** Full-width actions, e.g. on phones. */\n  block?: boolean;\n}) {\n  if (!primary && !secondary) return null;\n  return (\n    <div data-slot=\"block-actions\" className={cn(\"flex flex-wrap gap-3\", block && \"@max-[520px]:grid @max-[520px]:grid-cols-1\", className)}>\n      {primary && <BlockButton action={primary} kind=\"primary\" arrow />}\n      {secondary && <BlockButton action={secondary} kind=\"secondary\" />}\n    </div>\n  );\n}\n\nexport function BlockButton({ action, kind = \"primary\", arrow = false, link: Link = \"a\" }: { action: BlockAction; kind?: \"primary\" | \"secondary\"; arrow?: boolean; /** The element for a link action, e.g. your router's Link. */ link?: ElementType }) {\n  const shared = { \"data-slot\": \"block-button\", \"data-kind\": kind } as const;\n  const content = (\n    <>\n      {action.label}\n      {arrow && <ArrowRight aria-hidden=\"true\" data-slot=\"block-button-arrow\" className=\"size-4\" />}\n    </>\n  );\n  return action.href ? (\n    <Link href={action.href} {...shared}>\n      {content}\n    </Link>\n  ) : (\n    <button type=\"button\" onClick={action.onClick} {...shared}>\n      {content}\n    </button>\n  );\n}\n\nexport function BlockCard({ className, ...props }: ComponentProps<\"div\">) {\n  return <div data-slot=\"block-card\" className={className} {...props} />;\n}\n\nexport function BlockChip({ className, ...props }: ComponentProps<\"span\">) {\n  return <span data-slot=\"block-chip\" className={className} {...props} />;\n}\n\n/**\n * A product artefact on a stage: a dotted tonal panel holding a framed window, with an optional floating note that overlaps the\n * window's corner on wide blocks and sits beneath it on narrow ones.\n */\nexport function BlockStage({\n  title,\n  floating,\n  bare = false,\n  className,\n  children,\n}: {\n  /** Shown in the window bar, e.g. \"halden.app/close\". */\n  title?: string;\n  floating?: ReactNode;\n  /** No window frame: the children bring their own surfaces. */\n  bare?: boolean;\n  className?: string;\n  children: ReactNode;\n}) {\n  return (\n    <div data-slot=\"block-stage\" className={className}>\n      {bare ? (\n        <StageScope>{children}</StageScope>\n      ) : (\n        <div data-slot=\"block-window\">\n          <div data-slot=\"block-window-bar\" aria-hidden={title ? undefined : true}>\n            <span data-slot=\"block-window-dots\" aria-hidden=\"true\"><i /><i /><i /></span>\n            {title && <span data-slot=\"block-window-title\">{title}</span>}\n          </div>\n          <div data-slot=\"block-window-body\"><StageScope>{children}</StageScope></div>\n        </div>\n      )}\n      {floating && <div data-slot=\"block-float\">{floating}</div>}\n    </div>\n  );\n}\n\n/** Company names set as type in a quiet row; swap in SVG marks in production. */\nexport function BlockLogos({ label, logos, className }: { label?: string; logos: readonly string[]; className?: string }) {\n  return (\n    <div data-slot=\"block-logos\" className={className}>\n      {label && <p data-slot=\"block-logos-label\">{label}</p>}\n      <ul aria-label={label ?? \"Customers\"}>\n        {logos.map((logo) => (\n          <li key={logo}>{logo}</li>\n        ))}\n      </ul>\n    </div>\n  );\n}\n\n/** Initials from a name, in the block's highlight tones. */\nexport function BlockInitials({ name, size = 36, tone, className }: { name: string; size?: number; tone?: number; className?: string }) {\n  const words = name.trim().split(/\\s+/u);\n  const initials = ((words[0]?.[0] ?? \"\") + (words.length > 1 ? (words[words.length - 1]?.[0] ?? \"\") : \"\")).toUpperCase();\n  return (\n    <span data-slot=\"block-initials\" data-tone={tone === undefined ? undefined : tone % 4} aria-hidden=\"true\" className={className} style={{ width: size, height: size, fontSize: Math.round(size / 2.8) }}>\n      {initials}\n    </span>\n  );\n}\n\nexport type BlockStat = { value: ReactNode; label: string };\n"},{"path":"ui/cta-block.tsx","type":"registry:ui","target":"components/ui/cta-block.tsx","content":"import type { ReactNode } from \"react\";\nimport { cn } from \"./lib/cn\";\nimport { BlockActions, BlockEyebrow, BlockRoot, BlockTitle, type BlockAction } from \"./block-concept\";\nimport \"./cta-block.css\";\n\n/**\n * The closing call to action: the hero's promise again at poster size, one\n * specific next step and a reassurance line. `tone=\"ink\"` sets it on an ink\n * panel that inverts its actions; `tone=\"page\"` leaves it on the page.\n */\nexport function CtaBlock({\n  eyebrow,\n  title,\n  reassurance,\n  primary,\n  secondary,\n  action,\n  tone = \"ink\",\n  className,\n}: {\n  eyebrow?: string;\n  title: string;\n  /** e.g. \"14 days free · no card · import your September close\". */\n  reassurance?: string;\n  primary?: BlockAction;\n  secondary?: BlockAction;\n  /** Custom content in place of the actions, e.g. an install command. */\n  action?: ReactNode;\n  tone?: \"ink\" | \"page\";\n  className?: string;\n}) {\n  const ink = tone === \"ink\";\n  // An ink panel that inverts its actions.\n  return (\n    <BlockRoot className={className}>\n      <div\n        data-slot={ink ? \"cta-band\" : \"cta-page\"}\n        className={cn(\n          \"relative grid justify-items-center gap-8 overflow-hidden text-center\",\n          ink ? \"rounded-[var(--k-radius-xl)] bg-[var(--k-ink)] px-[clamp(20px,5cqi,80px)] py-[clamp(56px,9cqi,120px)] text-[var(--k-bg)]\" : \"py-[clamp(40px,8cqi,104px)]\",\n        )}\n      >\n        {ink && <div aria-hidden=\"true\" data-slot=\"block-dots\" />}\n        {eyebrow && <BlockEyebrow className={cn(\"relative\", ink && \"!text-current opacity-80\")}>{eyebrow}</BlockEyebrow>}\n        <BlockTitle size={1} className={cn(\"relative max-w-[18ch]\", ink && \"!text-current\")}>{title}</BlockTitle>\n        {action ? (\n          <div className=\"relative w-full max-w-[620px] text-left\">{action}</div>\n        ) : (\n          <BlockActions primary={primary} secondary={secondary} className=\"relative justify-center\" block />\n        )}\n        {reassurance && <p className={cn(\"relative text-sm\", ink ? \"opacity-80\" : \"text-[var(--k-muted)]\")}>{reassurance}</p>}\n      </div>\n    </BlockRoot>\n  );\n}\n"},{"path":"ui/lib/cn.ts","type":"registry:ui","target":"components/ui/lib/cn.ts","content":"import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n  extend: { theme: { radius: [\"control\", \"surface\", \"overlay\"], shadow: [\"overlay\"] } },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"},{"path":"ui/stage-scope.tsx","type":"registry:ui","target":"components/ui/stage-scope.tsx","content":"\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\n\n/**\n * True inside a block stage: a frame shown there is a demonstration on a page\n * that already has its own main landmark, so it should not add a second one.\n */\nconst InStage = createContext(false);\n\nexport function StageScope({ children }: { children: ReactNode }) {\n  return <InStage.Provider value={true}>{children}</InStage.Provider>;\n}\n\nexport const useInStage = () => useContext(InStage);\n"},{"path":"ui/block-concept.css","type":"registry:file","target":"components/ui/block-concept.css","content":"/* block-concept.tsx's styles; it imports this file. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  /* A site header used outside a block still needs the block tokens. */\n  [data-slot=\"block\"] {\n    --k-display-font: var(--font-display-block, var(--font-sans, system-ui, sans-serif));\n    --k-display-weight: 700;\n    --k-display-case: none;\n    --k-display-track: -0.03em;\n    --k-display-stretch: normal;\n    --k-display-lh: 1.04;\n    /* Monochrome, from the system tokens, so blocks follow the page theme. */\n    --k-bg: var(--background, #fff); --k-surface: var(--elevated, #fff); --k-sunken: var(--surface, #f7f7f8); --k-ink: var(--foreground, #18181b); --k-muted: var(--muted-foreground, #5d5d66); --k-line: var(--border, #e4e4e8);\n    --k-line-strong: color-mix(in oklab, var(--border-strong, #8a8a94) 55%, var(--k-line));\n    /* The grey second line of a two-tone title; 3:1 or better as large text in both themes. */\n    --k-faint: color-mix(in oklab, var(--k-muted) 70%, var(--k-bg));\n    --k-accent: var(--k-ink); --k-accent-ink: var(--k-bg); --k-hi: var(--accent-text, var(--k-ink)); --k-hi-soft: var(--accent-soft, var(--k-sunken));\n    --k-focus: var(--brand, #bb4400); --k-danger: var(--danger, #c2272d);\n    --k-stage: var(--surface, #f7f7f8); --k-stage-dot: color-mix(in oklab, var(--k-ink) 14%, var(--k-stage));\n    --k-shadow: none;\n    --k-radius: 12px; --k-radius-lg: 16px; --k-radius-xl: 20px; --k-btn-radius: 999px;\n    --k-tile-1: color-mix(in oklab, var(--k-ink) 5%, var(--k-bg)); --k-tile-2: color-mix(in oklab, var(--k-ink) 8%, var(--k-bg)); --k-tile-3: color-mix(in oklab, var(--k-ink) 11%, var(--k-bg)); --k-tile-4: color-mix(in oklab, var(--k-ink) 14%, var(--k-bg));\n    background: var(--k-bg);\n    color: var(--k-ink);\n    font-family: var(--font-sans, system-ui, sans-serif);\n  }\n  /* Band tones inside a concept: a sunken band, or an inverse ink band. */\n  [data-slot=\"block\"][data-tone=\"sunken\"] { background: var(--k-sunken); }\n\n  [data-slot=\"block-inner\"] {\n    position: relative;\n    z-index: 1;\n    margin-inline: auto;\n    max-inline-size: 1240px;\n    padding-inline: clamp(20px, 5cqi, 64px);\n    padding-block: clamp(64px, 10cqi, 128px);\n  }\n  [data-slot=\"block-inner\"][data-width=\"narrow\"] { max-inline-size: 960px; }\n  [data-slot=\"block-inner\"][data-width=\"wide\"] { max-inline-size: 1440px; }\n\n  /* ── Type ─────────────────────────────────────────── */\n  [data-slot=\"block-eyebrow\"] {\n    display: inline-flex;\n    align-items: center;\n    gap: 8px;\n    margin: 0;\n    font-size: 14px;\n    line-height: 20px;\n    font-weight: 500;\n    color: var(--k-muted);\n  }\n\n  [data-slot=\"block-title\"] {\n    margin: 0;\n    font-family: var(--k-display-font);\n    font-weight: var(--k-display-weight);\n    font-stretch: var(--k-display-stretch);\n    font-variation-settings: \"wdth\" var(--k-display-wdth, 100);\n    text-transform: var(--k-display-case);\n    letter-spacing: var(--k-display-track);\n    font-optical-sizing: auto;\n    text-wrap: balance;\n    color: var(--k-ink);\n  }\n  [data-slot=\"block-title\"][data-size=\"1\"] { font-size: clamp(40px, 5cqi, 64px); line-height: 1.04; font-weight: 700; letter-spacing: -0.048em; }\n  [data-slot=\"block-title\"][data-size=\"2\"] { font-size: clamp(30px, 3.4cqi, 40px); line-height: 1.1; letter-spacing: -0.04em; }\n  [data-slot=\"block-title\"][data-size=\"3\"] { font-size: clamp(19px, 1.7cqi, 22px); line-height: 1.2; font-weight: 600; letter-spacing: -0.015em; }\n  /* Two-tone titles: the emphasised words land in grey. */\n  [data-slot=\"block-em\"] { font-style: normal; color: var(--k-faint); }\n\n  [data-slot=\"block-lead\"] {\n    margin: 0;\n    max-width: 50ch;\n    font-size: clamp(16px, 1.3cqi, 18px);\n    line-height: 1.6;\n    color: var(--k-muted);\n    text-wrap: pretty;\n  }\n\n  /* The shared section opening. */\n  [data-slot=\"block-header\"] {\n    display: grid;\n    gap: 20px 48px;\n    margin-bottom: clamp(36px, 5cqi, 64px);\n  }\n  [data-slot=\"block-header-title\"] { display: grid; gap: 18px; justify-items: start; }\n  [data-slot=\"block-header-aside\"] { display: grid; gap: 16px; align-content: end; justify-items: start; }\n  [data-slot=\"block-header\"][data-align=\"center\"] { justify-items: center; text-align: center; }\n  [data-slot=\"block-header\"][data-align=\"center\"] :is([data-slot=\"block-header-title\"], [data-slot=\"block-header-aside\"]) { justify-items: center; }\n  [data-slot=\"block-header\"][data-align=\"center\"] [data-slot=\"block-title\"] { max-width: 18ch; }\n  @container (min-width: 900px) {\n    [data-slot=\"block-header\"][data-align=\"split\"] { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); align-items: end; }\n    [data-slot=\"block-header\"][data-align=\"split\"] [data-slot=\"block-header-aside\"] { justify-items: start; padding-bottom: 6px; }\n  }\n\n  /* ── Buttons ──────────────────────────────────────── */\n  [data-slot=\"block-button\"] {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    gap: 8px;\n    min-height: 40px;\n    padding: 0 16px;\n    border: 0;\n    border-radius: var(--k-btn-radius);\n    font: 500 14px/1 var(--font-sans, system-ui, sans-serif);\n    letter-spacing: -0.005em;\n    text-decoration: none;\n    white-space: nowrap;\n    cursor: pointer;\n    transition: background-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out), translate var(--duration-normal) var(--ease-settle);\n  }\n  [data-slot=\"block-button\"][data-kind=\"primary\"] {\n    background: var(--k-accent);\n    color: var(--k-accent-ink);\n    box-shadow: inset 0 1px 0 rgb(255 255 255 / 14%), 0 1px 2px rgb(0 0 0 / 20%);\n  }\n  [data-slot=\"block-button\"][data-kind=\"secondary\"] {\n    background: color-mix(in srgb, var(--k-surface) 60%, transparent);\n    color: var(--k-ink);\n    box-shadow: inset 0 0 0 1px var(--k-line-strong);\n  }\n  [data-slot=\"block-button-arrow\"] { transition: translate var(--duration-normal) var(--ease-settle); }\n  @media (hover: hover) {\n    [data-slot=\"block-button\"][data-kind=\"primary\"]:hover { background: color-mix(in srgb, var(--k-accent) 86%, var(--k-bg)); }\n    [data-slot=\"block-button\"][data-kind=\"secondary\"]:hover { background: var(--k-sunken); box-shadow: inset 0 0 0 1px var(--k-ink); }\n    [data-slot=\"block-button\"]:hover [data-slot=\"block-button-arrow\"] { translate: 3px 0; }\n  }\n  [data-slot=\"block-button\"]:active { translate: 0 var(--motion-press-travel); }\n  [data-slot=\"block-button\"]:focus-visible { outline: 2px solid var(--k-focus); outline-offset: 3px; }\n\n  [data-slot=\"block-card\"] {\n    border-radius: var(--k-radius-lg);\n    background: var(--k-surface);\n    box-shadow: 0 0 0 1px var(--k-line);\n  }\n  [data-slot=\"block-chip\"] {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    min-height: 28px;\n    padding: 0 12px;\n    border-radius: 999px;\n    font-size: 13px;\n    font-weight: 500;\n    background: var(--k-hi-soft);\n    color: var(--k-ink);\n    box-shadow: inset 0 0 0 1px var(--k-line);\n    text-decoration: none;\n  }\n  /* People in blocks are the library's light glass orbs (as Avatar), one pastel tone per person. */\n  [data-slot=\"block-initials\"] {\n    --av-a: #9ec5ff;\n    --av-b: #c4b2ff;\n    display: inline-grid;\n    flex: none;\n    place-items: center;\n    border-radius: 999px;\n    font-weight: 600;\n    color: #161616;\n    background:\n      radial-gradient(circle at 30% 24%, rgb(255 255 255 / 80%), rgb(255 255 255 / 0%) 36%),\n      radial-gradient(circle at 76% 84%, color-mix(in oklab, var(--av-b) 78%, #3b2a6b), transparent 58%),\n      linear-gradient(140deg, var(--av-a) 12%, var(--av-b) 88%);\n    box-shadow: inset 0 0 0 1px rgb(255 255 255 / 34%), inset 0 -4px 8px rgb(0 0 0 / 8%);\n  }\n  [data-slot=\"block-initials\"][data-tone=\"1\"] { --av-a: #a3f0c8; --av-b: #7fd3e6; }\n  [data-slot=\"block-initials\"][data-tone=\"2\"] { --av-a: #c9adff; --av-b: #ffb2d8; }\n  [data-slot=\"block-initials\"][data-tone=\"3\"] { --av-a: #ffd6a0; --av-b: #ffab86; }\n\n  /* ── Stage: a product artefact framed on a tonal panel ─ */\n  [data-slot=\"block-stage\"] {\n    position: relative;\n    padding: clamp(14px, 4.5cqi, 64px);\n    padding-bottom: 0;\n    border-radius: var(--k-radius-xl);\n    background-color: var(--k-stage);\n    background-image: radial-gradient(var(--k-stage-dot) 1px, transparent 1.2px);\n    background-size: 16px 16px;\n    box-shadow: inset 0 0 0 1px var(--k-line);\n    overflow: hidden;\n  }\n  [data-slot=\"block-window\"] {\n    position: relative;\n    overflow: hidden;\n    border-radius: var(--k-radius-lg) var(--k-radius-lg) 0 0;\n    background: var(--k-surface);\n    box-shadow: 0 0 0 1px var(--k-line), var(--k-shadow);\n  }\n  [data-slot=\"block-window-bar\"] {\n    display: flex; align-items: center; gap: 12px;\n    height: 40px; padding: 0 16px;\n    border-bottom: 1px solid var(--k-line);\n    background: color-mix(in srgb, var(--k-sunken) 55%, var(--k-surface));\n  }\n  [data-slot=\"block-window-dots\"] { display: none; }\n  [data-slot=\"block-window-dots\"] i { width: 10px; height: 10px; border-radius: 999px; background: var(--k-line-strong); }\n  [data-slot=\"block-window-title\"] {\n    flex: 1 1 0; min-width: 0; width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\n    text-align: left;\n    font-family: var(--font-mono, monospace); font-size: 12px; color: var(--k-muted);\n  }\n  [data-slot=\"block-window-body\"] { padding: clamp(14px, 2.6cqi, 28px); }\n  [data-slot=\"block-float\"] {\n    position: relative;\n    z-index: 2;\n    margin: 12px 0 14px;\n  }\n  @container (min-width: 760px) {\n    /* Over the window bar's empty right end, so it never hides a row. */\n    [data-slot=\"block-float\"] {\n      position: absolute;\n      top: clamp(12px, 2.4cqi, 36px);\n      right: clamp(12px, 2.4cqi, 36px);\n      margin: 0;\n      max-width: 320px;\n    }\n  }\n  [data-slot=\"block-float\"] > * {\n    border-radius: var(--k-radius);\n    background: var(--k-surface);\n    box-shadow: 0 0 0 1px var(--k-line), var(--k-shadow);\n  }\n\n  /* ── Logos ────────────────────────────────────────── */\n  [data-slot=\"block-logos\"] { display: grid; gap: 18px; }\n  [data-slot=\"block-logos-label\"] { margin: 0; font-size: 13px; color: var(--k-muted); }\n  [data-slot=\"block-logos\"] ul { display: flex; flex-wrap: wrap; align-items: center; gap: 14px clamp(24px, 4.5cqi, 56px); margin: 0; padding: 0; list-style: none; }\n  [data-slot=\"block-logos\"] li {\n    font-family: var(--k-display-font);\n    font-weight: var(--k-display-weight);\n    font-stretch: var(--k-display-stretch);\n    text-transform: var(--k-display-case);\n    font-size: clamp(18px, 2cqi, 24px);\n    letter-spacing: calc(var(--k-display-track) / 2);\n    color: var(--k-muted);\n    white-space: nowrap;\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    [data-slot=\"block-button\"], [data-slot=\"block-button-arrow\"] { transition: none; }\n    [data-slot=\"block-button\"]:active { translate: none; }\n    [data-slot=\"block-button\"]:hover [data-slot=\"block-button-arrow\"] { translate: none; }\n  }\n  @media print {\n    footer[data-slot=\"block\"] { display: none !important; }\n    [data-slot=\"block\"] { background: #fff; }\n  }\n}\n"},{"path":"ui/cta-block.css","type":"registry:file","target":"components/ui/cta-block.css","content":"/* cta-block.tsx's styles; it imports this file. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  [data-slot=\"block-dots\"] {\n    position: absolute; inset: 0; z-index: 0; pointer-events: none;\n    background-image: radial-gradient(var(--k-stage-dot) 1px, transparent 1.5px);\n    background-size: 22px 22px;\n    mask-image: linear-gradient(to bottom, #000, transparent 85%);\n  }\n\n  /* The closing band inverts its actions. */\n  [data-slot=\"cta-band\"] [data-slot=\"block-dots\"] { --k-stage-dot: rgb(255 255 255 / 14%); }\n  [data-slot=\"cta-band\"] [data-slot=\"block-button\"][data-kind=\"primary\"] { background: var(--k-bg); color: var(--k-ink); }\n  [data-slot=\"cta-band\"] [data-slot=\"block-button\"][data-kind=\"secondary\"] { background: transparent; color: inherit; box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 45%, transparent); }\n  @media (hover: hover) {\n    [data-slot=\"cta-band\"] [data-slot=\"block-button\"][data-kind=\"primary\"]:hover { background: color-mix(in srgb, var(--k-bg) 88%, var(--k-hi)); }\n    [data-slot=\"cta-band\"] [data-slot=\"block-button\"][data-kind=\"secondary\"]:hover { background: rgb(255 255 255 / 8%); box-shadow: inset 0 0 0 1px currentColor; }\n  }\n  [data-slot=\"cta-band\"] [data-slot=\"block-button\"]:focus-visible { outline-color: currentColor; }\n}\n"}],"categories":["free-marketing"],"meta":{"tier":"free","license":"MIT","family":"marketing","docs":"/docs/components/cta-block"}}