# Theming

Match the viewer to your design with CSS variables, dark and automatic presets, and state-based styling.

## Set CSS variables

Every color, size and spacing value in the viewer is a CSS variable. Set them on the viewer (`style` or `className`) or on any ancestor, so a whole section of your app can share one theme.

**Demo: A custom theme from a few variables**

```tsx
import { PdfViewer } from '@kingtech/react-pdf-viewer';
import type { CSSProperties } from 'react';

const theme = {
  '--rpv-toolbar-bg': '#0f172a',
  '--rpv-toolbar-radius': '14px',
  '--rpv-accent': '#6366f1',
  '--rpv-page-radius': '10px',
  '--rpv-page-border': '1px solid #c7d2fe',
  '--rpv-page-shadow': '0 16px 40px rgba(79, 70, 229, 0.18)',
} as CSSProperties;

export default function Demo() {
  return (
    <div style={theme}>
      <PdfViewer source="/samples/letter-3pages.pdf" pageInput />
    </div>
  );
}
```

The most useful variables:

| Variable                                                                             | Controls                                        |
| ------------------------------------------------------------------------------------ | ----------------------------------------------- |
| `--rpv-toolbar-bg`, `--rpv-toolbar-fg`                                               | Toolbar colors                                  |
| `--rpv-accent`                                                                       | Focus outlines, the current thumbnail, progress |
| `--rpv-toolbar-radius`, `--rpv-button-size`, `--rpv-icon-size`                       | Toolbar shape and sizes                         |
| `--rpv-page-bg`, `--rpv-page-border`, `--rpv-page-radius`, `--rpv-page-shadow`       | The page frame                                  |
| `--rpv-viewport-max-width`, `--rpv-viewport-min-height`, `--rpv-viewport-max-height` | The document area                               |
| `--rpv-font-family`                                                                  | Viewer text (inherits by default)               |

All 54 variables, with their default values, are generated from the stylesheet in the [CSS variables reference](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/css-variables/).

## Dark mode

`className="rpv-theme-dark"` applies the dark preset. `className="rpv-theme-auto"` applies it only when the operating system prefers a dark color scheme.

**Demo: The dark preset**

```tsx
import { PdfViewer } from '@kingtech/react-pdf-viewer';

export default function Demo() {
  return (
    <div style={{ padding: 16, background: '#121212', borderRadius: 12 }}>
      <PdfViewer source="/samples/multipage.pdf" className="rpv-theme-dark" search thumbnails />
    </div>
  );
}
```

The values each preset sets are in the [`rpv-theme-dark`](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/rpv-theme-dark/) and [`rpv-theme-auto`](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/rpv-theme-auto/) references. If your app has its own dark-mode switch, toggle the class from your theme state, or set the variables yourself inside your dark-mode selector.

## State-based styling

The root element (`.rpv-root`) reflects the viewer's state as attributes, so CSS can react to it without JavaScript:

| Attribute           | Present or value                      |
| ------------------- | ------------------------------------- |
| `data-status`       | `idle`, `loading`, `ready` or `error` |
| `data-layout`       | `single` or `continuous`              |
| `data-compact`      | below `compactBreakpoint`             |
| `data-fullscreen`   | in fullscreen, in any mode            |
| `data-presentation` | `layout`, `native` or `overlay`       |
| `data-zoomed`       | while zoomed above `defaultScale`     |

**Demo: A red toolbar while in the error state**

```tsx
import { PdfViewer } from '@kingtech/react-pdf-viewer';

const css = `
  .status-aware[data-status='error'] {
    --rpv-toolbar-bg: #991b1b;
  }
  .status-aware[data-status='loading'] {
    --rpv-toolbar-bg: #475569;
  }
`;

export default function Demo() {
  return (
    <>
      <style>{css}</style>
      <PdfViewer className="status-aware" source="/samples/does-not-exist.pdf" />
    </>
  );
}
```

The attributes are generated from the component source in the [`PdfViewer` reference](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/pdf-viewer/#css-classes).

## Fonts

The viewer inherits your page's font. Set `--rpv-font-family` to use a different one for viewer text. Page content always uses the fonts embedded in the PDF.

## Related

- [How to customize](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/customization/)
- [Recipes](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/customization/recipes/)
- [Accessibility](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/guides/accessibility/): keep contrast when you change colors
- [CSS variables reference](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/css-variables/)
