Quote Highlight

Editorial pull quote with oversized glyph, expanding rule, and blurred fade-in.

Add to your project

Pick the way you like to build.

Let your AI assistant add it

Copy this prompt and paste it into the AI tool building your site.

# Integrate this UI component

Add this component to my project.

1. Install any missing dependencies.
2. Make sure Tailwind CSS is set up and scans the new file.
3. Prefer passing props over editing the component source — changing the component itself may break it.
4. Adjust colors, size, and layout via props or wrapper classes to match my project. You know my codebase better than this snippet does.

## Component source

```tsx
'use client';

import { motion } from 'framer-motion';

// ---------------------------------------------------------------------------
// Props
// ---------------------------------------------------------------------------
//
// quote      Pull quote text
// author     Attribution name
// role       Optional title / company
// avatar     Optional portrait URL
// align      left | center
// tone       light | dark
// className  Styles for the outer shell
//
type QuoteHighlightProps = {
  quote?: string;
  author?: string;
  role?: string;
  avatar?: string;
  align?: 'left' | 'center';
  tone?: 'light' | 'dark';
  className?: string;
};

export default function QuoteHighlight({
  quote = 'The quietest interfaces often carry the most conviction.',
  author = 'Elena Voss',
  role = 'Design Director, Lattice',
  avatar = 'https://assets.uniquel.io/components/stock/photo-1534528741775-53994a69daeb.jpg',
  align = 'left',
  tone = 'light',
  className = '',
}: QuoteHighlightProps) {
  const dark = tone === 'dark';
  const centered = align === 'center';

  const quoteMarkClass = [
    'pointer-events-none select-none font-serif text-6xl leading-none',
    dark ? 'text-white/15' : 'text-gray-900/10',
  ].join(' ');

  return (
    <figure
      className={[
        'relative max-w-xl',
        centered ? 'mx-auto text-center' : 'text-left',
        className,
      ]
        .filter(Boolean)
        .join(' ')}
    >
      <motion.span
        aria-hidden
        className={[quoteMarkClass, centered ? 'mx-auto block' : 'block'].join(
          ' '
        )}
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.5, ease: [0.22, 1, 0.36, 1] }}
      >
        “
      </motion.span>

      <motion.blockquote
        className={[
          '-mt-6 text-xl font-medium leading-relaxed tracking-tight md:text-2xl',
          dark ? 'text-white' : 'text-gray-900',
        ].join(' ')}
        initial={{ opacity: 0, y: 16, filter: 'blur(6px)' }}
        animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }}
        transition={{ duration: 0.65, delay: 0.1, ease: [0.22, 1, 0.36, 1] }}
      >
        {quote}
      </motion.blockquote>

      <motion.span
        aria-hidden
        className={[
          quoteMarkClass,
          centered ? 'mx-auto block text-center' : 'block text-right',
        ].join(' ')}
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1] }}
      >
        ”
      </motion.span>

      <motion.div
        className={[
          'mt-5 h-px origin-left',
          dark ? 'bg-white/25' : 'bg-gray-300',
          centered ? 'mx-auto' : '',
        ].join(' ')}
        style={{ width: centered ? '4rem' : '3rem' }}
        initial={{ scaleX: 0 }}
        animate={{ scaleX: 1 }}
        transition={{ duration: 0.55, delay: 0.35, ease: [0.22, 1, 0.36, 1] }}
      />

      <motion.figcaption
        className={[
          'mt-4 flex items-center gap-3',
          centered ? 'justify-center' : 'justify-start',
        ].join(' ')}
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        transition={{ duration: 0.45, delay: 0.45 }}
      >
        {avatar ? (
          <img
            src={avatar}
            alt=''
            className='h-8 w-8 rounded-full object-cover ring-2 ring-white shadow-xs'
          />
        ) : null}
        <div className={centered ? 'text-center' : 'text-left'}>
          <div
            className={[
              'text-sm font-medium tracking-wide',
              dark ? 'text-white' : 'text-gray-900',
            ].join(' ')}
          >
            {author}
          </div>
          {role ? (
            <div
              className={[
                'text-xs tracking-wide',
                dark ? 'text-white/55' : 'text-gray-500',
              ].join(' ')}
            >
              {role}
            </div>
          ) : null}
        </div>
      </motion.figcaption>
    </figure>
  );
}

```

Works with your AI tools

ClaudeClaude*
CodexCodex*
LovableLovable
Base44Base44
Figma MakeFigma Make
ReplitReplit*
CursorCursor*
v0v0

* Compatible with most projects that use the default React/Next.js framework.

Built With

ReactTailwind CSSFramer Motion

Props

PropTypeDescription
quotestringPull quote text
authorstringAttribution name
rolestringOptional title / company
avatarstringOptional portrait URL
align'left' | 'center'Text alignment within the block
tone'light' | 'dark'Light or dark ground
classNamestringStyles for the outer shell

More Content Components

A circular scroll progress indicator that doubles as a compact return-to-top control.

62%

A drawn-line progress indicator with spring-smoothed scroll tracking and a fading percentage.