---
title: V7 Custom CSS Migration Guide
---

<div class='sidebar-layout'>
<div class='sidebar-layout__sidebar sidebar-layout__sidebar--bordered' markdown='1'>

<a href="#" onclick={(e) => { e.preventDefault(); window.scrollTo({top:0,behavior:'smooth'}) }}>Back to top</a>

## Table of Contents

- [Before You Begin](#before-you-begin)
- [Top-Level](#top-level)
- [Toolbar](#toolbar)
- [Events (General)](#events-general)
  - [Foreground Events](#foreground-normal-events)
  - [Background Events](#background-events)
  - [Horizontal Events](#horizontal-events-aka-row-events)
- [Resources (General)](#resources-general)
- [Popover & More-Link](#popover--more-link)
- Calendar Views
  - [General](#calendar-views-general)
  - [DayGrid View](#daygrid-view)
    - [Table Structure](#table-structure)
    - [Day Header Cells](#day-header-cells)
    - [Day Body Cells](#day-body-cells)
    - [More-Link](#daygrid-more-link)
    - [Week Number](#daygrid-week-number)
    - [Events](#daygrid-events)
    - [No Replacement](#no-replacement)
  - [Resource DayGrid View](#resource-daygrid-view)
  - [TimeGrid View](#timegrid-view)
    - [Table Structure](#table-structure-1)
    - [All-Day Divider](#all-day-divider)
    - [Time Axis](#time-axis)
    - [Time Slots](#time-slots)
    - [Day Lane](#day-lane)
    - [Now-Indicator](#now-indicator)
    - [More-Link](#more-link-1)
    - [Events](#events)
    - [No Replacement](#no-replacement-1)
  - [Resource TimeGrid View](#resource-timegrid-view)
  - [List View](#list-view)
    - [Day Header](#list-day-header)
    - [Events](#events-1)
    - [No-events](#no-events-screen)
    - [No Replacement](#no-replacement-2)
  - [MultiMonth View](#multimonth-view)
  - [Timeline View](#timeline-view)
    - [View States](#view-states-1)
    - [Table Structure](#table-structure-2)
    - [Time Slots](#time-slots-1)
    - [Now Indicator](#now-indicator-1)
    - [More-Link](#more-link-2)
    - [Events](#events-2)
    - [No Replacement](#no-replacement-3)
  - [Resource Timeline View](#resource-timeline-view)

</div>
<div class='sidebar-layout__main changelog' markdown='1'>

If you customized the look of your calendar by targeting the built-in `fc-*` class-names, this document will help you migrate to the future-proof settings-based approach.


## Before You Begin

### Start from Scratch?

If you have a lot of custom CSS, rewriting it will be a lot of work. Just look at the length of this guide! As a first step, see if your design more closely matches some of the themes on [themes.fullcalendar.io](https://themes.fullcalendar.io/), moreso than the "Classic" theme from v6. If that's the case, it might be worth writing your styles from scratch, [forking one of the newer themes](custom-themes). The [index of styling hooks](render-hook-index) will be a valuable reference.

### clsx

Many migrations in this document show the merging of multiple class-names with the [clsx utility](https://www.npmjs.com/package/clsx). It's especially important for conditional class-names. Installation:

```bash
npm install --save clsx
```

In the JS:

```js
import clsx from 'clsx'

const bool = true
clsx('you', 'can', 'merge', bool && 'okay?') // "you can merge okay?"
```

### Tailwind

In this document, all migrations start as vanilla CSS and end as vanilla CSS. Most of the migration is simply wiring up existing CSS to newly exposed settings. If you prefer to use Tailwind, you can bypass the CSS altogether. Example:

<div class='diff-code-2col' markdown='1'>
<div>

```diff
/* instead of vanilla CSS... */
- .fc-toolbar {
+ .my-toolbar {
    background: red;
  }

// in JS settings
+ toolbarClass: 'my-toolbar'
```

</div>
<div>

```diff
// ...just use Tailwind
+ toolbarClass: 'bg-red-500'
```

</div>
</div>


## Top-Level

The `.fc` className was on the root of each calendar and the selector was often used to increase precedence. It no longer exists.

```diff
- .fc .some-selector { /* custom CSS */ }
+ .some-selector { /* custom CSS */ }
```

Direction:

```diff
- .fc-direction-ltr { /* LRT CSS */ }
- .fc-direction-rtl { /* RTL CSS */ }
+ :root { /* general CSS */ }
+ [dir=rtl] { /* RTL overrides */ }
```

Media (print or screen):

```diff
- .fc-media-print { /* print-only CSS */ }
- .fc-media-screen { /* screen-only CSS */ }
+ @media print { /* print-only CSS */ }
+ @media screen { /* screen-only CSS */}
```

Page background color (for **Classic Theme** only):

```diff
:root {
  /* page background color */
- --fc-page-bg-color: grey;
+ --fc-classic-background: grey;
}
```

Removing the outer border was difficult before. It required messy CSS overrides. There are now settings for this:

```diff
- .fc-scrollgrid,
- .fc-scrollgrid-section > *,
- .fc-list,
- .fc-multimonth {
-   border: none !important;
- }

// in JS settings
+ borderless: true // ALSO: borderlessTop, borderlessBottom, borderlessX
```

Theme-system specific class-names have been removed:

```diff
- .fc-theme-standard {}
- .fc-theme-bootstrap {}
- .fc-theme-bootstrap5 {}
- .fc-theme-bootstrap5-shaded {}
```


## Toolbar

Header toolbar specifically:

```diff
- .fc-header-toolbar {
+ .my-header-toolbar {
    /* custom css */
  }

// in JS settings
+ headerToolbarClass: 'my-header-toolbar'
```

Footer toolbar specifically:

```diff
- .fc-footer-toolbar {
+ .my-footer-toolbar {
    /* custom css */
  }

// in JS settings
+ footerToolbarClass: 'my-footer-toolbar'
```

Any toolbar:

```diff
- .fc-toolbar {
+ .my-toolbar {
    /* custom css */
  }

// in JS settings
+ toolbarClass: 'my-toolbar'
```

### Toolbar Section

A subsection of the toolbar, like left/center/right.

```diff
- .fc-toolbar-chunk {
+ .my-toolbar-section {
    /* custom css */
  }

// in JS settings
+ toolbarSectionClass: 'my-toolbar-section'
```

### Title

The title text element within toolbar:

```diff
- .fc-toolbar-title {
+ .my-toolbar-title {
    /* custom css */
  }

// in JS settings
+ toolbarTitleClass: 'my-toolbar-title'
```

### Button Group

```diff
/* css */
- .fc-button-group {
+ .my-button-group {
  /* custom css */
}

// in JS settings
+ buttonGroupClass: 'my-button-group'
```

### Buttons

All buttons:

```diff
- .fc-button { /* OR .fc-button-primary */
+ .my-button {
  /* custom css */
}

// in JS settings
+ buttonClass: 'my-button'
```

Specific button:

```diff
- .fc-next-button {
+ .my-next-button {
  /* custom css */
}
- .fc-icon-chevron-right {} /* usually "next" button */
- .fc-icon-chevrons-right {}  /* usually "nextYear" button */
- .fc-icon-chevron-left {} /* usually "prev" button  */
- .fc-icon-chevrons-left {} /* usually "prevYear" button */

// in JS settings
+ buttons: {
+   next: {
+     className: 'my-next-button'
+   }
+   // prev/prevYear/etc...
+ }
```

Currently-selected button in button-group:

```diff
- .fc-button-active {
+ .my-button-active {
  /* custom css */
}

// in JS settings
+ buttonClass: (data) => clsx(data.isSelected && 'my-button-active')
```

Icons within buttons:

```diff
- .fc-button .fc-icon {
+ .my-button-icon {
    /* custom CSS */

    /* NOTE: rethink your vertical alignment technique. v7 uses flexbox */
-   vertical-align: baseline;
  }

// in JS settings
+ buttons: {
+   next: {
+     iconClass: 'my-button-icon',
+     // OR
+     iconContent: () => <svg className='my-button-icon'></svg>
+   },
+   prev: {
+     // SAME. must be applied to each INDIVIDUAL button entry
+   }
+ }
```

Button colors (for **Classic Theme** only):

```diff
  :root {
-   --fc-button-bg-color: #2C3E50;
+   --fc-classic-button: #2C3E50;

-   --fc-button-border-color: #2C3E50;
+   --fc-classic-button-border: #2C3E50;

    /* condensed to one value */
-   --fc-button-hover-bg-color: #1a252f;
-   --fc-button-active-bg-color: #1a252f;
+   --fc-classic-button-strong: #1a252f;

    /* condensed to one value */
-   --fc-button-hover-border-color: #1a252f;
-   --fc-button-active-border-color: #1a252f;
+   --fc-classic-button-strong-border: #1a252f;

-   --fc-button-text-color: #fff;
+   --fc-classic-button-foreground: #fff;
  }
```


## Events (General)

### Foreground (Normal) Events

```diff
- .fc-event {
+ .my-event {
  /* custom css */
}

// in JS
+ eventClass: 'my-event'
```

When the event segment represents the event's start:

```diff
- .fc-event-start {
+ .my-event-start {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isStart && 'my-event-start')
```

When the event segment represents the event's end:

```diff
- .fc-event-end {
+ .my-event-end {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isEnd && 'my-event-end')
```

Future event:

```diff
- .fc-event-future {
+ .my-event-future {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isFuture && 'my-event-future')
```

Past event:

```diff
- .fc-event-past {
+ .my-event-past {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isPast && 'my-event-past')
```

Event occuring today:

```diff
- .fc-event-today {
+ .my-event-today {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isToday && 'my-event-today')
```


Selected state:

```diff
- .fc-event-selected {
+ .my-event-selected {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isSelected && 'my-event-selected')
```

Draggable state:

```diff
- .fc-event-draggable {
+ .my-event-draggable {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isDraggable && 'my-event-draggable')
```

Dragging state:

```diff
- .fc-event-dragging {
+ .my-event-dragging {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isDragging && 'my-event-dragging')
```

Event "mirror" that appears during dragging/resize:

```diff
- .fc-event-mirror {
+ .my-event-mirror {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isMirror && 'my-event-mirror')
```

Resizable state:

```diff
- .fc-event-resizable {
+ .my-event-resizable {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx((data.isStartResizable || data.isEndResizable) && 'my-event-resizable')
```

Resizing state:

```diff
- .fc-event-resizing {
+ .my-event-resizing {
  /* custom css */
}

// in JS
+ eventClass: (data) => clsx(data.isResizing && 'my-event-resizing')
```

The resizer sub-element:

```diff
- .fc-event-resizer {
+ .my-event-resizer {
  /* custom css */
}

// in JS
+ eventBeforeClass: (data) => clsx(data.isStartResizable && 'my-event-resizer')
+ eventAfterClass: (data) => clsx(data.isEndResizable && 'my-event-resizer')
```

The start-resizer sub-element:

```diff
- .fc-event-resizer-start {
+ .my-event-resizer-start {
  /* custom css */
}

// in JS
+ eventBeforeClass: (data) => clsx(data.isStartResizable && 'my-event-resizer-start')
```

The end-resizer sub-element:

```diff
- .fc-event-resizer-end {
+ .my-event-resizer-end {
  /* custom css */
}

// in JS
+ eventAfterClass: (data) => clsx(data.isEndResizable && 'my-event-resizer-end')
```

The inner-element that wraps the time and title:

```diff
- .fc-event-main { /* OR .fc-event-title-container */
+ .my-event-inner {
  /* custom css */
}

// in JS
+ eventInnerClass: 'my-event-inner'
```

Time sub-element:

```diff
- .fc-event-time {
+ .my-event-time {
  /* custom css */
}

// in JS
+ eventTimeClass: 'my-event-time'
```

Title sub-element:

```diff
- .fc-event-title { /* OR .fc-event-title-container */
+ .my-event-title {
  /* custom css */
}

// in JS
+ eventTitleClass: 'my-event-title'
```

Event colors (for **Classic Theme** only):

```diff
:root {
  /* NOTE: the classic theme forces both background and border as same color */
- --fc-event-bg-color: red;
- --fc-event-border-color: red;
+ --fc-classic-primary: red;

- --fc-event-text-color: white;
+ --fc-classic-primary-foreground: white;
}
```

Event-related CSS variables that have no replacement:

```diff
  :root {
-   --fc-small-font-size: 9px; /* applied to events & more-link */
-   --fc-event-resizer-dot-border-width: 1px
-   --fc-event-resizer-dot-total-width: 8px;
-   --fc-event-resizer-thickness: 8px;
-   --fc-event-selected-overlay-color: red; /* dimming effect when selected. UX is different now */
  }
```

### Background Events

```diff
- .fc-bg-event {
+ .my-bg-event {
  /* custom css */
}

// in JS
+ backgroundEventClass: 'my-bg-event'
```

When the event segment represents the event's start:

```diff
- .fc-bg-event.fc-event-start {
+ .my-bg-event-start {
  /* custom css */
}

// in JS
+ backgroundEventClass: (data) => clsx(data.isStart && 'my-bg-event-start')
```

When the event segment represents the event's end:

```diff
- .fc-bg-event.fc-event-end {
+ .my-bg-event-end {
  /* custom css */
}

// in JS
+ backgroundEventClass: (data) => clsx(data.isEnd && 'my-bg-event-end')
```

Future event:

```diff
- .fc-bg-event.fc-event-future {
+ .my-bg-event-future {
  /* custom css */
}

// in JS
+ backgroundEventClass: (data) => clsx(data.isFuture && 'my-bg-event-future')
```

Past event:

```diff
- .fc-bg-event.fc-event-past {
+ .my-bg-event-past {
  /* custom css */
}

// in JS
+ backgroundEventClass: (data) => clsx(data.isPast && 'my-bg-event-past')
```

Event occuring today:

```diff
- .fc-bg-event.fc-event-today {
+ .my-bg-event-today {
  /* custom css */
}

// in JS
+ backgroundEventClass: (data) => clsx(data.isToday && 'my-bg-event-today')
```

Background event colors (for **Classic Theme** only):

```diff
  :root {
-   --fc-bg-event-color: red;
+   --fc-classic-background-event: red;

-   --fc-bg-event-opacity: 10%;
+   --fc-classic-background-event-opacity: 10%;
  }
```

### Horizontal Events (aka "Row Events")

These selectors and settings allow targetting both DayGrid and Timeline events at the same time.

```diff
- .fc-h-event {
+ .my-row-event {
  /* custom css */
}

// in JS
+ rowEventClass: 'my-row-event'
```

When the event segment represents the event's start:

```diff
- .fc-h-event.fc-event-start {
+ .my-row-event-start {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isStart && 'my-row-event-start')
```

When the event segment represents the event's end:

```diff
- .fc-h-event.fc-event-end {
+ .my-row-event-end {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isEnd && 'my-row-event-end')
```

Future event:

```diff
- .fc-h-event.fc-event-future {
+ .my-row-event-future {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isFuture && 'my-row-event-future')
```

Past event:

```diff
- .fc-h-event.fc-event-past {
+ .my-row-event-past {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isPast && 'my-row-event-past')
```

Event occuring today:

```diff
- .fc-h-event.fc-event-today {
+ .my-row-event-today {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isToday && 'my-row-event-today')
```


Selected state:

```diff
- .fc-h-event.fc-event-selected {
+ .my-row-event-selected {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isSelected && 'my-row-event-selected')
```

Draggable state:

```diff
- .fc-h-event.fc-event-draggable {
+ .my-row-event-draggable {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isDraggable && 'my-row-event-draggable')
```

Dragging state:

```diff
- .fc-h-event.fc-event-dragging {
+ .my-row-event-dragging {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isDragging && 'my-row-event-dragging')
```

Event "mirror" that appears during dragging/resize:

```diff
- .fc-h-event.fc-event-mirror {
+ .my-row-event-mirror {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isMirror && 'my-row-event-mirror')
```

Resizable state:

```diff
- .fc-h-event.fc-event-resizable {
+ .my-row-event-resizable {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx((data.isStartResizable || data.isEndResizable) && 'my-row-event-resizable')
```

Resizing state:

```diff
- .fc-h-event.fc-event-resizing {
+ .my-row-event-resizing {
  /* custom css */
}

// in JS
+ rowEventClass: (data) => clsx(data.isResizing && 'my-row-event-resizing')
```

The resizer sub-element:

```diff
- .fc-h-event .fc-event-resizer {
+ .my-row-event-resizer {
  /* custom css */
}

// in JS
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-row-event-resizer')
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-row-event-resizer')
```

The start-resizer sub-element:

```diff
- .fc-h-event .fc-event-resizer-start {
+ .my-row-event-resizer-start {
  /* custom css */
}

// in JS
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-row-event-resizer-start')
```

The end-resizer sub-element:

```diff
- .fc-h-event .fc-event-resizer-end {
+ .my-row-event-resizer-end {
  /* custom css */
}

// in JS
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-row-event-resizer-end')
```

The inner-element that wraps the time and title:

```diff
- .fc-h-event .fc-event-main {
+ .my-row-event-main {
  /* custom css */
}

// in JS
+ rowEventInnerClass: 'my-row-event-main'
```

Time sub-element:

```diff
- .fc-h-event .fc-event-time {
+ .my-row-event-time {
  /* custom css */
}

// in JS
+ rowEventTimeClass: 'my-row-event-time'
```

Title sub-element:

```diff
- .fc-h-event .fc-event-title {
+ .my-row-event-title {
  /* custom css */
}

// in JS
+ rowEventTitleClass: 'my-row-event-title'
```


## Resources (General)

TODO: link to fc-resource stuff. label too?


## Popover & More-Link

### More-Link

The link that triggers a popover:

```diff
- .fc-more-link {
+ .my-more-link {
  /* custom css */
}

// in JS
+ moreLinkClass: 'my-more-link'
```

The above code shows how to style *all* more-links, but it's possible to target specific ones. See [Row More-Links](row-more-link-render-hooks) and [Column More-Links](column-more-link-render-hooks).

More-link colors (for **Classic Theme** only):

```diff
  :root {
    /* bg color - easy */
-   --fc-more-link-bg-color: #374151;
+   --fc-classic-strong: #374151; /* now uses a general-purpose neutral color */

    /* text color - needs more complex migration... */
-   --fc-more-link-text-color: #fff;
  }

+ .my-more-link-inner {
+   color: #fff;
+ }

  // in JS settings
+ moreLinkInnerClass: 'my-more-link-inner'
```

### Popover

Popover root element:

```diff
- .fc-popover { /* OR .fc-more-popover */
+ .my-popover {
  /* custom css */
}

// in JS
+ popoverClass: 'my-popover'
```

Popover for future date:

```diff
- .fc-popover.fc-day-future {
+ .my-popover-future { /* will apply separately to both popover header and body */
  /* custom css */
}

// in JS settings
+ dayHeaderClass: (data) => clsx((data.inPopover && data.isFuture) && 'my-popover-future'),
+ dayCellClass: (data) => clsx((data.inPopover && data.isFuture) && 'my-popover-future'),
```

Popover for past date:

```diff
- .fc-popover.fc-day-past {
+ .my-popover-past { /* will apply separately to both popover header and body */
  /* custom css */
}

// in JS settings
+ dayHeaderClass: (data) => clsx((data.inPopover && data.isPast) && 'my-popover-past'),
+ dayCellClass: (data) => clsx((data.inPopover && data.isPast) && 'my-popover-past'),
```

Popover for today:

```diff
- .fc-popover.fc-day-today {
+ .my-popover-today { /* will apply separately to both popover header and body */
  /* custom css */
}

// in JS settings
+ dayHeaderClass: (data) => clsx((data.inPopover && data.isToday) && 'my-popover-today'),
+ dayCellClass: (data) => clsx((data.inPopover && data.isToday) && 'my-popover-today'),
```

Popover for other month:

```diff
- .fc-popover.fc-day-other {
+ .my-popover-other { /* will apply separately to both popover header and body */
  /* custom css */
}

// in JS settings
+ dayHeaderClass: (data) => clsx((data.inPopover && data.isOther) && 'my-popover-other'),
+ dayCellClass: (data) => clsx((data.inPopover && data.isOther) && 'my-popover-other'),
```

Popover for specific day-of-week:

```diff
- .fc-popover.fc-day-sun {
+ .my-popover-sun {
  /* custom CSS */
}

// in JS settings, timeZone='local'
+ dayHeaderClass: (data) => clsx((data.inPopover && data.getDay() === 0) && 'my-popover-sun'),
+ dayCellClass: (data) => clsx((data.inPopover && data.getDay() === 0) && 'my-popover-sun'),

// in JS settings, timeZone='UTC'
+ dayHeaderClass: (data) => clsx((data.inPopover && data.getUTCDay() === 0) && 'my-popover-sun'),
+ dayCellClass: (data) => clsx((data.inPopover && data.getUTCDay() === 0) && 'my-popover-sun'),
```

For other days of week, modify the above example:

- `.fc-popover.fc-day-mon` - change the `=== 0` to `=== 1`
- `.fc-popover.fc-day-tue` - change the `=== 0` to `=== 2`
- `.fc-popover.fc-day-wed` - change the `=== 0` to `=== 3`
- `.fc-popover.fc-day-thu` - change the `=== 0` to `=== 4`
- `.fc-popover.fc-day-fri` - change the `=== 0` to `=== 5`
- `.fc-popover.fc-day-sat` - change the `=== 0` to `=== 6`

Popover close button:

```diff
- .fc-popover-close { /* OR .fc-icon-x */
+ .my-popover-close {
  /* custom css */
}

// in JS
+ popoverCloseClass: 'my-popover-close'
```

Popover header (now a "day-header"):

```diff
- .fc-popover-header {
+ .my-popover-header {
  /* custom css */
}

// in JS
+ dayHeaderClass: (data) => clsx(data.inPopover && 'my-popover-header')
```

Popover title text element:

```diff
- .fc-popover-title {
+ .my-popover-title {
  /* custom css */
}

// in JS
+ dayHeaderInnerClass: (data) => clsx(data.inPopover && 'my-popover-title')
```

Popover header (now a "day-cell"):

```diff
- .fc-popover-body {
+ .my-popover-body {
  /* custom css */
}
/* would wrap custom injected content (no longer possible) */
- .fc-more-popover-misc {}

// in JS
+ dayCellClass: (data) => clsx(data.inPopover && 'my-popover-body')
```


## Calendar Views (General)

All views:

```diff
- .fc-view {
+ .my-view {
  /* custom css */
}

// in JS settings
+ viewClass: 'my-view'
```

A specific view:

```diff
- .fc-timeGridWeek-view {
+ .my-timeGridWeek-view {
  /* custom css */
}

// in JS settings
+ views: {
+   timeGridWeek: {
+     viewClass: 'my-timeGridWeek-view'
+   }
+ }
```

### Table Header Cells

Alignment for content within all header cells:

```diff
/* in CSS */
- .fc th {
-   text-align: left;
- }

// in JS
+ dayHeaderAlign: 'left',
+ resourceDayHeaderAlign: 'left',
```

Any other custom CSS for header cells:

```diff
/* in CSS */
- .fc th {
+ .my-header-class {
  font-weight: 900;
}

// in JS
+ dayHeaderClass: 'my-header-class',
+ resourceDayHeaderClass: 'my-header-class',
+ listDayHeaderClass: 'my-header-class',
+ views: {
+   timeline: {
+     slotHeaderClass: 'my-header-class',
+   }
+ }
```

**NOTE:** the default `font-weight` for header cells in DayGrid, TimeGrid, Timeline, and Resource-Timeline is now `normal`. If you wrote CSS to force `normal`, it is now unnecessary.


### Background Colors (for Classic Theme only)

Colors for specific elements:

```diff
  :root {
-   --fc-border-color: #d0d7de;
+   --fc-classic-border: #d0d7de;

-   --fc-now-indicator-color: #ef4444;
+   --fc-classic-now: #ef4444;

-   --fc-today-bg-color: #fef3c7;
+   --fc-classic-today: #fef3c7;

-   --fc-highlight-color: #fde68a;
+   --fc-classic-highlight: #fde68a;

-   --fc-non-business-color: #f3f4f6;
+   --fc-classic-faint: #f3f4f6; /* now uses a general-purpose neutral color */
  }
```

Migrations for existing general-purpose neutral colors:

```diff
-   --fc-neutral-bg-color: #f3f4f6;
+   --fc-classic-muted: #f3f4f6;

-   --fc-neutral-text-color: #4b5563;
+   --fc-classic-muted-foreground: #4b5563;
```

If you were customizing `.fc-cell-shaded` directly instead of `--fc-neutral-bg-color`:

```diff
- .fc-cell-shaded {
-   background: red;
- }

+ :root {
+   --fc-classic-muted: red;
+ }
```

If you were customizing `.fc-highlight` directly instead of `--fc-highlight-color`:

```diff
- .fc-highlight {
+ .my-highlight {
  /* custom css */
}

// in JS
+ highlightClass: 'my-highlight'
```

If you were customizing `.fc-non-business` directly instead of `--fc-non-business-color`:

```diff
- .fc-non-business {
+ .my-non-business {
  /* custom css */
}

// in JS
+ nonBusinessHoursClass: 'my-non-business'
```

### Obsolete

These class-names were intended internal-only and are now removed:

```diff
- .fc-view-harness {}
- .fc-view-harness-active {}
- .fc-view-harness-passive {}
- .fc-scrollgrid-section-liquid {}
- .fc-scrollgrid-section-footer {}
- .fc-scrollgrid-collapsible {}
- .fc-scrollgrid-liquid {}
- .fc-scrollgrid-shrink {}
- .fc-scrollgrid-shrink-cushion {}
- .fc-scrollgrid-shrink-frame {}
- .fc-scrollgrid-sticky-shim {}
- .fc-scrollgrid-sync-inner {}
- .fc-scrollgrid-sync-table {}
- .fc-scroller {}
- .fc-scroller-harness {}
- .fc-scroller-harness-liquid {}
- .fc-scroller-liquid {}
- .fc-scroller-liquid-absolute {}
- .fc-sticky {}
- .fc-liquid-hack {}
- .fc-not-allowed {}
- .fc-license-message {}
```


## DayGrid View

Root view element:

```diff
- .fc-daygrid { /* OR .fc-daygrid .fc-scrollgrid */
+ .my-daygrid-view {
  /* custom CSS */
}

// in JS settings
+ views: {
+   daygrid: {
+     viewClass: 'my-daygrid-view'
+   }
+ }
```

### Table Structure

Table header section:

```diff
- .fc-daygrid .fc-scrollgrid-section-header { /* OR .fc-daygrid .fc-col-header */
+ .my-daygrid-header {
  /* custom CSS */
}

// in JS settings
+ views: {
+   dayGrid: {
+     tableHeaderClass: 'my-daygrid-header'
+   }
+ }
```

Sticky table header section:

```diff
- .fc-daygrid .fc-scrollgrid-section-sticky {
+ .my-daygrid-header-sticky {
  /* custom CSS */
}

// in JS settings
+ views: {
+   dayGrid: {
+     tableHeaderClass: (data) => clsx(data.isSticky && 'my-daygrid-header-sticky')
+   }
+ }
```

Table body section:

```diff
- .fc-daygrid .fc-scrollgrid-section-body { /* OR .fc-daygrid-body */
+ .my-daygrid-body {
  /* custom CSS */
}

// in JS settings
+ views: {
+   dayGrid: {
+     tableBodyClass: 'my-daygrid-body'
+   }
+ }
```

### Day Header Cells

```diff
- .fc-col-header-cell {
+ .my-day-header {
  /* custom css */
}

// in JS
+ dayHeaderClass: 'my-day-header'
```

Day-of-week:

```diff
- .fc-col-header-cell.fc-day-sun {
+ .my-header-cell-sun {
  /* custom CSS */
}

// in JS settings, timeZone='local'
+ dayCellClass: (data) => clsx(data.getDay() === 0 && 'my-header-cell-sun'),

// in JS settings, timeZone='UTC'
+ dayCellClass: (data) => clsx(data.getUTCDay() === 0 && 'my-header-cell-sun'),
```

For other days of week, modify the above example:

- `.fc-col-header-cell.fc-day-mon` - change the `=== 0` to `=== 1`
- `.fc-col-header-cell.fc-day-tue` - change the `=== 0` to `=== 2`
- `.fc-col-header-cell.fc-day-wed` - change the `=== 0` to `=== 3`
- `.fc-col-header-cell.fc-day-thu` - change the `=== 0` to `=== 4`
- `.fc-col-header-cell.fc-day-fri` - change the `=== 0` to `=== 5`
- `.fc-col-header-cell.fc-day-sat` - change the `=== 0` to `=== 6`

Inner-wrapper within table header cell:

```diff
- .fc-col-header-cell-cushion {
+ .my-day-header-inner {
  /* custom css */
}

// in JS
+ dayHeaderInnerClass: 'my-day-header-inner'
```

### Day Body Cells

```diff
- .fc-daygrid-day {
+ .my-cell {
  /* custom CSS */
}

// in JS settings
+ dayCellClass: 'my-cell'
```

Future day:

```diff
- .fc-daygrid-day.fc-day-future {
+ .my-cell-future {
  /* custom css */
}

// in JS settings
+ dayCellClass: (data) => clsx(data.isFuture && 'my-cell-future'),
```

Past day:

```diff
- .fc-daygrid-day.fc-day-past {
+ .my-cell-past {
  /* custom css */
}

// in JS settings
+ dayCellClass: (data) => clsx(data.isPast && 'my-cell-past'),
```

Today:

```diff
- .fc-daygrid-day.fc-day-today {
+ .my-cell-today {
  /* custom css */
}

// in JS settings
+ dayCellClass: (data) => clsx(data.isToday && 'my-cell-today'),
```

Other month:

```diff
- .fc-daygrid-day.fc-day-other {
+ .my-cell-other {
  /* custom css */
}

// in JS settings
+ dayCellClass: (data) => clsx(data.isOther && 'my-cell-other'),
```

Day-of-week:

```diff
- .fc-daygrid-day.fc-day-sun {
+ .my-cell-sun {
  /* custom CSS */
}

// in JS settings, timeZone='local'
+ dayCellClass: (data) => clsx(data.getDay() === 0 && 'my-cell-sun'),

// in JS settings, timeZone='UTC'
+ dayCellClass: (data) => clsx(data.getUTCDay() === 0 && 'my-cell-sun'),
```

For other days of week, modify the above example:

- `.fc-daygrid-day.fc-day-mon` - change the `=== 0` to `=== 1`
- `.fc-daygrid-day.fc-day-tue` - change the `=== 0` to `=== 2`
- `.fc-daygrid-day.fc-day-wed` - change the `=== 0` to `=== 3`
- `.fc-daygrid-day.fc-day-thu` - change the `=== 0` to `=== 4`
- `.fc-daygrid-day.fc-day-fri` - change the `=== 0` to `=== 5`
- `.fc-daygrid-day.fc-day-sat` - change the `=== 0` to `=== 6`

Day top sub-element. Contains the day-number:

```diff
- .fc-daygrid-day-top {
+ .my-day-top {
  /* custom css */
}

// in JS
+ dayCellTopClass: 'my-day-top'
```

Day-number:

```diff
- .fc-daygrid-day-number {
+ .my-day-number {
  /* custom css */
}

// in JS
+ dayCellTopInnerClass: (data) => clsx((data.text === data.dayNumberText) && 'my-day-number')
```

Month text within the day cell:

```diff
- .fc-daygrid-month-start {
+ .my-month-start {
  /* custom css */
}

// in JS
+ dayCellTopInnerClass: (data) => clsx((data.text !== data.dayNumberText) && 'my-month-start')
```

Events within the day cell:

```diff
- .fc-daygrid-day-events {
+ .my-day-events {
  background: yellow;
}

// in JS
+ dayCellInnerClass: 'my-day-events'
```

But adding space to the top/bottom requires a different technique:

```diff
- .fc-daygrid-day-events {
-    margin-top: 10px;
-    margin-bottom: 20px;
- }

+ .my-day-top {
+   min-height: 10px;
+ }
+ .my-day-bottom {
+   min-height: 20px;
+ }

// in JS settings
+ dayCellTopClass: 'my-day-top',
+ dayCellBottomClass: 'my-day-bottom',
```

Day bottom sub-element. Contains the more-link:

```diff
- .fc-daygrid-day-bottom {
+ .my-day-bottom {
  /* custom css */
}

// in JS
+ dayCellBottomClass: 'my-day-bottom'
```

### DayGrid More-Link

```diff
- .fc-daygrid-more-link {
+ .my-more-link {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: { rowMoreLinkClass: 'my-more-link' },
+   timeGrid: { rowMoreLinkClass: 'my-more-link' },
+ }
```

### DayGrid Week Number

```diff
- .fc-daygrid-week-number {
+ .my-daygrid-week-number {
  /* custom CSS */
}

// in JS settings
+ inlineWeekNumberClass: 'my-daygrid-week-number'
```

### DayGrid Events

```diff
- .fc-daygrid-event {
+ .my-daygrid-event {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: { eventClass: 'my-daygrid-event' },
+   timeGrid: { rowEventClass: 'my-daygrid-event' },
+ }
```

The solid-looking all-day or multi-day events:

```diff
- .fc-daygrid-block-event {
+ .my-row-event {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: { rowEventClass: 'my-row-event' },
+   timeGrid: { rowEventClass: 'my-row-event' },
+ }
```

Timed events that are usually prefixed with a bullet-point:

```diff
- .fc-daygrid-dot-event {
+ .my-daygrid-list-event {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: { listItemEventClass: 'my-daygrid-list-event' },
+ }
```

The bullet-point's width (for **Classic Theme** only):

```diff
  :root {
-   --fc-daygrid-event-dot-width: 8px;
+   --fc-classic-small-dot-width: 8px;
  }
```

The bullet-point's custom CSS:

```diff
- .fc-daygrid-event-dot {
+ .my-event-dot {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: { listItemEventBeforeClass: 'my-event-dot' },
+ }
```

When the event segment represents the event’s start:

```diff
- .fc-daygrid-event.fc-event-start {
+ .my-daygrid-event-start {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: (data) => clsx(data.isStart && 'my-daygrid-event-start')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isStart && 'my-daygrid-event-start')
+   },
+ }
```

When the event segment represents the event’s end:

```diff
- .fc-daygrid-event.fc-event-end {
+ .my-daygrid-event-end {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: (data) => clsx(data.isEnd && 'my-daygrid-event-end')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isEnd && 'my-daygrid-event-end')
+   },
+ }
```

Future event:

```diff
- .fc-daygrid-event.fc-event-future {
+ .my-daygrid-event-future {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: (data) => clsx(data.isFuture && 'my-daygrid-event-future')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isFuture && 'my-daygrid-event-future')
+   },
+ }
```

Past event:

```diff
- .fc-daygrid-event.fc-event-past {
+ .my-daygrid-event-past {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: (data) => clsx(data.isPast && 'my-daygrid-event-past')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isPast && 'my-daygrid-event-past')
+   },
+ }
```

Event occuring today:

```diff
- .fc-daygrid-event.fc-event-today {
+ .my-daygrid-event-today {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: (data) => clsx(data.isToday && 'my-daygrid-event-today')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isToday && 'my-daygrid-event-today')
+   },
+ }
```

Selected state:

```diff
- .fc-daygrid-event.fc-event-selected {
+ .my-daygrid-event-selected {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: (data) => clsx(data.isSelected && 'my-daygrid-event-selected')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isSelected && 'my-daygrid-event-selected')
+   },
+ }
```

Draggable state:

```diff
- .fc-daygrid-event.fc-event-draggable {
+ .my-daygrid-event-draggable {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: (data) => clsx(data.isDraggable && 'my-daygrid-event-draggable')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isDraggable && 'my-daygrid-event-draggable')
+   },
+ }
```

Dragging state:

```diff
- .fc-daygrid-event.fc-event-dragging {
+ .my-daygrid-event-dragging {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: (data) => clsx(data.isDragging && 'my-daygrid-event-dragging')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isDragging && 'my-daygrid-event-dragging')
+   },
+ }
```

Event “mirror” that appears during dragging/resize:

```diff
- .fc-daygrid-event.fc-event-mirror {
+ .my-daygrid-event-mirror {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: (data) => clsx(data.isMirror && 'my-daygrid-event-mirror')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isMirror && 'my-daygrid-event-mirror')
+   },
+ }
```

Resizable state:

```diff
- .fc-daygrid-event.fc-event-resizable {
+ .my-daygrid-event-resizable {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     rowEventClass: (data) => clsx((data.isStartResizable || data.isEndResizable) && 'my-daygrid-event-resizable')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx((data.isStartResizable || data.isEndResizable) && 'my-daygrid-event-resizable')
+   },
+ }
```

Resizing state:

```diff
- .fc-daygrid-event.fc-event-resizing {
+ .my-daygrid-event-resizing {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     rowEventClass: (data) => clsx(data.isResizing && 'my-daygrid-event-resizing')
+   },
+   timeGrid: {
+     rowEventClass: (data) => clsx(data.isResizing && 'my-daygrid-event-resizing')
+   },
+ }
```

The resizer sub-element:

```diff
- .fc-daygrid-event .fc-event-resizer {
+ .my-daygrid-event-resizer {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-daygrid-event-resizer'),
+     rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-daygrid-event-resizer'),
+   },
+   timeGrid: {
+     rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-daygrid-event-resizer'),
+     rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-daygrid-event-resizer'),
+   },
+ }
```

The start-resizer sub-element:

```diff
- .fc-daygrid-event .fc-event-resizer-start {
+ .my-daygrid-event-resizer-start {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-daygrid-event-resizer-start')
+   },
+   timeGrid: {
+     rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-daygrid-event-resizer-start')
+   },
+ }
```

The end-resizer sub-element:

```diff
- .fc-daygrid-event .fc-event-resizer-end {
+ .my-daygrid-event-resizer-end {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-daygrid-event-resizer-end')
+   },
+   timeGrid: {
+     rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-daygrid-event-resizer-end')
+   },
+ }
```

The inner-element that wraps the time and title:

```diff
- .fc-daygrid-event .fc-event-main {
+ .my-daygrid-event-main {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: 'my-daygrid-event-main'
+   },
+   timeGrid: {
+     rowEventInnerClass: 'my-daygrid-event-main'
+   },
+ }
```

Time sub-element:

```diff
- .fc-daygrid-event .fc-event-time {
+ .my-daygrid-event-time {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: 'my-daygrid-event-time'
+   },
+   timeGrid: {
+     rowEventTimeClass: 'my-daygrid-event-time'
+   },
+ }
```

Title sub-element:

```diff
- .fc-daygrid-event .fc-event-title {
+ .my-daygrid-event-title {
  /* custom css */
}

// in JS
+ views: {
+   dayGrid: {
+     eventClass: 'my-daygrid-event-title'
+   },
+   timeGrid: {
+     rowEventTitleClass: 'my-daygrid-event-title'
+   },
+ }
```

### No Replacement

```diff
- .fc-daygrid-event-harness {}
- .fc-daygrid-event-harness-abs {}
- .fc-daygrid-bg-harness {}
- .fc-daygrid-body {}
- .fc-daygrid-body-balanced {}
- .fc-daygrid-body-natural {}
- .fc-daygrid-body-unbalanced {}
- .fc-daygrid-day-frame {}
- .fc-daygrid-day-bg {}
```

## Resource DayGrid View

Day header cell:

```diff
- .fc-col-header-cell.fc-resource {
+ .my-resource-header {
  /* custom CSS */
}

// in JS settings
+ resourceDayHeaderClass: (data) => 'my-resource-header',
+ dayHeaderClass: (data) => clsx(data.resource && 'my-resource-header'),
```

Day body cell:

```diff
- .fc-daygrid-day.fc-resource {
+ .my-resource-cell {
  /* custom CSS */
}

// in JS settings
+ dayCellClass: (data) => clsx(data.resource && 'my-resource-cell')
```

## TimeGrid View

Root view element:

```diff
- .fc-timegrid {
+ .my-timegrid-view { /* OR .fc-timegrid .fc-scrollgrid */
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     viewClass: 'my-timegrid-view'
+   }
+ }
```

### Table Structure

Table header section:

```diff
- .fc-timegrid .fc-scrollgrid-section-header { /* OR .fc-timegrid .fc-col-header */
+ .my-timegrid-header {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     tableHeaderClass: 'my-timegrid-header'
+   }
+ }
```

Sticky table header section:

```diff
- .fc-timegrid .fc-scrollgrid-section-sticky {
+ .my-timegrid-header-sticky {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     tableHeaderClass: (data) => clsx(data.isSticky && 'my-timegrid-header-sticky')
+   }
+ }
```

Table body section:

```diff
- .fc-timegrid .fc-scrollgrid-section-body { /* OR .fc-timegrid-body */
+ .my-timegrid-body {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     tableBodyClass: 'my-timegrid-body'
+   }
+ }
```

### All-Day Divider

The horizontal divider between the all-day area and timed area:

```diff
- .fc-timegrid-divider {
+ .my-timegrid-divider {
  /* custom CSS */
}

// in JS settings
+ allDayDividerClass: 'my-timegrid-divider',
```

### Time Axis

Time-axis cells:

```diff
- .fc-timegrid-axis {
+ .my-timegrid-axis {
  /* custom CSS */
}

// in JS settings
+ weekNumberHeaderClass: 'my-timegrid-axis',
+ allDayHeaderClass: 'my-timegrid-axis',
+ views: {
+   timeGrid: {
+     slotHeaderClass: 'my-timegrid-axis'
+   }
+ }
```

Inner wrapper within time-axis cells:

```diff
- .fc-timegrid-axis-cushion {
+ .my-timegrid-axis-inner {
  /* custom CSS */
}

// in JS settings
+ weekNumberHeaderInnerClass: 'my-timegrid-axis-inner',
+ allDayHeaderInnerClass: 'my-timegrid-axis-inner',
+ views: {
+   timeGrid: {
+     slotHeaderInnerClass: 'my-timegrid-axis-inner'
+   }
+ }
```

### Time Slots

Targeting both axis and lane:

```diff
- .fc-timegrid-slot {
+ .my-timegrid-slot {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     slotHeaderClass: 'my-timegrid-slot',
+     slotLaneClass: 'my-timegrid-slot',
+   }
+ }
```

Minor dotted slot (both axis and lane):

```diff
- .fc-timegrid-slot-minor {
+ .my-timegrid-slot-minor {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     slotHeaderClass: (data) => clsx(data.isMinor && 'my-timegrid-slot-minor'),
+     slotLaneClass: (data) => clsx(data.isMinor && 'my-timegrid-slot-minor'),
+   }
+ }
```

Slot axis (aka "header"):

```diff
- .fc-timegrid-slot-label {
+ .my-timegrid-slot-header {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     slotHeaderClass: 'my-timegrid-slot-header',
+   }
+ }
```

Slot axis inner wrapper:

```diff
- .fc-timegrid-slot-label-cushion {
+ .my-timegrid-slot-header-inner {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     slotHeaderInnerClass: 'my-timegrid-slot-header-inner',
+   }
+ }
```

Slot lane:

```diff
- .fc-timegrid-slot-lane {
+ .my-timegrid-slot-lane {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     slotLaneClass: 'my-timegrid-slot-lane'
+   }
+ }
```

### Day Lane

In the timed area, day element that spans top-to-bottom:

```diff
- .fc-timegrid-col {
+ .my-lane {
  /* custom CSS */
}

// in JS settings
+ dayLaneClass: 'my-lane',
```

In future:

```diff
- .fc-timegrid-col.fc-day-future {
+ .my-lane-future {
  /* custom css */
}

// in JS settings
+ dayLaneClass: (data) => clsx(data.isFuture && 'my-lane-future'),
```

In past:

```diff
- .fc-timegrid-col.fc-day-past {
+ .my-lane-past {
  /* custom css */
}

// in JS settings
+ dayLaneClass: (data) => clsx(data.isPast && 'my-lane-past'),
```

Today:

```diff
- .fc-timegrid-col.fc-day-today {
+ .my-lane-today {
  /* custom css */
}

// in JS settings
+ dayLaneClass: (data) => clsx(data.isToday && 'my-lane-today'),
```

Other month:

```diff
- .fc-timegrid-col.fc-day-other {
+ .my-lane-other {
  /* custom css */
}

// in JS settings
+ dayLaneClass: (data) => clsx(data.isOther && 'my-lane-other'),
```

Day-of-week:

```diff
- .fc-timegrid-col.fc-day-sun {
+ .my-lane-sun {
  /* custom CSS */
}

// in JS settings, timeZone='local'
+ dayLaneClass: (data) => clsx(data.getDay() === 0 && 'my-lane-sun'),

// in JS settings, timeZone='UTC'
+ dayLaneClass: (data) => clsx(data.getUTCDay() === 0 && 'my-lane-sun'),
```

For other days of week, modify the above example:

- `.fc-timegrid-col.fc-day-mon` - change the `=== 0` to `=== 1`
- `.fc-timegrid-col.fc-day-tue` - change the `=== 0` to `=== 2`
- `.fc-timegrid-col.fc-day-wed` - change the `=== 0` to `=== 3`
- `.fc-timegrid-col.fc-day-thu` - change the `=== 0` to `=== 4`
- `.fc-timegrid-col.fc-day-fri` - change the `=== 0` to `=== 5`
- `.fc-timegrid-col.fc-day-sat` - change the `=== 0` to `=== 6`

Lane inner-wrapper:

```diff
- .fc-timegrid-col-events {
+ .my-day-lane-inner {
  /* custom CSS */
}
/* would wrap custom injected content (no longer possible) */
- .fc-timegrid-col-misc {}

// in JS settings
+ dayLaneInnerClass: 'my-day-lane-inner',
```

### Now-Indicator

Arrow:

```diff
- .fc-timegrid-now-indicator-arrow {
+ .my-timegrid-now-indicator-header {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     nowIndicatorHeaderClass: 'my-timegrid-now-indicator-header'
+   }
+ }
```

Line:

```diff
- .fc-timegrid-now-indicator-line {
+ .my-timegrid-now-indicator-line {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     nowIndicatorLineClass: 'my-timegrid-now-indicator-line'
+   }
+ }
```

### More-Link

```diff
- .fc-timegrid-more-link {
+ .my-timegrid-more-link {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     columnMoreLinkClass: 'my-timegrid-more-link'
+   }
+ }
```

The inner-wrapper:

```diff
- .fc-timegrid-more-link-inner {
+ .my-timegrid-more-link-inner {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeGrid: {
+     columnMoreLinkInnerClass: 'my-timegrid-more-link-inner'
+   }
+ }
```

### Events

```diff
- .fc-timegrid-event { /* OR .fc-v-event */
+ .my-timegrid-event {
  /* custom css */
}

// in JS
+ columnEventClass: 'my-timegrid-event'
```

Short event:

```diff
- .fc-timegrid-event-short {
+ .my-timegrid-event-short {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isShort && 'my-timegrid-event-short')
```

When the event segment represents the event’s start:

```diff
- .fc-timegrid-event.fc-event-start { /* OR .fc-v-event.fc-event-start */
+ .my-timegrid-event-start {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isStart && 'my-timegrid-event-start')
```

When the event segment represents the event’s end:

```diff
- .fc-timegrid-event.fc-event-end { /* OR .fc-v-event.fc-event-end */
+ .my-timegrid-event-end {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isEnd && 'my-timegrid-event-end')
```

Future event:

```diff
- .fc-timegrid-event.fc-event-future { /* OR .fc-v-event.fc-event-future */
+ .my-timegrid-event-future {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isFuture && 'my-timegrid-event-future')
```

Past event:

```diff
- .fc-timegrid-event.fc-event-past { /* OR .fc-v-event.fc-event-past */
+ .my-timegrid-event-past {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isPast && 'my-timegrid-event-past')
```

Event occurring today:

```diff
- .fc-timegrid-event.fc-event-today { /* OR .fc-v-event.fc-event-today */
+ .my-timegrid-event-today {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isToday && 'my-timegrid-event-today')
```

Selected state:

```diff
- .fc-timegrid-event.fc-event-selected { /* OR .fc-v-event.fc-event-selected */
+ .my-timegrid-event-selected {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isSelected && 'my-timegrid-event-selected')
```

Draggable state:

```diff
- .fc-timegrid-event.fc-event-draggable { /* OR .fc-v-event.fc-event-draggable */
+ .my-timegrid-event-draggable {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isDraggable && 'my-timegrid-event-draggable')
```

Dragging state:

```diff
- .fc-timegrid-event.fc-event-dragging { /* OR .fc-v-event.fc-event-dragging */
+ .my-timegrid-event-dragging {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isDragging && 'my-timegrid-event-dragging')
```

Event “mirror” that appears during dragging/resize:

```diff
- .fc-timegrid-event.fc-event-mirror { /* OR .fc-v-event.fc-event-mirror */
+ .my-timegrid-event-mirror {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isMirror && 'my-timegrid-event-mirror')
```

Resizable state:

```diff
- .fc-timegrid-event.fc-event-resizable { /* OR .fc-v-event.fc-event-resizable */
+ .my-timegrid-event-resizable {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(
+   (data.isStartResizable || data.isEndResizable) && 'my-timegrid-event-resizable'
+ )
```

Resizing state:

```diff
- .fc-timegrid-event.fc-event-resizing { /* OR .fc-v-event.fc-event-resizing */
+ .my-timegrid-event-resizing {
  /* custom css */
}

// in JS
+ columnEventClass: (data) => clsx(data.isResizing && 'my-timegrid-event-resizing')
```

The resizer sub-element:

```diff
- .fc-timegrid-event .fc-event-resizer { /* OR .fc-v-event .fc-event-resizer */
+ .my-timegrid-event-resizer {
  /* custom css */
}

// in JS
+ columnEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-timegrid-event-resizer')
+ columnEventAfterClass: (data) => clsx(data.isEndResizable && 'my-timegrid-event-resizer')
```

The start-resizer sub-element:

```diff
- .fc-timegrid-event .fc-event-resizer-start { /* OR .fc-v-event .fc-event-resizer-start */
+ .my-timegrid-event-resizer-start {
  /* custom css */
}

// in JS
+ columnEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-timegrid-event-resizer-start')
```

The end-resizer sub-element:

```diff
- .fc-timegrid-event .fc-event-resizer-end { /* OR .fc-v-event .fc-event-resizer-end */
+ .my-timegrid-event-resizer-end {
  /* custom css */
}

// in JS
+ columnEventAfterClass: (data) => clsx(data.isEndResizable && 'my-timegrid-event-resizer-end')
```

The inner-element that wraps the time and title:

```diff
- .fc-timegrid-event .fc-event-main { /* OR .fc-v-event .fc-event-main */
+ .my-timegrid-event-main {
  /* custom css */
}

// in JS
+ columnEventInnerClass: 'my-timegrid-event-main'
```

Time sub-element:

```diff
- .fc-timegrid-event .fc-event-time { /* OR .fc-v-event .fc-event-time */
+ .my-timegrid-event-time {
  /* custom css */
}

// in JS
+ columnEventTimeClass: 'my-timegrid-event-time'
```

Title sub-element:

```diff
- .fc-timegrid-event .fc-event-title { /* OR .fc-v-event .fc-event-title */
+ .my-timegrid-event-title {
  /* custom css */
}

// in JS
+ columnEventTitleClass: 'my-timegrid-event-title'
```

### No Replacement

```diff
- .fc-timegrid-event-harness {}
- .fc-timegrid-event-harness-inset {}
- .fc-timegrid-axis-frame {}
- .fc-timegrid-axis-frame-liquid {}
- .fc-timegrid-axis-chunk {}
- .fc-timegrid-bg-harness {}
- .fc-timegrid-body {}
- .fc-timegrid-col-bg {}
- .fc-timegrid-col-frame {}
- .fc-timegrid-cols {}
- .fc-timegrid-now-indicator-container {}
- .fc-timegrid-slots {}
- .fc-timegrid-slot-label-frame {}
```


## Resource TimeGrid View

```diff
- .fc-timegrid-col.fc-resource {
+ .my-resource-lane {
  /* custom CSS */
}

// in JS settings
+ dayLaneClass: (data) => clsx(data.resource && 'my-resource-lane')
```

## List View

```diff
- .fc-list { /* OR .fc-list-table */
+ .my-list-view {
  /* custom CSS */
}

// in JS settings
+ views: {
+   list: {
+     viewClass: 'my-list-view'
+   }
+ }
```

### List Day-Header

The header that labels a group of events:

```diff
- .fc-list-day {
+ .my-list-day-header {
  /* custom css */
}

// in JS
+ listDayHeaderClass: 'my-list-day-header'
```

Inner wrapper that applies to both primary and secondary header text:

```diff
- .fc-list-day-cushion {
+ .my-list-day-header-inner {
  /* custom css */
}

// in JS
+ listDayHeaderInnerClass: 'my-list-day-header-inner'
```

Primary header text element (usually to left):

```diff
- .fc-list-day-side-text {
+ .my-list-day-header-inner-primary {
  /* custom css */
}

// in JS
+ listDayHeaderInnerClass: (data) => clsx((data.level === 0) && 'my-list-day-header-inner-primary')
```

Secondary header text element (usually to right):

```diff
- .fc-list-day-side-text {
+ .my-list-day-header-inner-secondary {
  /* custom css */
}

// in JS
+ listDayHeaderInnerClass: (data) => clsx((data.level > 0) && 'my-list-day-header-inner-secondary')
```

### Events

```diff
- .fc-list-event {
+ .my-list-event {
  /* custom css */
}

// in JS
+ views: {
+   list: {
+     listItemEventClass: 'my-list-event'
+   }
+ }
```

When the event segment represents the event’s start:

```diff
- .fc-list-event.fc-event-start {
+ .my-list-event-start {
  /* custom css */
}

// in JS
+ views: {
+   list: {
+     listItemEventClass: (data) => clsx(data.isStart && 'my-list-event-start')
+   }
+ }
```

When the event segment represents the event’s end:

```diff
- .fc-list-event.fc-event-end {
+ .my-list-event-end {
  /* custom css */
}

// in JS
+ views: {
+   list: {
+     listItemEventClass: (data) => clsx(data.isEnd && 'my-list-event-end')
+   }
+ }
```

Future event:

```diff
- .fc-list-event.fc-event-future {
+ .my-list-event-future {
  /* custom css */
}

// in JS
+ views: {
+   list: {
+     listItemEventClass: (data) => clsx(data.isFuture && 'my-list-event-future')
+   }
+ }
```

Past event:

```diff
- .fc-list-event.fc-event-past {
+ .my-list-event-past {
  /* custom css */
}

// in JS
+ views: {
+   list: {
+     listItemEventClass: (data) => clsx(data.isPast && 'my-list-event-past')
+   }
+ }
```

Event occuring today:

```diff
- .fc-list-event.fc-event-today {
+ .my-list-event-today {
  /* custom css */
}

// in JS
+ views: {
+   list: {
+     listItemEventClass: (data) => clsx(data.isToday && 'my-list-event-today')
+   }
+ }
```

Bullet-point sub-element's size (only for **Classic Theme**):

```diff
  :root {
-   --fc-list-event-dot-width: 10px;
+   --fc-classic-large-dot-width: 10px;
  }
```

Bullet-point sub-element custom CSS:

```diff
- .fc-list-event-dot {
+ .my-list-event-dot {
  /* custom css */
}

// in JS
+ views: {
+   list: {
+     listItemEventBeforeClass: 'my-list-event-dot'
+   }
+ }
```

Time sub-element

```diff
- .fc-list-event-time {
+ .my-list-event-time {
  /* custom css */
}

// in JS
+ views: {
+   list: {
+     listItemEventTimeClass: 'my-list-event-time'
+   }
+ }
```

Title sub-element:

```diff
- .fc-list-event-title {
+ .my-list-event-title {
  /* custom css */
}

// in JS
+ views: {
+   list: {
+     listItemEventTitleClass: 'my-list-event-title'
+   }
+ }
```

Event colors (for **Classic Theme** only):

```diff
  :root {
-   --fc-list-event-hover-bg-color: #f3f4f6;
+   --fc-classic-muted: #f3f4f6; /* now uses a general-purpose neutral color */
  }
```

### No-events Screen

```diff
- .fc-list-empty {
+ .my-no-events {
  /* custom css */
}

// in JS
+ noEventsClass: 'my-no-events'
```

Inner wrapper:

```diff
- .fc-list-empty-cushion {
+ .my-no-events-inner {
  /* custom css */
}

// in JS
+ noEventsInnerClass: 'my-no-events-inner'
```

### No Replacement

```diff
- .fc-list-sticky {} /* day-headers are always sticky now. TODO: changelog */
- .fc-list-event-graphic {} /* wrapper for dot. style that instead */
- .fc-event-forced-url {}
```

## MultiMonth View

View root element:

```diff
- .fc-multimonth {
+ .my-multimonth-view {
  /* custom CSS */
}

// in JS
+ views: {
+   multiMonth: {
+     viewClass: 'my-multimonth-view'
+   }
+ }
```

### View States

No longer put on the view root...

Single-column:

```diff
- .fc-multimonth-singlecol .fc-multimonth-month {
+ .my-month-singlecol {
  /* custom CSS */
}
- .fc-multimonth-singlecol .fc-multimonth-header {
+ .my-month-header-singlecol {
  /* custom CSS */
}

// in JS settings
+ singleMonthClass: (data) => clsx((data.multiMonthColumns === 1) && 'my-month-singlecol')
+ singleMonthHeaderClass: (data) => clsx((data.multiMonthColumns === 1) && 'my-month-header-singlecol')
```

Multiple columns:

```diff
- .fc-multimonth-multicol .fc-multimonth-month {
+ .my-month-multicol {
  /* custom CSS */
}
- .fc-multimonth-multicol .fc-multimonth-header {
+ .my-month-header-multicol {
  /* custom CSS */
}

// in JS settings
+ singleMonthClass: (data) => clsx((data.multiMonthColumns > 1) && 'my-month-multicol')
+ singleMonthHeaderClass: (data) => clsx((data.multiMonthColumns > 1) && 'my-month-header-multicol')
```

Narrow single-months:

```diff
- .fc-multimonth-compact .fc-multimonth-month {
+ .my-month-narrow {
  /* custom CSS */
}
- .fc-multimonth-compact .fc-multimonth-header {
+ .my-month-header-narrow {
  /* custom CSS */
}
- .fc-multimonth-compact .fc-col-header-cell {
+ .my-day-header-narrow {
  /* custom CSS */
}
- .fc-multimonth-compact .fc-daygrid-day {
+ .my-cell-narrow {
  /* custom CSS */
}
- .fc-multimonth-compact .fc-h-event {
+ .my-row-event-narrow {
  /* custom CSS */
}

// in JS settings
+ singleMonthClass: (data) => clsx(data.isNarrow && 'my-month-narrow')
+ singleMonthHeaderClass: (data) => clsx(data.isNarrow && 'my-month-header-narrow')
+ dayHeaderClass: (data) => clsx(data.isNarrow && 'my-day-header-narrow')
+ dayCellClass: (data) => clsx(data.isNarrow && 'my-cell-narrow')
+ rowEventClass: (data) => clsx(data.isNarrow && 'my-row-event-narrow')
```

### Single Month

```diff
- .fc-multimonth-month {
+ .my-single-month {
  /* custom CSS */
}

// in JS
+ singleMonthClass: 'my-single-month'
```

Single-month header like wraps "January 2025":

```diff
- .fc-multimonth-title {
+ .my-single-month-header {
  /* custom CSS */
}

// in JS
+ singleMonthHeaderClass: 'my-single-month-header'
```

Single-month header section for DAY-HEADERS:

```diff
- .fc-multimonth-header { /* OR .fc-multimonth-header-table */
+ .my-single-month-table-header {
  /* custom CSS */
}

// in JS
+ views: {
+   multiMonth: {
+     tableHeaderClass: 'my-single-month-table-header'
+   }
+ }
```

Single-month body section for DAY-CELLS:

```diff
- .fc-multimonth-daygrid { /* OR .fc-multimonth-daygrid-table */
+ .my-single-month-table-body {
  /* custom CSS */
}

// in JS
+ views: {
+   multiMonth: {
+     tableBodyClass: 'my-single-month-table-body'
+   }
+ }
```

## Timeline View

View root element:

```diff
- .fc-timeline { /* OR .fc-timeline .fc-scrollgrid */
+ .my-timeline-view {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     viewClass: 'my-timeline-view'
+   }
+ }
```

### View States

Timeline view with time slots (as opposed to day/week/month slots):

```diff
- .fc-timeline-header-row-chrono .fc-timeline-slot-frame {
-   justify-content: flex-start;
- }
+ .my-timeline-slot-header-chrono {
+   align-items: flex-start;
+ }

// in JS settings
+ views: {
+   timeline: {
+     slotHeaderClass: (data) => clsx(data.isTime && 'my-timeline-slot-header-chrono')
+   }
+ }
```

Timeline view with overlap enabled:

```diff
- .fc-timeline-overlap-enabled .fc-timeline-events { /* event container */
-   padding-bottom: 20px; /* creates extra padding under events */
- }
+ .my-timeline-lane-bottom-spacious {
+   min-height: 20px;
+ }

// in JS settings
+ resourceLaneBottomClass: (data) => clsx(data.options.eventOverlap && 'my-timeline-lane-bottom-spacious')
```

Timeline view with overlap disabled:

```diff
- .fc-timeline-overlap-disabled .fc-timeline-event {
+ .my-timeline-event-inner-chunky {
  padding-top: 10px;
  padding-bottom: 10px;
}

// in JS settings
+ views: {
+   timeline: {
+     rowEventInnerClass: (data) => clsx(!data.options.eventOverlap && 'my-timeline-event-inner-chunky')
+   }
+ }
```

### Table Structure

Header section:

```diff
- .fc-timeline .fc-scrollgrid-section-header {
+ .my-timeline-view-header {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     tableHeaderClass: 'my-timeline-view-header'
+   }
+ }
```

Sticky header section:

```diff
- .fc-timeline .fc-scrollgrid-section-sticky {
+ .my-timeline-header-sticky {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     tableHeaderClass: (data) => clsx(data.isSticky && 'my-timeline-header-sticky')
+   }
+ }
```

Body section:

```diff
- .fc-timeline .fc-scrollgrid-section-body { /* OR .fc-timeline-body */
+ .my-timeline-body {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     tableBodyClass: 'my-timeline-body'
+   }
+ }
```

### Time Slots

Row of slot labels (aka slot headers):

```diff
- .fc-timeline-header-row {
+ .my-timeline-header-row {
  /* custom CSS */
}

// in JS
+ slotHeaderRowClass: 'my-timeline-header-row'
```

Slot label cell (aka header cell):

```diff
- .fc-timeline-slot-label {
+ .my-timeline-slot-header {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     slotHeaderClass: 'my-timeline-slot-header'
+   }
+ }
```

Slot label cell inner wrapper:

```diff
- .fc-timeline-slot-cushion {
+ .my-timeline-slot-header-inner {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     slotHeaderInnerClass: 'my-timeline-slot-header-inner'
+   }
+ }
```

Targets slot label AND slot lane:

```diff
- .fc-timeline-slot { /* OR .fc-timeline .fc-slot */
-                     /* OR .fc-timeline .fc-day */
+ .my-timeline-slot {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     slotHeaderClass: 'my-timeline-slot',
+     slotLaneClass: 'my-timeline-slot',
+   }
+ }
```

Dotted minor slot (label AND lane):

```diff
- .fc-timeline-slot-minor {
+ .my-timeline-slot-minor {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     slotHeaderClass: (data) => clsx(data.isMinor && 'my-timeline-slot-minor'),
+     slotLaneClass: (data) => clsx(data.isMinor && 'my-timeline-slot-minor'),
+   }
+ }
```

Bolded major slot (label AND lane):

```diff
- .fc-timeline-slot-major { /* OR .fc-timeline-slot-em */
+ .my-timeline-slot-major {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     slotHeaderClass: (data) => clsx(data.isMajor && 'my-timeline-slot-major'),
+     slotLaneClass: (data) => clsx(data.isMajor && 'my-timeline-slot-major'),
+   }
+ }
```

Slot lane:

```diff
- .fc-timeline-slot-lane {
+ .my-timeline-slot-lane {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     slotLaneClass: 'my-timeline-slot-lane'
+   }
+ }
```

### Now Indicator

Arrow:

```diff
- .fc-timeline-now-indicator-arrow {
+ .my-timeline-now-indicator-header {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     nowIndicatorHeaderClass: 'my-timeline-now-indicator-header'
+   }
+ }
```

Line:

```diff
- .fc-timeline-now-indicator-line {
+ .my-timeline-now-indicator-line {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     nowIndicatorLineClass: 'my-timeline-now-indicator-line'
+   }
+ }
```

### More-Link

More-link root element:

```diff
- .fc-timeline-more-link {
+ .my-timeline-more-link {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     rowMoreLinkClass: 'my-timeline-more-link'
+   }
+ }
```

More-link inner wrapper element:

```diff
- .fc-timeline-more-link-inner {
+ .my-timeline-more-link-inner {
  /* custom CSS */
}

// in JS
+ views: {
+   timeline: {
+     rowMoreLinkInnerClass: 'my-timeline-more-link-inner'
+   }
+ }
```

### Events

Base event:

```diff
- .fc-timeline-event {
+ .my-timeline-event {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: 'my-timeline-event'
+   }
+ }
```

When the event segment represents the event's start:

```diff
- .fc-timeline-event.fc-event-start {
+ .my-timeline-event-start {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isStart && 'my-timeline-event-start')
+   }
+ }
```

When the event segment represents the event's end:

```diff
- .fc-timeline-event.fc-event-end {
+ .my-timeline-event-end {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isEnd && 'my-timeline-event-end')
+   }
+ }
```

Future event:

```diff
- .fc-timeline-event.fc-event-future {
+ .my-timeline-event-future {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isFuture && 'my-timeline-event-future')
+   }
+ }
```

Past event:

```diff
- .fc-timeline-event.fc-event-past {
+ .my-timeline-event-past {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isPast && 'my-timeline-event-past')
+   }
+ }
```

Event occuring today:

```diff
- .fc-timeline-event.fc-event-today {
+ .my-timeline-event-today {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isToday && 'my-timeline-event-today')
+   }
+ }
```

Selected state:

```diff
- .fc-timeline-event.fc-event-selected {
+ .my-timeline-event-selected {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isSelected && 'my-timeline-event-selected')
+   }
+ }
```

Draggable state:

```diff
- .fc-timeline-event.fc-event-draggable {
+ .my-timeline-event-draggable {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isDraggable && 'my-timeline-event-draggable')
+   }
+ }
```

Dragging state:

```diff
- .fc-timeline-event.fc-event-dragging {
+ .my-timeline-event-dragging {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isDragging && 'my-timeline-event-dragging')
+   }
+ }
```

Event "mirror" that appears during dragging/resize:

```diff
- .fc-timeline-event.fc-event-mirror {
+ .my-timeline-event-mirror {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isMirror && 'my-timeline-event-mirror')
+   }
+ }
```

Resizable state:

```diff
- .fc-timeline-event.fc-event-resizable {
+ .my-timeline-event-resizable {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) =>
+       clsx((data.isStartResizable || data.isEndResizable) && 'my-timeline-event-resizable')
+   }
+ }
```

Resizing state:

```diff
- .fc-timeline-event.fc-event-resizing {
+ .my-timeline-event-resizing {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventClass: (data) => clsx(data.isResizing && 'my-timeline-event-resizing')
+   }
+ }
```

The resizer sub-element:

```diff
- .fc-timeline-event .fc-event-resizer {
+ .my-timeline-event-resizer {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-timeline-event-resizer'),
+     rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-timeline-event-resizer')
+   }
+ }
```

The start-resizer sub-element:

```diff
- .fc-timeline-event .fc-event-resizer-start {
+ .my-timeline-event-resizer-start {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-timeline-event-resizer-start')
+   }
+ }
```

The end-resizer sub-element:

```diff
- .fc-timeline-event .fc-event-resizer-end {
+ .my-timeline-event-resizer-end {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-timeline-event-resizer-end')
+   }
+ }
```

Continuation arrow in start-direction:

```diff
- .fc-timeline-event:not(.fc-event-start):before {
+ .my-timeline-event-start-contd {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeline: {
+     rowEventBeforeClass: (data) => clsx(!data.isStart && 'my-timeline-event-start-contd')
+   }
+ }
```

Continuation arrow in end-direction:

```diff
- .fc-timeline-event:not(.fc-event-end):after {
+ .my-timeline-event-end-contd {
  /* custom CSS */
}

// in JS settings
+ views: {
+   timeline: {
+     rowEventAfterClass: (data) => clsx(!data.isEnd && 'my-timeline-event-end-contd')
+   }
+ }
```

The inner-element that wraps the time and title:

```diff
- .fc-timeline-event .fc-event-main {
+ .my-timeline-event-main {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventInnerClass: 'my-timeline-event-main'
+   }
+ }
```

Time sub-element:

```diff
- .fc-timeline-event .fc-event-time {
+ .my-timeline-event-time {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventTimeClass: 'my-timeline-event-time'
+   }
+ }
```

Title sub-element:

```diff
- .fc-timeline-event .fc-event-title {
+ .my-timeline-event-title {
  /* custom css */
}

// in JS
+ views: {
+   timeline: {
+     rowEventTitleClass: 'my-timeline-event-title'
+   }
+ }
```

### No Replacement

```diff
- .fc-timeline-header /* is the header but ONLY for the timeline area */
- .fc-timeline-event-harness
- .fc-timeline-bg
- .fc-timeline-bg-harness
- .fc-timeline-body-expandrows
- .fc-timeline-events /* see top/bottom tho */
- .fc-timeline-slots
- .fc-timeline-lane-frame
- .fc-timeline-lane-misc /* no longer allow injecting content in "inner", but see "top"/"bottom" */
- .fc-timeline-slot-frame
- .fc-timeline-now-indicator-container
```

## Resource Timeline View

View root element:

```diff
- .fc-resource-timeline {
+ .my-resource-timeline-view {
  /* custom CSS */
}

// in JS settings
+ views: {
+   resourceTimeline: {
+     viewClass: 'my-resource-timeline-view'
+   }
+ }
```

### Data Grid

Datagrid ANY cell:

```diff
- .fc-datagrid-cell {
+ .my-any-cell {
  /* custom CSS */
}

// in JS settings
+ resourceColumnHeaderClass: 'my-any-cell',
+ resourceGroupHeaderClass: 'my-any-cell',
+ resourceCellClass: 'my-any-cell',
```

Inner wrapper within ANY datagrid cell:

```diff
- .fc-datagrid-cell-cushion { /* OR .fc-datagrid-cell-main */
+ .my-any-cell-inner {
  /* custom CSS */
}

// in JS settings
+ resourceColumnHeaderInnerClass: 'my-any-cell-inner',
+ resourceGroupHeaderInnerClass: 'my-any-cell-inner',
+ resourceCellInnerClass: 'my-any-cell-inner',
```

Datagrid header cell:

```diff
- .fc-datagrid-header .fc-datagrid-cell {
+ .my-header-cell {
  /* custom CSS */
}

// in JS settings
+ resourceColumnHeaderClass: 'my-header-cell',
```

Datagrid header cell that encompasses other header cells beneath:

<!--
TODO: implement resourceColumnHeaderClass({ level })
-->

```diff
- .fc-datagrid-cell-super {
+ .my-header-super {
  /* custom CSS */
}

// in JS settings
+ resourceColumnHeaderClass: (data) => clsx((data.level > 0) && 'my-header-super')
```

Column resizer in header:

```diff
- .fc-datagrid-cell-resizer {
+ .my-resizer {
  /* custom CSS */
}

// in JS settings
+ resourceColumnResizerClass: 'my-resizer',
```

Datagrid row-group cell (is a row "header" that lives in the body):

```diff
- .fc-datagrid-cell.fc-resource-group {
+ .my-resource-group-header {
  /* custom CSS */
}

// in JS settings
+ resourceGroupHeaderClass: 'my-resource-group-header',
```

Datagrid resource-specific cell in body:

```diff
- .fc-datagrid-cell.fc-resource {
+ .my-resource-cell {
  /* custom CSS */
}

// in JS settings
+ resourceCellClass: 'my-resource-cell',
```

For datagrids with row hierarchy, the space force at the beginning of each row:

```diff
- .fc-datagrid-expander-placeholder {
+ .my-resource-indent {
  /* custom CSS */
}

// in JS settings
+ resourceIndentClass: 'my-resource-indent',
```

For datagrids with row hierarchy, the expander icon for each row:

```diff
- .fc-datagrid-expander { /* OR .fc-datagrid-expander .fc-icon */
+ .my-expander {
  /* custom CSS */
}

// in JS settings
+ resourceExpanderClass: 'my-expander'
```

Expander icon in different expanded states:

```diff
- .fc-icon-minus-square {
+ .my-expander-expanded {
  /* custom CSS */
}

- .fc-icon-plus-square {
+ .my-expander-collapsed {
  /* custom CSS */
}

+ resourceExpanderClass: (data) => (
+   data.isExpanded ? 'my-expander-expanded' : 'my-expander-collapsed'
+ )
```

### Divider

Divider between datagrid & timeline area:

```diff
- .fc-resource-timeline-divider {
+ .my-resource-column-divider {
  /* custom CSS */
}

// in JS settings
+ views: {
+   resourceColumnDividerClass: 'my-resource-column-divider'
+ }
```

### Timeline Area

Targets both resource lanes & resource-group lanes:

```diff
- .fc-timeline-lane {
+ .my-lane {
  /* custom CSS */
}

// in JS settings
+ resourceLaneClass: 'my-lane'
+ resourceGroupLaneClass: 'my-lane'
```

Resource lane:

```diff
- .fc-timeline-lane.fc-resource {
+ .my-resource-lane {
  /* custom CSS */
}

// in JS settings
+ resourceLaneClass: 'my-resource-lane'
```

Resource group lane:

```diff
- .fc-timeline-lane.fc-resource-group {
+ .my-resource-group-lane {
  /* custom CSS */
}

// in JS settings
+ resourceGroupLaneClass: 'my-resource-group-lane'
```

### No Replacement

```diff
- .fc-resource-timeline-flat {} /* see resourceIndentClass */
- .fc-datagrid-header {} /* ONLY above datagrid */
- .fc-datagrid-body {} /* ONLY for datagrid */
- .fc-datagrid-cell-frame {}
- .fc-datagrid-cell-frame-liquid {}
- .fc-main-col {}
```

</div>
</div>
