Files
shadcn-ui/apps/v4/app/globals.css
shadcn 18fcf0f766 feat: @shadcn/react (#11022)
* feat(@shadcn/react): add message-scroller package

Add the @shadcn/react headless primitives package with MessageScroller
scroll anchoring, streaming follow, history prepend, and jump-to-message
behavior. Includes geometry helpers, use-render utility, and unit,
browser, and perf tests.

* feat(registry): add chat components

Add MessageScroller, Message, Bubble, Attachment, and Marker registry
sources for base and radix, style variants, preview-03 chat blocks,
and registry index wiring.

* feat(v4): integrate chat components into docs site

Wire chat components into the v4 app with docs routes, example preview
pages, message part renderers, markdown support, registry build updates,
and supporting lib utilities.

* feat(examples): add chat component demos

Add base and radix example demos for MessageScroller, Message, Bubble,
Attachment, Marker, scroll-fade, and shimmer.

* docs: add chat component documentation

Add component and utility docs for the chat component set, update docs
navigation, and add the June 2026 chat components changelog entry.

* chore: regenerate registry JSON output

Rebuild public registry artifacts for all style variants with the new
chat components.

* chore(release): add @shadcn/react publish and CI pipeline

Add Changesets prerelease workflow, browser test job, RELEASING docs,
and monorepo wiring for publishing @shadcn/react independently from
the shadcn CLI.

* docs: fix display of component preview on mobile

* fix

* fix

* docs: add message scroller docs

* style: format

* fix
2026-06-26 21:19:31 +04:00

421 lines
12 KiB
CSS

@import "tailwindcss";
@import "tw-animate-css";
@import "shadcn/tailwind.css";
@import "./legacy-themes.css";
@source "../node_modules/streamdown/dist/*.js";
@custom-variant style-vega (&:where(.style-vega *));
@custom-variant style-nova (&:where(.style-nova *));
@custom-variant style-lyra (&:where(.style-lyra *));
@custom-variant style-maia (&:where(.style-maia *));
@custom-variant style-mira (&:where(.style-mira *));
@custom-variant style-luma (&:where(.style-luma *));
@custom-variant style-sera (&:where(.style-sera *));
@custom-variant style-rhea (&:where(.style-rhea *));
@custom-variant dark (&:is(.dark *));
@custom-variant fixed (&:is(.layout-fixed *));
@theme inline {
--breakpoint-3xl: 1600px;
--breakpoint-4xl: 2000px;
--font-sans: var(--font-sans);
--font-heading: var(--font-heading);
--font-mono: var(--font-mono);
--radius-sm: calc(var(--radius) * 0.6);
--radius-md: calc(var(--radius) * 0.8);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) * 1.4);
--radius-2xl: calc(var(--radius) * 1.8);
--radius-3xl: calc(var(--radius) * 2.2);
--radius-4xl: calc(var(--radius) * 2.6);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
--color-surface: var(--surface);
--color-surface-foreground: var(--surface-foreground);
--color-code: var(--code);
--color-code-foreground: var(--code-foreground);
--color-code-highlight: var(--code-highlight);
--color-code-number: var(--code-number);
--color-selection: var(--selection);
--color-selection-foreground: var(--selection-foreground);
}
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0% 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0% 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0% 0 0);
--primary: oklch(0% 0 0);
--primary-foreground: oklch(0.985 0 0);
--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: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--destructive-foreground: oklch(0.97 0.01 17);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: var(--color-blue-300);
--chart-2: var(--color-blue-500);
--chart-3: var(--color-blue-600);
--chart-4: var(--color-blue-700);
--chart-5: var(--color-blue-800);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0% 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);
--surface: oklch(0.98 0 0);
--surface-foreground: var(--foreground);
--code: var(--surface);
--code-foreground: var(--surface-foreground);
--code-highlight: oklch(0.96 0 0);
--code-number: oklch(0.56 0 0);
--selection: oklch(0% 0 0);
--selection-foreground: oklch(1 0 0);
}
.dark {
--background: oklch(0.145 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: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--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: oklch(0.371 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--destructive-foreground: oklch(0.58 0.22 27);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: var(--color-blue-300);
--chart-2: var(--color-blue-500);
--chart-3: var(--color-blue-600);
--chart-4: var(--color-blue-700);
--chart-5: var(--color-blue-800);
--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.439 0 0);
--surface: oklch(0.2 0 0);
--surface-foreground: oklch(0.708 0 0);
--code: var(--surface);
--code-foreground: var(--surface-foreground);
--code-highlight: oklch(0.27 0 0);
--code-number: oklch(0.72 0 0);
--selection: oklch(0.922 0 0);
--selection-foreground: oklch(0.205 0 0);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
::selection {
@apply bg-selection text-selection-foreground;
}
html {
@apply overscroll-y-none;
}
body {
font-synthesis-weight: none;
text-rendering: optimizeLegibility;
}
.cn-font-heading {
@apply font-heading;
}
[data-slot="layout"] {
@apply overscroll-none;
}
@supports (font: -apple-system-body) and (-webkit-appearance: none) {
[data-wrapper] {
@apply min-[1800px]:border-t;
}
}
a:active,
button:active {
@apply opacity-60 md:opacity-100;
}
[data-lang="ar"] {
font-family: var(--font-ar);
}
[data-lang="he"] {
font-family: var(--font-he);
}
}
@utility border-grid {
@apply border-border/50 dark:border-border;
}
@utility section-soft {
@apply bg-linear-to-b from-background to-surface/40 dark:bg-background 3xl:fixed:bg-none;
}
@utility theme-container {
@apply font-sans;
}
@utility container-wrapper {
@apply mx-auto w-full px-2 3xl:fixed:max-w-[calc(var(--breakpoint-2xl)+2rem)];
}
@utility container {
@apply mx-auto max-w-[1400px] px-4 3xl:max-w-screen-2xl lg:px-8;
}
@utility no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
@utility border-ghost {
@apply relative after:absolute after:inset-0 after:border after:border-border after:mix-blend-darken dark:after:mix-blend-lighten;
}
@utility step {
counter-increment: step;
&:before {
@apply mr-2 inline-flex size-6 items-center justify-center rounded-full border-background bg-muted text-center -indent-px font-mono text-sm font-medium md:absolute md:mt-[-4px] md:ml-[-50px] md:size-9 md:border-4;
content: counter(step);
}
}
@utility extend-touch-target {
@media (pointer: coarse) {
@apply relative touch-manipulation after:absolute after:-inset-2;
}
}
@layer components {
.steps {
&:first-child {
@apply !mt-0;
}
&:first-child > h3:first-child {
@apply !mt-0;
}
> h3 {
@apply !mt-8;
}
> h3 + p {
@apply !mt-2;
}
}
[data-rehype-pretty-code-figure] {
background-color: var(--color-code);
color: var(--color-code-foreground);
border-radius: var(--radius-xl);
border-width: 0px;
border-color: var(--border);
margin-top: calc(var(--spacing) * 6);
overflow: hidden;
font-size: var(--text-sm);
outline: none;
position: relative;
@apply -mx-1 md:-mx-1;
&:has([data-rehype-pretty-code-title]) [data-slot="copy-button"] {
top: calc(var(--spacing) * 1.5) !important;
}
}
[data-rehype-pretty-code-figure] code,
[data-rehype-pretty-code-figure] code span {
font-variant-ligatures: none;
font-feature-settings:
"liga" 0,
"calt" 0;
}
[data-rehype-pretty-code-title] {
border-bottom: color-mix(in oklab, var(--border) 30%, transparent);
border-bottom-width: 1px;
border-bottom-style: solid;
padding-block: calc(var(--spacing) * 2.5);
padding-inline: calc(var(--spacing) * 4);
font-size: var(--text-sm);
font-family: var(--font-mono);
color: var(--color-code-foreground);
}
[data-line-numbers] {
display: grid;
min-width: 100%;
white-space: pre;
border: 0;
background: transparent;
padding: 0;
counter-reset: line;
box-decoration-break: clone;
}
[data-line-numbers] [data-line]::before {
font-size: var(--text-sm);
counter-increment: line;
content: counter(line);
display: inline-block;
width: calc(var(--spacing) * 16);
padding-right: calc(var(--spacing) * 6);
text-align: right;
color: var(--color-code-number);
background-color: var(--color-code);
position: sticky;
left: 0;
}
[data-line-numbers] [data-highlighted-line][data-line]::before {
background-color: var(--color-code-highlight);
}
[data-line] {
padding-top: calc(var(--spacing) * 0.5);
padding-bottom: calc(var(--spacing) * 0.5);
min-height: calc(var(--spacing) * 1);
width: 100%;
display: inline-block;
}
/*
* ```text composition trees use box-drawing characters; per-line padding makes
* vertical connectors look broken. rehype-pretty-code sets `data-language` on
* `pre`/`code` (not `language-*` classes). It also sets `code { display: grid }`,
* which can add visible row separation — reset to a normal pre stack for text.
*/
[data-rehype-pretty-code-figure] pre[data-language="text"] code,
[data-rehype-pretty-code-figure] pre[data-language="plaintext"] code,
[data-slot="docs"] pre[data-language="text"] code,
[data-slot="docs"] pre[data-language="plaintext"] code {
display: block !important;
white-space: pre;
line-height: 0.95;
font-family:
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace;
font-variant-ligatures: none;
}
[data-rehype-pretty-code-figure] pre[data-language="text"] [data-line],
[data-rehype-pretty-code-figure] pre[data-language="plaintext"] [data-line],
[data-rehype-pretty-code-figure] code[data-language="text"] [data-line],
[data-rehype-pretty-code-figure] code[data-language="plaintext"] [data-line],
[data-slot="docs"] pre[data-language="text"] [data-line],
[data-slot="docs"] pre[data-language="plaintext"] [data-line] {
padding-top: 0;
padding-bottom: 0;
min-height: unset;
line-height: 0.95;
display: block;
}
[data-line] span {
color: var(--shiki-light);
@variant dark {
color: var(--shiki-dark) !important;
}
}
[data-highlighted-line],
[data-highlighted-chars] {
position: relative;
background-color: var(--color-code-highlight);
}
[data-highlighted-line] {
&:after {
position: absolute;
top: 0;
left: 0;
width: 2px;
height: 100%;
content: "";
background-color: color-mix(
in oklab,
var(--muted-foreground) 50%,
transparent
);
}
}
[data-highlighted-chars] {
border-radius: var(--radius-sm);
padding-inline: 0.3rem;
padding-block: 0.1rem;
font-family: var(--font-mono);
font-size: 0.8rem;
}
}
@layer components {
.dialog-ring {
@apply rounded-xl border-none bg-clip-padding shadow-2xl ring-4 ring-neutral-200/80 dark:bg-neutral-900 dark:ring-neutral-800;
}
}