000h-cojeev
uiaccordionsource: ok · hit
Accordion
Organizes related sections into expandable panels so readers can open the details they need.
npx shadcn add "https://000h.cojeev.com/r/accordion.json"free
Interaction
accordion
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lightui-primitives@radix-ui/react-accordion
Registry dependencies
https://cojeev.com/ui/r/cojeev.jsonhttps://cojeev.com/ui/r/icon.json
Files2 · source cached 10/9/2026, 12:47:18 AM
registry/cojeev/ui/accordion.tsx
"use client";
import * as React from "react";
import { useChoreography } from "@/lib/cojeev-motion/choreography";
import { useDisclosureHeight } from "@/lib/cojeev-motion/use-disclosure-height";
import { useMorph } from "@/lib/cojeev-motion/use-morph";
import { cva } from "class-variance-authority";
import { cn } from "@/lib/utils";
import { Icon } from "@/components/ui/icon";
import * as Primitive from "@radix-ui/react-accordion";
export const accordionVariants = cva("v-acc [display:grid] [gap:var(--s-2)]");
export type AccordionAppearance = "faq" | "chapters" | "editorial";
const AccordionAppearanceContext = React.createContext<
AccordionAppearance | undefined
>(undefined);
export type AccordionProps = React.ComponentProps<typeof Primitive.Root> & {
/** Optional structural treatment. Omit to preserve the original painted cards. */
appearance?: AccordionAppearance;
};
export function Accordion({ className, appearance, ...props }: AccordionProps) {
const { quiet } = useChoreography();
return (
<AccordionAppearanceContext.Provider value={appearance}>
<Primitive.Root
data-slot="accordion"
data-part="root"
data-appearance={appearance}
data-motion-quiet={quiet || undefined}
data-motion={quiet ? "off" : undefined}
className={cn(accordionVariants(), className)}
{...props}
/>
</AccordionAppearanceContext.Provider>
);
}
export type AccordionItemProps = React.ComponentProps<typeof Primitive.Item>;
export function AccordionItem({
className,
ref,
...props
}: AccordionItemProps) {
const appearance = React.useContext(AccordionAppearanceContext);
const morphRef = useMorph<HTMLDivElement>("cards", ref);
return (
<Primitive.Item
ref={morphRef}
data-slot="accordion-item"
data-part="item"
data-stable-hit=""
data-morph={appearance ? "fill" : undefined}
data-tier={appearance ? "card" : undefined}
data-r={appearance === "chapters" ? "12" : appearance ? "18" : undefined}
className={cn(
"overflow-hidden rounded-[var(--r-card)] bg-[var(--card)]",
className,
)}
{...props}
/>
);
}
export type AccordionTriggerProps = React.ComponentProps<
typeof Primitive.Trigger
> & { indicator?: React.ReactNode };
export function AccordionTrigger({
className,
children,
indicator,
...props
}: AccordionTriggerProps) {
return (
<Primitive.Header className="contents">
<Primitive.Trigger
data-slot="accordion-trigger"
data-part="trigger"
className={cn(
"flex w-full items-center text-left min-h-[60px] py-3 pl-3 pr-4 gap-3.5 rounded-[var(--r-card)] font-semibold text-[length:var(--fs-body)] leading-[1.3]",
className,
)}
{...props}
>
{props.asChild ? (
children
) : (
<>
{children}
{indicator ?? <AccordionIndicator />}
</>
)}
</Primitive.Trigger>
</Primitive.Header>
);
}
export type AccordionContentProps = React.ComponentProps<
typeof Primitive.Content
>;
export function AccordionContent({
className,
ref,
children,
...props
}: AccordionContentProps) {
const contentRef = React.useRef<HTMLDivElement>(null);
React.useImperativeHandle(ref, () => contentRef.current!);
useDisclosureHeight(contentRef, props.style?.animationName);
return (
<Primitive.Content
ref={contentRef}
data-slot="accordion-content"
data-part="content"
className={cn("v-acc__body", className)}
{...props}
>
<div data-slot="accordion-content-inner" data-disclosure-inner>
{children}
</div>
</Primitive.Content>
);
}
export type AccordionIndicatorProps = React.ComponentProps<"svg">;
export function AccordionIndicator({
className,
...props
}: AccordionIndicatorProps) {
const appearance = React.useContext(AccordionAppearanceContext);
return (
<Icon
name={appearance === "faq" ? "plus" : "chevron-down"}
feedback={false}
data-slot="accordion-indicator"
data-part="indicator"
aria-hidden="true"
viewBox="0 0 24 24"
className={cn("v-icon v-chev ml-auto", className)}
{...props}
/>
);
}
registry/cojeev/styles/accordion.css
@layer cojeev-states {
/* Cojeev authored subparts, state precedence, and irreducible shapes; scoped to this registry item. */
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"] {
background: var(--card);
border-radius: var(--r-card-sm);
overflow: hidden;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"] {
list-style: none;
display: flex;
align-items: center;
gap: var(--s-3);
min-height: 56px;
padding: var(--s-3) var(--s-4);
cursor: pointer;
font-weight: var(--fw-semibold);
font-size: var(--fs-body);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"]
.v-chev {
margin-left: auto;
transition: transform var(--t-element) var(--enter);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-item"][data-state="open"]
[data-slot="accordion-trigger"]
.v-chev {
transform: rotate(180deg);
}
.v-acc__body:where([data-slot="accordion"], [data-slot^="accordion-"]) {
padding: 0 var(--s-4) var(--s-4);
color: var(--muted-foreground);
font-size: var(--fs-body);
line-height: var(--lh-body);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
) {
interpolate-size: allow-keywords;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"] {
background: var(--card);
border-radius: var(--r-card);
overflow: hidden;
box-shadow: inset 0 0 0 1px transparent;
transition:
background var(--t-element) var(--enter),
box-shadow var(--t-element) var(--enter);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"] {
background: var(--v-canvas);
box-shadow: inset 0 0 0 1px
color-mix(in oklab, var(--v-edge) 70%, var(--v-border));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"] {
min-height: 60px;
padding: var(--s-3) var(--s-4) var(--s-3) var(--s-3);
gap: var(--s-4);
font-weight: var(--fw-semibold);
font-size: var(--fs-body);
line-height: 1.3;
border-radius: var(--r-card);
transition: background var(--t-micro);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:not([data-state="open"])
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--card) 90%, var(--v-ink));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--v-canvas) 94%, var(--v-ink));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"]:focus-visible {
outline: 2px solid var(--ring);
outline-offset: -3px;
border-radius: var(--r-card);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"]
> .v-icon:first-child {
width: 36px;
height: 36px;
padding: var(--s-2);
border-radius: 50%;
background: var(--v-canvas);
color: var(--v-text);
box-shadow: inset 0 0 0 1px var(--v-border);
transition:
background var(--t-element) var(--enter),
box-shadow var(--t-element);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]
> h3
> [data-slot="accordion-trigger"]
> .v-icon:first-child {
background: var(--v-pink);
box-shadow: none;
color: var(--v-on-accent);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"]
.v-chev {
width: 18px;
height: 18px;
color: var(--v-text-2);
stroke-width: 2;
transition:
transform var(--t-max) var(--enter),
color var(--t-micro);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]
> h3
> [data-slot="accordion-trigger"]
.v-chev {
color: var(--v-text);
}
.v-acc__body:where([data-slot="accordion"], [data-slot^="accordion-"]) {
padding: 0 var(--s-4) var(--s-5) 62px;
color: var(--v-text-2);
font-size: var(--fs-body);
line-height: var(--lh-body);
max-width: 60ch;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]
> .v-acc__body {
animation: none;
}
@media (max-width: 640px) {
.v-acc__body:where([data-slot="accordion"], [data-slot^="accordion-"]) {
padding-left: var(--s-4);
}
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"] {
position: relative;
border-radius: var(--r-card);
background: var(--card);
box-shadow: none;
overflow: hidden;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"] {
box-shadow: none;
color: var(--v-on-accent);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]::after {
content: "";
position: absolute;
right: -8%;
top: -30%;
width: 46%;
aspect-ratio: 1;
-webkit-mask: var(--wm-m) center/contain no-repeat;
mask: var(--wm-m) center/contain no-repeat;
opacity: 0;
transform: translate(12px, -12px) rotate(-8deg) scale(0.9);
transition:
opacity var(--t-max) var(--enter),
transform var(--t-max) var(--enter);
pointer-events: none;
z-index: 0;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]::after {
opacity: 0.9;
transform: none;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 1):not(
[class*=" -"]
)[data-state="open"],
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-pink[data-state="open"] {
background: var(--v-pink);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 1):not([class*=" -"])::after,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-pink::after {
background: var(--v-pink-deep);
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 90C22 68 6 52 6 33A20 20 0 0 1 50 21A20 20 0 0 1 94 33C94 52 78 68 50 90Z'/%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 90C22 68 6 52 6 33A20 20 0 0 1 50 21A20 20 0 0 1 94 33C94 52 78 68 50 90Z'/%3E%3C/svg%3E");
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 1):not([class*=" -"]):not(
[data-state="open"]
)
> h3
> [data-slot="accordion-trigger"]:hover,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-pink:not([data-state="open"])
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--card) 88%, var(--v-pink));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 1):not(
[class*=" -"]
)[data-state="open"]
> h3
> [data-slot="accordion-trigger"]:hover,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-pink[data-state="open"]
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--v-pink) 92%, var(--ink-fixed));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 2):not(
[class*=" -"]
)[data-state="open"],
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-yellow[data-state="open"] {
background: var(--v-yellow);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 2):not([class*=" -"])::after,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-yellow::after {
background: var(--v-yellow-deep);
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2l12 30 30 12-30 12-12 30-12-30-30-12 30-12z'/%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2l12 30 30 12-30 12-12 30-12-30-30-12 30-12z'/%3E%3C/svg%3E");
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 2):not([class*=" -"]):not(
[data-state="open"]
)
> h3
> [data-slot="accordion-trigger"]:hover,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-yellow:not([data-state="open"])
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--card) 88%, var(--v-yellow));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 2):not(
[class*=" -"]
)[data-state="open"]
> h3
> [data-slot="accordion-trigger"]:hover,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-yellow[data-state="open"]
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--v-yellow) 92%, var(--ink-fixed));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 3):not(
[class*=" -"]
)[data-state="open"],
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-blue[data-state="open"] {
background: var(--v-blue);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 3):not([class*=" -"])::after,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-blue::after {
background: var(--v-blue-deep);
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='24' r='20'/%3E%3Ccircle cx='76' cy='50' r='20'/%3E%3Ccircle cx='50' cy='76' r='20'/%3E%3Ccircle cx='24' cy='50' r='20'/%3E%3Ccircle cx='50' cy='50' r='22'/%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='24' r='20'/%3E%3Ccircle cx='76' cy='50' r='20'/%3E%3Ccircle cx='50' cy='76' r='20'/%3E%3Ccircle cx='24' cy='50' r='20'/%3E%3Ccircle cx='50' cy='50' r='22'/%3E%3C/svg%3E");
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 3):not([class*=" -"]):not(
[data-state="open"]
)
> h3
> [data-slot="accordion-trigger"]:hover,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-blue:not([data-state="open"])
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--card) 88%, var(--v-blue));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n + 3):not(
[class*=" -"]
)[data-state="open"]
> h3
> [data-slot="accordion-trigger"]:hover,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-blue[data-state="open"]
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--v-blue) 92%, var(--ink-fixed));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n):not(
[class*=" -"]
)[data-state="open"],
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-olive[data-state="open"] {
background: var(--v-olive);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n):not([class*=" -"])::after,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-olive::after {
background: var(--v-olive-deep);
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M60 5A45 45 0 1 0 60 95A50 50 0 0 1 60 5Z'/%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M60 5A45 45 0 1 0 60 95A50 50 0 0 1 60 5Z'/%3E%3C/svg%3E");
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n):not([class*=" -"]):not(
[data-state="open"]
)
> h3
> [data-slot="accordion-trigger"]:hover,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-olive:not([data-state="open"])
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--card) 88%, var(--v-olive));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:nth-of-type(4n):not(
[class*=" -"]
)[data-state="open"]
> h3
> [data-slot="accordion-trigger"]:hover,
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"].-olive[data-state="open"]
> h3
> [data-slot="accordion-trigger"]:hover {
background: color-mix(in oklab, var(--v-olive) 92%, var(--ink-fixed));
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"] {
position: relative;
z-index: 1;
min-height: 64px;
padding: var(--s-3) var(--s-4) var(--s-3) var(--s-3);
gap: var(--s-4);
border-radius: var(--r-card);
font-size: var(--fs-body);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"]
> .v-icon:first-child {
position: relative;
width: 40px;
height: 40px;
padding: var(--s-3);
border-radius: var(--r-card-sm) var(--r-card-sm) var(--r-card-sm) var(--r-xs);
background: var(--v-paper);
box-shadow: none;
color: var(--v-on-accent);
transition:
background var(--t-max) var(--enter),
border-radius var(--t-max) var(--enter),
color var(--t-micro);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]
> h3
> [data-slot="accordion-trigger"]
> .v-icon:first-child {
background: var(--v-ink);
color: var(--v-on-ink);
border-radius: 50%;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"]
> .v-icon:first-child::after {
content: none;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"]
.v-chev {
width: 28px;
height: 28px;
padding: var(--s-2);
border-radius: 50%;
background: var(--v-canvas);
color: var(--v-text);
box-shadow: inset 0 0 0 1px var(--v-border);
stroke-width: 2.2;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]
> h3
> [data-slot="accordion-trigger"]
.v-chev {
background: var(--ink-fixed);
color: var(--v-paper);
box-shadow: none;
transform: rotate(180deg);
}
.v-acc__body:where([data-slot="accordion"], [data-slot^="accordion-"]) {
position: relative;
z-index: 1;
padding: 2px var(--s-5) var(--s-5) 66px;
color: var(--v-on-accent);
font-size: var(--fs-body);
line-height: 1.5;
max-width: 56ch;
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]
> .v-acc__body {
color: var(--v-on-accent);
}
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
[data-slot="accordion-trigger"]:focus-visible {
outline: 2px solid var(--ring);
outline-offset: -3px;
}
@media (max-width: 640px) {
.v-acc__body:where([data-slot="accordion"], [data-slot^="accordion-"]) {
padding-left: var(--s-5);
}
}
:root[data-mode="dark"]
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"],
:root[data-mode="dark"]
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]
[data-slot="accordion-trigger"],
:root[data-mode="dark"]
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"][data-state="open"]
> .v-acc__body {
color: var(--v-on-accent);
}
:root[data-mode="dark"]
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:not([data-state="open"])
[data-slot="accordion-trigger"] {
color: var(--v-text);
}
:root[data-mode="dark"]
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:not([data-state="open"])
[data-slot="accordion-trigger"]
> .v-icon:first-child {
background: var(--v-beige-2);
color: var(--v-text);
}
:root[data-mode="dark"]
.v-acc:where(:not([data-appearance])):where(
[data-slot="accordion"],
[data-slot^="accordion-"]
)
> [data-slot="accordion-item"]:not([data-state="open"])
[data-slot="accordion-trigger"]
.v-chev {
background: var(--v-beige-2);
color: var(--v-text);
box-shadow: inset 0 0 0 1px var(--v-border);
}
@keyframes v-acc-in {
from {
opacity: 0;
transform: translateY(-4px);
}
}
@media (prefers-reduced-motion: reduce) {
[data-slot="accordion"],
[data-slot^="accordion-"],
[data-slot="accordion"]::before,
[data-slot="accordion"]::after,
[data-slot^="accordion-"]::before,
[data-slot^="accordion-"]::after {
animation-duration: 0s;
animation-iteration-count: 1;
transition-duration: 0s;
scroll-behavior: auto;
}
}
/* Radix's heading keeps native summary geometry without adding a layout box. */
[data-slot="accordion-item"] > h3 > [data-slot="accordion-trigger"],
[data-slot="accordion-item"] > h3 > [data-slot="accordion-trigger"] {
width: 100%;
}
[data-slot="accordion-item"] > h3 {
display: contents;
}
/* Height has one interruptible Motion owner. This nonvisual exit lets Radix
retain the content until collapse ends; hidden children are inert immediately. */
.v-acc [data-slot="accordion-content"] {
padding: 0;
overflow: hidden;
animation: none;
}
.v-acc [data-slot="accordion-content-inner"] {
padding: 2px var(--s-5) var(--s-5) 66px;
}
.v-acc [data-slot="accordion-content"][data-state="closed"]:not([hidden]) {
display: block;
animation: v-acc-retain var(--disclosure-exit-duration, 220ms) linear;
}
@keyframes v-acc-retain {
from {
visibility: visible;
}
to {
visibility: visible;
}
}
@media (max-width: 600px) {
.v-acc [data-slot="accordion-content-inner"] {
padding-inline: var(--s-5);
}
}
@media (prefers-reduced-motion: reduce) {
.v-acc [data-slot="accordion-content"][data-state="closed"] {
animation-duration: 0s;
}
}
/* Optional authored compositions. Legacy painted-card defaults above remain intact. */
.v-acc[data-appearance] {
width: 100%;
min-width: 0;
color: var(--v-text);
gap: var(--s-3);
}
.v-acc[data-appearance] > [data-slot="accordion-item"] {
--acc-accent: var(--v-pink);
--acc-companion: var(--v-yellow);
--mfill: var(--card);
position: relative;
min-width: 0;
border-radius: var(--r-card);
background: var(--mfill);
color: var(--v-text);
overflow: visible;
isolation: isolate;
}
.v-acc[data-appearance] > [data-slot="accordion-item"]:nth-of-type(3n + 2) {
--acc-accent: var(--v-blue);
--acc-companion: var(--v-pink);
}
.v-acc[data-appearance] > [data-slot="accordion-item"]:nth-of-type(3n) {
--acc-accent: var(--v-yellow);
--acc-companion: var(--v-olive);
}
/* Keep the authored CSS fallback, but let the mounted contour own visible paint.
Its hook briefly suspends this selector while sampling state/theme colours. */
:root
.v-acc[data-appearance]
> [data-slot="accordion-item"]:has(> svg.v-morph) {
background: transparent;
box-shadow: none;
}
.v-acc[data-appearance] [data-slot="accordion-trigger"] {
display: flex;
align-items: center;
gap: var(--s-4);
min-height: 76px;
padding: var(--s-5) var(--s-6);
border-radius: inherit;
background: transparent;
color: inherit;
text-align: start;
cursor: pointer;
}
.v-acc[data-appearance] [data-slot="accordion-trigger"]:focus-visible {
outline: 2px solid var(--ring);
outline-offset: -3px;
}
.v-acc[data-appearance] [data-slot="accordion-trigger"]:disabled {
color: var(--v-disabled-ink);
cursor: not-allowed;
}
.v-acc[data-appearance] [data-slot="accordion-indicator"] {
flex: none;
width: 36px;
height: 36px;
padding: var(--s-2);
margin-inline-start: auto;
color: inherit;
pointer-events: none;
border: 1px solid currentColor;
border-radius: 50%;
transition:
transform var(--t-element) var(--enter),
border-radius var(--t-element) var(--enter);
}
.v-acc[data-appearance]
[data-slot="accordion-trigger"][data-state="open"]
[data-slot="accordion-indicator"] {
transform: rotate(180deg);
border-radius: 38% 48% 40% 46%;
}
.v-acc[data-appearance] [data-slot="accordion-content"] {
max-width: none;
color: var(--v-text-2);
}
.v-acc[data-appearance] [data-slot="accordion-content-inner"] {
padding: 0 76px var(--s-7) var(--s-6);
}
.v-acc__summary {
display: grid;
gap: var(--s-1);
min-width: 0;
line-height: 1.35;
text-wrap: balance;
}
.v-acc__summary small {
font-size: var(--fs-small);
font-weight: var(--fw-regular);
color: inherit;
opacity: 0.8;
}
.v-acc__detail {
display: grid;
gap: var(--s-3);
min-width: 0;
align-content: center;
}
.v-acc__detail p {
margin: 0;
font-size: var(--fs-control);
line-height: 1.7;
max-width: 60ch;
}
.v-acc__eyebrow {
font-size: var(--fs-meta);
color: inherit;
font-weight: var(--fw-medium);
}
.v-acc[data-appearance="faq"] {
gap: var(--s-3);
}
/* A resting question carries a trace of its own accent, so the list separates
without a rule between items. The open accent below still wins. */
.v-acc[data-appearance="faq"] > [data-slot="accordion-item"] {
--mfill: color-mix(in oklab, var(--card) 93%, var(--acc-accent));
background: var(--mfill);
}
.v-acc[data-appearance="faq"]
> [data-slot="accordion-item"][data-state="open"] {
--mfill: var(--acc-accent);
background: var(--acc-accent);
color: var(--v-on-accent);
}
.v-acc[data-appearance="faq"]
> [data-slot="accordion-item"]:not([data-state="open"]):has(
[data-slot="accordion-trigger"]:hover:not(:disabled)
) {
--mfill: color-mix(in oklab, var(--card) 88%, var(--acc-accent));
background: color-mix(in oklab, var(--card) 88%, var(--acc-accent));
}
.v-acc[data-appearance="faq"] [data-slot="accordion-content"] {
color: inherit;
}
.v-acc[data-appearance="faq"]
[data-state="open"]
[data-slot="accordion-indicator"] {
transform: none;
}
.v-acc[data-appearance="faq"]
[data-slot="accordion-indicator"]
[data-icon-part="1"] {
transform-origin: 12px 12px;
transition: transform var(--t-element) var(--enter);
}
.v-acc[data-appearance="faq"]
[data-state="open"]
[data-slot="accordion-indicator"]
[data-icon-part="1"] {
transform: scaleY(0);
}
.v-acc[data-appearance="chapters"] {
/* One reading column: the trigger inset, the numbered spine and the answer
indent are all derived from these three measurements. */
--acc-inset: 16px;
--acc-index: 42px;
--acc-gap: 20px;
padding: var(--s-3);
gap: var(--s-1);
border-radius: var(--r-card);
background: var(--v-beige-2);
box-shadow: 0 3px 0 var(--v-border);
}
.v-acc[data-appearance="chapters"] > [data-slot="accordion-item"] {
--mfill: var(--v-beige-2);
background: var(--v-beige-2);
border-radius: var(--r-md);
}
.v-acc[data-appearance="chapters"]
> [data-slot="accordion-item"][data-state="open"] {
--mfill: var(--v-canvas);
background: var(--v-canvas);
}
.v-acc[data-appearance="chapters"] [data-slot="accordion-trigger"] {
padding: var(--s-5) var(--acc-inset);
gap: var(--acc-gap);
}
.v-acc__index {
flex: none;
font-variant-numeric: tabular-nums;
font-size: var(--fs-meta);
font-weight: var(--fw-medium);
color: var(--v-text-2);
}
.v-acc[data-appearance="chapters"] .v-acc__index {
display: grid;
place-items: center;
width: var(--acc-index);
height: 48px;
font-family: var(--font-display);
font-size: var(--fs-title);
background: var(--acc-accent);
color: var(--v-on-accent);
border-radius: var(--r-sm) var(--r-sm) var(--r-card) var(--r-sm);
transition: border-radius var(--t-element) var(--enter);
}
.v-acc[data-appearance="chapters"] [data-state="open"] > h3 .v-acc__index {
border-radius: 42% 46% 40% 48%;
}
.v-acc[data-appearance="chapters"] [data-slot="accordion-content-inner"] {
/* Spine through the centre of the number; answer on the summary's own start. */
margin-inline-start: calc(var(--acc-inset) + var(--acc-index) / 2);
padding: 0 var(--s-6) var(--s-7) calc(var(--acc-index) / 2 + var(--acc-gap) - 1px);
border-inline-start: 1px dashed var(--v-border);
}
.v-acc[data-appearance="chapters"] [data-slot="accordion-indicator"] {
border-color: transparent;
padding: var(--s-2);
width: 28px;
height: 28px;
}
.v-acc[data-appearance="editorial"] {
gap: var(--s-3);
}
.v-acc[data-appearance="editorial"] > [data-slot="accordion-item"] {
background: var(--card);
border-radius: var(--r-card);
}
.v-acc[data-appearance="editorial"]
> [data-slot="accordion-item"][data-state="open"] {
--mfill: var(--acc-accent);
background: var(--acc-accent);
color: var(--v-on-accent);
}
.v-acc[data-appearance="editorial"]
> [data-state="open"]
[data-slot="accordion-content"] {
color: inherit;
}
.v-acc[data-appearance="editorial"] [data-slot="accordion-trigger"] {
padding: var(--s-6);
gap: var(--s-6);
}
.v-acc[data-appearance="editorial"] .v-acc__index {
font-family: var(--font-display);
font-size: 36px;
font-weight: var(--fw-regular);
letter-spacing: -0.03em;
color: inherit;
}
.v-acc[data-appearance="editorial"] .v-acc__summary > span {
font-family: var(--font-display);
font-size: clamp(20px, 2.5cqi, 26px);
font-weight: var(--fw-medium);
}
.v-acc[data-appearance="editorial"] [data-slot="accordion-content-inner"] {
/* A supporting motif accompanies the answer; it never competes for width. */
--acc-art: 96px;
display: grid;
grid-template-columns: var(--acc-art) minmax(0, 1fr);
align-items: start;
gap: var(--s-7);
padding: 0 var(--s-7) var(--s-8);
}
.v-acc__preview {
position: relative;
display: grid;
place-items: center;
grid-template: var(--acc-art, 150px) auto / minmax(0, 1fr);
color: var(--v-on-accent);
pointer-events: none;
}
.v-acc__preview
:is(.v-acc__preview-shape, .v-acc__preview-echo, .v-acc__preview-letter) {
grid-area: 1 / 1;
}
.v-acc__preview-shape,
.v-acc__preview-echo {
width: min(100%, var(--acc-art, 150px));
height: var(--acc-art, 150px);
color: var(--acc-companion);
transform: rotate(-12deg);
transition: transform var(--t-element) var(--enter);
}
.v-acc__preview-echo {
transform: translate(
calc(var(--acc-art, 150px) * 0.047),
calc(var(--acc-art, 150px) * -0.027)
)
rotate(8deg);
color: currentColor;
opacity: 0.45;
}
.v-acc__preview-letter {
z-index: 1;
font-family: var(--font-display);
font-size: calc(var(--acc-art, 150px) * 0.32);
letter-spacing: -0.03em;
}
.v-acc__preview-letter > .v-icon {
width: calc(var(--acc-art, 150px) * 0.27);
height: calc(var(--acc-art, 150px) * 0.27);
stroke-width: 1.5;
}
.v-acc__preview-caption {
grid-area: 2 / 1;
font-size: var(--fs-caps);
text-align: center;
line-height: 1.4;
}
.v-acc[data-appearance="editorial"]
[data-slot="accordion-item"]:hover
.v-acc__preview-shape {
transform: rotate(4deg);
}
.v-acc[data-motion-quiet]
:is(
[data-slot="accordion-indicator"],
[data-icon-part],
.v-acc__preview-shape,
.v-acc__preview-echo,
.v-acc__index
) {
transition: none;
}
.v-acc[data-motion-quiet]
[data-slot="accordion-item"]:hover
.v-acc__preview-shape {
transform: rotate(-12deg);
}
@media (max-width: 600px) {
.v-acc[data-appearance] [data-slot="accordion-trigger"] {
padding: var(--s-5);
gap: var(--s-3);
}
.v-acc[data-appearance] [data-slot="accordion-content-inner"] {
padding: 0 var(--s-5) var(--s-6);
}
.v-acc[data-appearance="editorial"] [data-slot="accordion-content-inner"] {
--acc-art: 56px;
gap: var(--s-4);
padding: 0 var(--s-5) var(--s-5);
}
.v-acc[data-appearance="editorial"] [data-slot="accordion-trigger"] {
padding: var(--s-5);
gap: var(--s-3);
}
.v-acc[data-appearance="editorial"] .v-acc__index {
font-size: var(--fs-section);
}
.v-acc__preview-caption {
display: none;
}
.v-acc[data-appearance="chapters"] {
--acc-inset: 18px;
--acc-index: 32px;
--acc-gap: 12px;
padding: var(--s-2);
}
.v-acc[data-appearance="chapters"] .v-acc__index {
height: 40px;
font-size: var(--fs-lead);
}
.v-acc[data-appearance="chapters"] [data-slot="accordion-trigger"] {
padding: var(--s-5) var(--acc-inset);
gap: var(--acc-gap);
}
.v-acc[data-appearance="chapters"] [data-slot="accordion-content-inner"] {
padding-inline-start: calc(var(--acc-index) / 2 + var(--acc-gap) - 1px);
}
}
}