# Combine Calendars: Deduplicate Shared Events Source: https://docs.daylightcalendar.com/advanced/combine-calendars Use combine_calendars to merge duplicate events across multiple Home Assistant calendars, with bars, stripes, or dots styles to mark combined event chips. A common problem in multi-calendar setups is that the same event appears more than once — for example, a family dinner added to both a shared household calendar and a personal calendar, or a team meeting that shows up in both a project calendar and an individual calendar. Without any deduplication, the card renders these as separate event chips stacked on the same day, which makes the view feel noisy and harder to read. Enabling `combine_calendars` tells the card to detect these duplicates and merge them into a single display event, with a configurable visual indicator that communicates the event spans more than one calendar source. ## How Deduplication Works When `combine_calendars` is `true`, the card compares every event loaded from your calendar entities. Two events are considered duplicates if they share the same normalized **title**, **start time**, **end time**, and **location**. When a match is found, the events are merged into one chip, and a small indicator is added to show that the event came from multiple sources. The merged event inherits the color of the first matching source calendar unless overridden by an `event_styles` rule. ## Configuration Set to `true` to enable event deduplication. When enabled, events with identical title, start time, end time, and location are merged into a single display event. The visual style used to indicate that a displayed event was combined from multiple calendar sources. Accepted values: * **`bars`** — parallel colored bars along the side of the event chip, one per source calendar * **`stripes`** — a diagonal stripe pattern on the event chip background * **`dots`** — small colored dots displayed on the event chip, one per source calendar Controls the background color applied to combined events. Accepted values: * **`primary`** — uses the color of the primary (first) source calendar * **`neutral`** — uses a neutral gray that does not favor any single calendar * A **hex color string** (e.g. `'#E8EAF6'`) — applies a fixed custom color to all combined events The width in pixels of the combine indicator strip rendered on the event chip. Increase this value if you want the bars, stripes, or dots to be more prominent. ## Example The following configuration loads three calendar entities and merges any events that appear in more than one of them, displaying a colored bar strip on combined events. ```yaml theme={null} type: custom:daylight-calendar-card entities: - calendar.family - calendar.personal - calendar.work combine_calendars: true combine_style: bars combine_background: primary combine_calendars_width: 18 ``` ## Using All Three Combine Styles Choose the style that best fits your card's visual theme: ```yaml theme={null} # Bars — clear per-calendar color strips on the event side combine_style: bars # Stripes — subtle diagonal texture across the event background combine_style: stripes # Dots — compact colored dot indicators combine_style: dots ``` Deduplication requires an **exact match** on title, start time, end time, and location. If the same real-world event is stored with slightly different times across calendars — for example, due to timezone conversion differences of even one minute — the events will **not** be merged and will appear as separate chips. If you notice duplicates that are not being merged, check whether the title, event times, and location are truly identical in both calendar sources. `combine_calendars` pairs well with `virtual_calendars`. Group related calendar entities under a virtual calendar for a unified toggle in the header, and enable `combine_calendars` to ensure that shared events from those grouped entities only appear once on the card. Need finer visual control than the built-in options provide? The card also accepts a YAML-only [`uix.style`](/advanced/uix) escape hatch for injecting raw CSS into its shadow DOM. # Day Badges: Add Custom Indicators to Calendar Days Source: https://docs.daylightcalendar.com/advanced/day-badges Configure day_badges rules to display text labels, icons, or icon-and-text chips on calendar days matched by event title, calendar source, or day conditions. Day badges are small labeled chips or icon indicators that appear on individual calendar day cells when a set of conditions is met. A badge can show text, an icon, or an icon followed by text in the same chip. You define a list of badge objects under `day_badges`, and the card evaluates every badge against the day and its events — showing the badge on any day that satisfies the badge's match block. Multiple badges can appear on the same day simultaneously, which makes them well-suited for layered annotations like recurring schedule reminders, birthday markers, or availability flags. ## Badge Fields Each entry in `day_badges` supports the following fields: Advanced match block using the [shared match schema](/advanced/event-styles#advanced-match-schema). Use this to combine event and day conditions, e.g. `match: { event: { title_contains: 'Soccer' }, day: { weekend: true } }`, or to use logical operators (`any`, `all`, `not`). `when` is accepted as an alias. Legacy shorthand for event-scoped matches. Equivalent to `match: { event: { ... } }`. At least one event on the day must satisfy **all** specified conditions for the badge to appear. Either `match` or `conditions` is required. Optional ordering hint used by tooling. Badges are evaluated independently and all matching badges are shown, so priority does not suppress other badges. Optional string identifier. Auto-generated (`day-badge-1`, `day-badge-2`, …) if omitted. The text label displayed inside the badge chip. You can use `text` by itself or combine it with `icon` to show an icon followed by the label in the same badge. An MDI icon name (e.g. `mdi:cake-variant`) displayed inside the badge. When `text` is also provided, the icon appears first, followed by the text, inside one badge. A hex color string for the badge's background. Defaults to the card's accent color if not specified. A hex color string for the badge's foreground (text and icon color). Controls the contrast against `background_color`. If omitted, the card picks a readable color automatically. Overrides the overall size of the badge chip. Accepts a number (interpreted as pixels) or a CSS length string such as `'32px'`. Overrides the font size of the badge label text. Accepts a number (interpreted as pixels) or a CSS length string such as `'11px'`. ## Condition Keys The `conditions` object matches against events on each day. All specified keys must match at least one event on that day for the badge to appear. The following fields are supported: A Home Assistant calendar entity ID (or virtual calendar ID). The badge appears on days where at least one event belongs to that calendar. A substring to match against event titles on a given day. The badge appears on days that have at least one event whose title contains this string. Prefix with `exact:` for an exact match or `regex:` for a regular expression. Alias for `conditions.title`. Both names match the event summary field. A substring to match against the event description field. Supports the same `exact:` and `regex:` prefixes as `title`. A substring to match against the event location field. Supports the same `exact:` and `regex:` prefixes as `title`. When `true`, the badge appears only on days that have at least one all-day event. When `false`, only days with at least one timed event match. When `true`, the badge appears on days where at least one event is in the past. When `false`, only days with non-past events match. Text conditions accept a plain string or a matcher object, but operators such as `contains` accept one string, not an array. In `day_badges`, bare event conditions are supported under `match.any`, so use a separate condition for each value. See [Text matching](/advanced/event-styles#text-matching) for the shared text operators; other rule types may require explicit event scoping. ### Day-scoped badges Badges can also fire purely from day-level state (no event required) by using `match.day`. For example, mark every weekend with a chip: ```yaml theme={null} day_badges: - match: day: weekend: true text: Weekend background_color: '#FF9800' ``` Or mark days that have **no** events from a given calendar: ```yaml theme={null} day_badges: - match: day: no_event: calendar: calendar.work icon: mdi:beach background_color: '#4CAF50' ``` See [Day match fields](/advanced/day-styles#day-match-fields) for the full list of day conditions. ### Legacy condition aliases For backward compatibility, the card silently accepts several alternative spellings of the condition keys above. New configurations should use the canonical names (`title`, `summary`, `location`, `calendar`, `all_day`), but the following aliases continue to work: | Alias | Equivalent to | | - | - | | `title_contains: foo` | `title: 'contains:foo'` | | `summary_contains: foo` | `summary: 'contains:foo'` (same as `title`) | | `location_contains: foo` | `location: 'contains:foo'` | | `calendar_entity` | `calendar` | | `entity_id` | `calendar` | | `entity` | `calendar` | | `all_day_event` | `all_day` (bidirectional) | ## Examples ### Show a cake icon on days with birthday events This badge watches `calendar.birthdays` and renders a pink cake icon on any day that calendar has an event. ```yaml theme={null} day_badges: - conditions: calendar: calendar.birthdays icon: mdi:cake-variant background_color: '#E91E63' ``` ### Show a badge on days with a standup meeting This badge appears on any day that has an event whose title contains "standup", making it easy to spot those days at a glance. ```yaml theme={null} day_badges: - conditions: title: standup text: Standup background_color: '#1565C0' ``` ### Show an icon and text in one badge Set both `icon` and `text` on the same badge when you want a compact chip with an MDI icon followed by a label. The card renders this as one badge, not two separate badges. ```yaml theme={null} day_badges: - conditions: calendar: calendar.helper_day_types all_day: true title: Schoolday icon: mdi:school text: School background_color: '#EDE7F6' ``` ### Use values from matched event metadata Badge display fields can reference simple values from the event that matched the badge conditions. This is useful when a helper calendar stores day classification metadata in the event description. Only full-value path templates are supported. The whole string must be a template like `{{ event.description_json.badge_text }}`. Partial strings such as `Type: {{ event.description_json.badge_text }}` are not interpolated and remain literal text. ```yaml theme={null} day_badges: - conditions: calendar: calendar.helper_day_types all_day: true icon: "{{ event.description_json.icon }}" text: "{{ event.description_json.badge_text }}" background_color: "{{ event.description_json.badge_color }}" ``` The matched helper event description can contain a JSON object like this: ```json theme={null} { "icon": "mdi:school", "badge_text": "School", "badge_color": "#EDE7F6" } ``` This renders one badge with the `mdi:school` icon, the `School` label, and the `#EDE7F6` background color. Supported dynamic display fields are `icon`, `text`, `background_color`, and `color`. Available paths include `event.description_json.`, `event.title`, `event.summary`, `event.calendar`, `event.entity_id`, `title`, `calendar`, and `date`. Dynamic badge values are intentionally narrow in scope: * This is not a general-purpose template engine. * JavaScript, expressions, function calls, conditionals, filters, arithmetic, bracket access, and mixed string interpolation are not supported. * Invalid JSON descriptions are ignored. * Missing fields are ignored safely. * Values that resolve to objects or arrays are ignored for display fields. * Dynamic `background_color` and `color` values must resolve to supported CSS color formats, such as hex, `rgb()`/`rgba()`, `hsl()`/`hsla()`, or a recognized named color. Invalid color values are ignored. * Dynamic resolution applies only to `day_badges` display fields and `tap_action.event_data`, not matching, priority, or hidden calendar rules. ### Fire a DOM event when tapping a badge You can make an individual day badge clickable by adding `tap_action`. Currently, day badges support only `action: fire-dom-event`. Other Home Assistant actions such as `navigate`, `url`, `call-service`, `more-info`, `hold_action`, and `double_tap_action` are not supported for day badges. `tap_action.event_data` supports the same safe full-value templates as dynamic badge text, icon, and color. Values can resolve from `date`, `calendar`, `title`, `event`, and `event.description_json`. Only scalar string, number, and boolean values are included in the dispatched event detail. ```yaml theme={null} day_badges: - conditions: calendar: calendar.helper_day_types all_day: true title: Schoolday icon: "{{ event.description_json.icon }}" text: "{{ event.description_json.badge_text }}" background_color: "{{ event.description_json.badge_color }}" tap_action: action: fire-dom-event event_type: open-day-detail event_data: date: "{{ date }}" calendar: "{{ calendar }}" title: "{{ title }}" ``` When tapped, the card dispatches a bubbling, composed `CustomEvent` named `open-day-detail`. The event `detail` contains the resolved `event_data` values. ### Mark all-day event days with an indicator This badge shows a calendar icon on every day that has at least one all-day event. ```yaml theme={null} day_badges: - conditions: all_day: true icon: mdi:calendar-today background_color: '#FF9800' ``` ### Combine conditions for precise targeting You can stack multiple conditions in one badge. This example shows a star icon only on days that have an event from `calendar.work` with "review" in the title. ```yaml theme={null} day_badges: - conditions: calendar: calendar.work title: review icon: mdi:star background_color: '#FFC107' ``` ### Show multiple badges on the same day All badge definitions are evaluated independently, so more than one can appear on the same day. Here, a day that has both a birthday event and a work standup will show both the cake icon and the "Standup" chip. ```yaml theme={null} day_badges: - conditions: calendar: calendar.birthdays icon: mdi:cake-variant background_color: '#E91E63' - conditions: title: standup text: Standup background_color: '#1565C0' ``` # Day Styles: Highlight and Color Calendar Days Source: https://docs.daylightcalendar.com/advanced/day-styles Use day_styles rules to apply custom background colors, borders, and opacity to calendar days based on conditions like today, weekend, or has_event. The `day_styles` configuration lets you define a list of rules that change how individual calendar day cells look. Each rule pairs a `match` block (or the legacy `condition` shorthand) with a `style` object, and an optional `priority` integer decides which rule wins when multiple rules set the same property on the same day. Use this feature to visually distinguish weekends from weekdays, draw attention to today's cell, dim days in the past, or automatically tint days that have events scheduled. ## Rule Structure Each entry in `day_styles` accepts the following top-level keys: * **`match`** — describes which days the rule applies to using the [shared advanced match schema](/advanced/event-styles#advanced-match-schema). `when` is accepted as an alias. * **`condition`** — legacy shorthand for simple day rules (see [Legacy condition shorthand](#legacy-condition-shorthand) below). Still fully supported. * **`style`** — the visual properties to apply to matching days. Style fields may also be written at the top level of the rule (sibling to `condition`). * **`priority`** — optional integer (default `0`) that resolves conflicts when multiple rules set the same property on the same day. Conflicts are resolved **per property** — see [Priority](#priority). * **`id`** — optional string identifier. Auto-generated (`day-style-1`, `day-style-2`, …) if omitted. ## Day match fields Use one or more of the following fields inside `match.day` to filter by date properties. By default, a day must satisfy **all** specified fields to match. When `true`, matches only the current day. When `false`, matches every day except today. When `true`, matches days strictly before today. When `false`, matches today and future days. When `true`, matches days strictly after today. When `false`, matches today and past days. When `true`, matches Saturdays and Sundays. When `true`, matches Mondays through Fridays. One or more weekdays. Accepts numbers (0 = Sunday, 6 = Saturday), weekday names (`'Monday'`, `'Tue'`, etc.) honoring the card's locale, or an array mixing the two. When `true`, matches days that have at least one event. When set to an object, the value is treated as an event match — only days with at least one event satisfying that match qualify. For example, `has_event: { title_contains: 'Soccer', calendar: 'calendar.school' }` matches any day with a Soccer event on `calendar.school`. The matched event is also used to resolve `background: 'auto'`. Inverse of `has_event`. When `true`, matches days with no events. When set to an object, matches days where **no** event satisfies that sub-match. You can also nest event-scoped conditions under `match.event` and combine blocks with `match.any`, `match.all`, `match.and`, and `match.not` — see the [shared advanced match schema](/advanced/event-styles#advanced-match-schema). Text fields accept a plain string or a matcher object, but each text operator takes one string. To match multiple event text values in `day_styles`, put each alternative in an explicit `event` block under `match.any`; do not copy the event-style shorthand or pass an array to `contains`. See [Text matching](/advanced/event-styles#text-matching) for the shared text operators. ```yaml theme={null} match: any: - event: title: "Dentist" - event: title: "Annual Leave" ``` ### Example: only weekdays in the future ```yaml theme={null} day_styles: - match: day: weekday: true future: true style: background_color: '#FFF8E1' ``` ### Example: days with a Soccer event on the school calendar ```yaml theme={null} day_styles: - match: day: has_event: calendar: calendar.school title_contains: Soccer style: background_color: auto ``` ### Example: workdays without any meetings ```yaml theme={null} day_styles: - match: day: weekday: true no_event: calendar: calendar.work style: opacity: 0.5 ``` ## Legacy condition shorthand The original `condition` form continues to work and is automatically converted into the advanced `match` schema at load time. Existing configurations do not need to change. One of the following named conditions. A day matches when it satisfies the specified condition. | Value | Matches | | - | - | | `today` | The current calendar day | | `past` | Any day before today | | `future` | Any day after today | | `weekend` | Saturday or Sunday | | `weekday` | Monday through Friday | | `has_event` | Any day that has at least one visible event from a specific calendar (requires the `calendar` sibling key) | | `day_of_week` | A specific weekday (requires the `day_of_week` sibling key — see below) | ### Using `day_of_week` When `condition` is `day_of_week`, add a sibling `day_of_week` key with the target day number (0 = Sunday, 6 = Saturday). You can also provide a list of numbers to match multiple days with one rule. ```yaml theme={null} day_styles: - condition: day_of_week day_of_week: 1 # Monday style: background_color: '#E3F2FD' ``` ### Using `has_event` When `condition` is `has_event`, you must also provide a `calendar` sibling key containing the entity ID (or virtual calendar ID) to watch. The rule only applies to days where that specific calendar has at least one event. A legacy `has_event` rule without `calendar` (or `title_match`) is ignored — use the advanced `match.day.has_event: true` form instead if you want to match any event. You can optionally narrow the rule further by adding a `title_match` sibling key. When set, the rule only matches days where the named calendar has at least one event whose title contains the given string. `title_match` uses the same single-string matching syntax as `event_styles` and `day_badges` — prefix the value with `exact:` for an exact match or `regex:` for a regular expression. It does not accept an array; use the event-scoped `match.any` form shown above for multiple titles. See [Text matching](/advanced/event-styles#text-matching). ```yaml theme={null} # Any event on calendar.work makes the day match day_styles: - condition: has_event calendar: calendar.work style: background_color: '#FFF9C4' # Only days where calendar.work has a "standup" event match day_styles: - condition: has_event calendar: calendar.work title_match: standup style: background_color: '#E3F2FD' border_color: '#1565C0' border_width: 2 ``` ## Style Fields A hex color string applied to the day cell's background. You can also pass `'auto'` to let the card automatically compute a soft tint derived from the event colors present on that day. A number between `0` and `1` that controls the day cell's overall transparency. A hex color string for the day cell's border. The border width in pixels. ## Priority When two or more rules match the same day, conflicts are resolved **per style property** (`background`, `opacity`, `border_color`, `border_width`). For each property, the rule with the highest `priority` wins; ties go to the rule defined earlier in the list. Style properties not set by the winning rule fall through to the next matching rule, so e.g. one rule can supply the background and a lower-priority rule can still contribute the opacity. ## Convenience Shorthands In addition to the full `day_styles` list, the card also accepts a pair of shorthand options for styling today's cell. These are processed as `day_styles` rules internally and are a quick alternative to writing a full condition block. A hex color shorthand for setting today's background. Equivalent to a `day_styles` rule with `condition: today` and `style.background_color` set to the same value. An object with any combination of `background_color`, `opacity`, `border_color`, and `border_width` applied to today's cell. ```yaml theme={null} today_style: background_color: '#E3F2FD' border_color: '#1565C0' border_width: 2 ``` ## Examples ### Highlight weekends with a light gray background This rule gives Saturday and Sunday cells a subtle gray tint to help them stand out from the work week. ```yaml theme={null} day_styles: - condition: weekend style: background_color: '#F5F5F5' ``` ### Show today with a bold blue background A high `priority` of `10` ensures this rule overrides any other day style that might also match today, such as `weekend`. ```yaml theme={null} day_styles: - condition: today style: background_color: '#1565C0' priority: 10 ``` ### Dim past days This rule reduces the opacity of every day in the past, creating a visual separation between what has happened and what is coming up. ```yaml theme={null} day_styles: - condition: past style: opacity: 0.4 ``` ### Auto-tint days that have events Instead of choosing a fixed background color, pass `'auto'` and let the card compute a soft tint derived from the event colors on each matching day. ```yaml theme={null} day_styles: - condition: has_event calendar: calendar.personal style: background_color: 'auto' ``` ### Combine multiple rules Rules are independent and additive. Here, past days are dimmed, weekends get a warm tint, and today is boldly highlighted above both. ```yaml theme={null} day_styles: - condition: past style: opacity: 0.4 priority: 1 - condition: weekend style: background_color: '#FFF8E1' priority: 2 - condition: today style: background_color: '#1565C0' priority: 10 ``` Use `background_color: 'auto'` on days with events alongside a fixed background color for today. Set a higher `priority` on the today rule so it always wins, even if today has events. # Event Styles: Custom Colors and Icons for Calendar Events Source: https://docs.daylightcalendar.com/advanced/event-styles Use event_styles rules to apply colors, icons, opacity, and hide overrides to Home Assistant calendar events matched by title, calendar, location, or date. The `event_styles` configuration lets you define a list of rules that change how individual events look on your calendar. Each rule specifies which events to target through a `match` object and how to style them through a `style` object. When multiple rules match the same event, conflicts are resolved per style property: the matching rule with the highest `priority` for that property wins. This makes it easy to build layered styling — for example, dimming all past events while still highlighting specific recurring ones at a higher priority. ## Rule Structure Each entry in `event_styles` is a rule with the following top-level keys: * **`match`** — describes which events the rule applies to. `when` is accepted as an alias. * **`style`** — describes how matching events should look * **`priority`** — optional integer (default `0`) that controls which rule wins when multiple rules set the same style property * **`id`** — optional string identifier. Auto-generated (`event-style-1`, `event-style-2`, …) if omitted. `event_styles`, `day_styles`, and `day_badges` all share the same advanced match schema. Anything you learn here applies to the other two rule types. For one-off, per-device recoloring — for example, giving a single event a distinctive color on the family dashboard without changing the calendar — use the [Custom Color](/configuration/event-management#custom-event-colors) action in the event detail modal instead of `event_styles`. Modal overrides win over the `color` / `background_color` set here, but do not affect other style properties. ## Advanced match schema The `match` object supports two scopes and the standard logical operators: * **`match.event`** — event-scoped conditions (title, calendar, all\_day, etc.). For `event_styles`, fields written at the top level of `match` are implicitly treated as event conditions, so `match: { title: 'standup' }` and `match: { event: { title: 'standup' } }` are equivalent. * **`match.day`** — day-scoped conditions (`today`, `weekend`, `has_event`, …). See [Day match fields](/advanced/day-styles#day-match-fields) for the full list. Useful when you want a rule to fire only on certain dates, e.g. weekdays. * **`match.any` / `match.all` / `match.and` / `match.not`** — combine nested match blocks with OR / AND / NOT logic. ### Example: match a calendar only on weekdays ```yaml theme={null} event_styles: - match: event: calendar: calendar.work day: weekday: true style: color: '#1565C0' font_color: '#ffffff' ``` ## Event match fields Use one or more of the following fields inside `match` (or `match.event`) to filter by event properties. By default, an event must satisfy **all** specified fields to be considered a match. For OR / NOT logic, use the [logical operators](#logical-operators) below. A calendar entity ID or substring to match against an event's calendar identifiers. Plain strings use case-insensitive substring matching. Use an `exact` matcher object when an exact value is required. Aliases: `calendar_entity`, `entity_id`, `entity`. A substring to look for in the event title. The match is case-insensitive. You can also pass a regex pattern wrapped in forward slashes, e.g. `/standup/i`. Alias: `title_contains: foo` is equivalent to `title: 'contains:foo'`. Alias for `match.title`. Both names map to the event summary field. Use whichever feels more natural. Alias: `summary_contains`. A substring to look for in the event description field. Alias: `description_contains`. A substring to look for in the event location field. Alias: `location_contains`. When `true`, only matches all-day events. When `false`, only matches timed events. Alias: `all_day_event`. When `true`, only matches events whose end time is in the past. When `false`, only matches events that are not yet past. ## Text matching Plain strings for `title`, `summary`, `description`, `location`, and `calendar` use case-insensitive substring matching by default. Use this simple form for most rules: ```yaml theme={null} match: title: "Dentist" ``` For explicit matching, these fields also accept an object with one of the following operators: * `title: { exact: "Dentist" }` matches the complete value. * `title: { contains: "Dentist" }` uses substring matching. * `title: { substring: "Dentist" }` is equivalent to `contains`. * `title: { regex: "^Dentist appointment$" }` uses a regular expression. Each text operator accepts a **single string**, not a YAML array. For example, this is invalid: ```yaml theme={null} title: contains: ["Dentist"] # Invalid ``` To match multiple possible values, put separate conditions in `match.any`: ```yaml theme={null} match: any: - title: "Dentist" - title: "Annual Leave" ``` Arrays belong to logical operators such as `any` and `all`, not text operators such as `contains`. Event conditions nested in `day_styles` or `day_badges` use the same text matching rules, but follow each rule type's scoping syntax. ## Logical Operators For compound rules, `match` supports four logical operator keys. `any`, `all`, `and`, and `not` each accept either a single sub-condition object or an array of sub-condition objects. Arrays are typically used when combining multiple conditions. Sub-conditions use the same match-field syntax as a top-level `match` block, including nested operators. OR logic. The rule matches when **at least one** of the listed sub-conditions matches. AND logic. The rule matches when **all** listed sub-conditions match. Same as combining fields at the top level, but useful when nesting inside `any` or `not`. Alias for `match.all`. NOT logic. The rule matches when the sub-condition does not match. When given an array, the rule matches only when none of the listed sub-conditions match. ### Example: events on the work OR personal calendar ```yaml theme={null} event_styles: - match: any: - calendar: calendar.work - calendar: calendar.personal style: opacity: 0.6 ``` ### Example: all-day events that are NOT in the past ```yaml theme={null} event_styles: - match: all_day: true not: past: true style: color: '#1565C0' font_color: '#ffffff' ``` ## Style Fields The `style` object accepts the following properties to control how matched events are rendered. Alias for `style.background_color`. Hex color string (e.g. `'#1565C0'`) applied to the event's background or bar color. Hex color string applied to the event's background or bar color. Equivalent to `style.color`. Hex color string applied to the event's text. Use this to ensure readable contrast when you change the background color. Replaces the event title shown in the card with a nonempty fixed string. This changes only the card display; matching, event details, editing, and the source calendar event continue to use the original title. ```yaml theme={null} event_styles: - match: calendar: calendar.family title: exact: "My Long Title Event" style: display_title: "My Event" ``` A plain `match.title` string uses case-insensitive substring matching against the original event title. Use `title: { exact: "…" }`, as shown above, when the alias should apply only to the complete original title. A number between `0` and `1` that controls the event's transparency. Use `0.4` to visually mute events without hiding them entirely. A CSS filter string applied to the event element. For example, `grayscale(100%)` removes all color from matching events. An MDI icon name (e.g. `mdi:repeat`) to attach to matching events. Combine with `icon_position` to control placement. Controls where the icon is rendered. Use `before_title` to place it inline before the event title, or `corner` to display it as a small overlay in the corner of the event chip. Hex color string applied to the matched style icon. Defaults to the event's text color. Overrides the icon size. Accepts a number (interpreted as pixels) or any CSS length string such as `'14px'` or `'1.1em'`. When `true`, matching events are completely removed from the calendar view. Hidden events are not counted toward day event totals. When `true`, suppresses the time label on matching events even if times would otherwise be shown. When `true`, forces the time label to render on matching events even if it would otherwise be hidden (for example, by `hide_times_for_calendars`). When `true`, hides the small calendar-color dot on matching events. Useful when you've added a custom `icon` and don't want the default indicator competing with it. Per-rule override of the global `show_event_location` setting. Set to `true` to force locations on for matching events, or `false` to hide them on matching events only. Per-rule override of the global `use_short_location` setting. Per-rule override of the event title font size. Accepts a number (pixels) or CSS length string. Per-rule override of the event time font size. Accepts a number (pixels) or CSS length string. Per-rule override of the event location font size. Accepts a number (pixels) or CSS length string. Per-rule override of the global `event_title_prefix` mode. Accepted values: `none`, `badge_icon`, `friendly_name`. ## Priority When two or more rules match the same event, conflicts are resolved **per style property**. For each property, the rule with the highest `priority` wins. If priorities are equal, the rule defined earlier in the list wins. Properties that aren't set by the winning rule fall through to the next matching rule, so styles from different rules can compose on the same event. Use `priority` to layer general rules with specific overrides. For example, set a low-priority rule that dims all past events, then add a high-priority rule that keeps a specific calendar's events fully visible regardless. ## Examples ### Color all events from a work calendar This rule applies a deep blue background and white text to every event from `calendar.work`. ```yaml theme={null} event_styles: - match: calendar: calendar.work style: color: '#1565C0' font_color: '#ffffff' ``` ### Hide events titled "Free" This rule completely removes any event whose title contains the word "Free" from the calendar view. ```yaml theme={null} event_styles: - match: title: 'Free' style: hide: true ``` ### Add a corner icon to a specific calendar's events This rule stamps a briefcase icon in the corner of every event from `calendar.work`. A `priority` of `5` ensures it takes precedence over lower-priority color rules. ```yaml theme={null} event_styles: - match: calendar: calendar.work style: icon: mdi:briefcase icon_position: corner priority: 5 ``` ### Mute all-day events with opacity This rule reduces the opacity of all-day events to `0.4`, visually de-emphasizing them without hiding them. ```yaml theme={null} event_styles: - match: all_day: true style: opacity: 0.4 priority: 1 ``` ### Dim past events This rule applies a grayscale filter and reduced opacity to any event that has already passed, giving the calendar a clear visual split between past and upcoming. ```yaml theme={null} event_styles: - match: past: true style: filter: 'grayscale(100%)' opacity: 0.5 priority: 1 ``` ### Combine multiple match conditions You can narrow a rule by specifying more than one match field at the same time. This rule applies a grayscale filter only to past all-day events from a specific calendar. ```yaml theme={null} event_styles: - match: calendar: calendar.holidays all_day: true past: true style: filter: 'grayscale(100%)' opacity: 0.5 priority: 2 ``` All style values are sanitized before they are applied to the DOM. Attempting to inject HTML or JavaScript through a `color`, `filter`, or other style field will be stripped out automatically. # uix: Inject Custom CSS into Daylight Calendar Card Source: https://docs.daylightcalendar.com/advanced/uix Use the uix.style option to inject raw CSS into Daylight Calendar Card's shadow DOM and override internal styling for events, days, and headers. The `uix` option is a YAML-only escape hatch for power users who need low-level visual control beyond what the standard appearance, event-style, and day-style options provide. Set `uix.style` to a raw CSS string and the card injects that CSS directly into its shadow DOM at render time. This lets you override any internal style — spacing, font sizes, element visibility, animation durations — without needing a custom theme or additional frontend resources like Card Mod. `uix.style` is intended for advanced users. Internal class names and CSS variables may change between card releases, so custom `uix` overrides may need updating after card upgrades. ## Configuration A raw CSS string injected into the card's shadow DOM. Use a YAML block scalar (`|`) so newlines and indentation are preserved verbatim. ## Basic Example ```yaml theme={null} type: custom:daylight-calendar-card entities: - calendar.family uix: style: | .day-number { font-weight: 700; } .event-chip { border-radius: 4px; } ``` ## Common Use Cases ### Make day numbers bolder ```yaml theme={null} uix: style: | .day-number { font-weight: 700; font-size: 1.05em; } ``` ### Round event chips ```yaml theme={null} uix: style: | .event-chip { border-radius: 6px; } ``` ### Tighten internal padding ```yaml theme={null} uix: style: | .calendar-body { padding: 4px; } ``` ## When to Use `uix.style` vs Other Options Reach for `uix.style` only when the built-in options don't cover what you need. | Goal | Use | | - | - | | Change event background or icon | [`event_styles`](/advanced/event-styles) | | Highlight a specific day or weekend | [`day_styles`](/advanced/day-styles) | | Add a chip to days with certain events | [`day_badges`](/advanced/day-badges) | | Header colors, background images, density | [Appearance options](/configuration/appearance) | | Anything else not covered above | `uix.style` | ## Cautions CSS injected via `uix.style` is applied as written. Mistyped selectors or invalid declarations can leave the card visually broken — if that happens, remove the `uix` block to restore the default styling. Class names inside the card's shadow DOM are not part of a public API. They may change in any release. If a future upgrade visually breaks your overrides, expect to update the selectors. # Virtual Calendars: Group Calendar Entities into Named Sets Source: https://docs.daylightcalendar.com/advanced/virtual-calendars Use virtual_calendars to combine multiple Home Assistant calendar entities under a single name, color, and icon in the Daylight Calendar Card. If your Home Assistant setup has many calendar entities — for example, a separate calendar for each family member, or different calendars per project — the card header's toggle list can quickly become cluttered. Virtual calendars solve this by letting you group multiple real calendar entities under a single named entry. When a user toggles the virtual calendar on or off in the header, all of its member calendars are shown or hidden together. Events from all grouped entities are aggregated and displayed with the virtual calendar's shared color and icon, giving your view a clean, organized appearance. ## Configuration Virtual calendars are defined as a list under the `virtual_calendars` key. Each entry represents one group. A unique internal identifier for this virtual calendar. This ID is used when referencing the virtual calendar in `event_styles` or `day_styles` match rules. It must be unique across all virtual calendar definitions. The display name shown in the card header's calendar toggle list. A list of real Home Assistant calendar entity IDs to include in this group. Events from all listed entities are combined and treated as belonging to this virtual calendar. A hex color string applied to all events from this virtual calendar. Individual event colors from the source entities are replaced by this shared color. An MDI icon name (e.g. `mdi:account-group`) displayed next to the virtual calendar's name in the header toggle. Each `id` must be unique. If two virtual calendar entries share the same `id`, the card will raise a validation error and may not render correctly. Choose IDs that are descriptive and won't conflict, such as `family`, `work`, or `sports_league`. ## How Virtual Calendars Appear in the Card Virtual calendars replace their member entities in the card header's toggle list — you see the virtual calendar's name and icon instead of the individual entity IDs. Toggling the virtual calendar on or off controls all of its member entities at once. Event chips on the calendar display the virtual calendar's `color` rather than the original entity color, and any `event_styles` or `day_styles` rules that reference the virtual calendar's `id` will match events from all its member entities. ## Using Virtual Calendars with Event Styles You can target a virtual calendar in `event_styles` match rules by using its `id` as you would a normal entity ID in the `calendar` match field. ```yaml theme={null} event_styles: - match: calendar: family style: font_color: '#ffffff' ``` ## Visual Editor Support You can create and manage virtual calendars directly in the card's visual configuration editor without writing YAML. The editor provides fields for name, entity selection, color, and icon for each group. ## Example This configuration creates two virtual calendars: one for family members and one for work-related calendars. ```yaml theme={null} virtual_calendars: - id: family name: Family entities: - calendar.mom - calendar.dad - calendar.kids_school color: '#4CAF50' icon: mdi:account-group - id: work name: Work entities: - calendar.meetings - calendar.deadlines color: '#1565C0' icon: mdi:briefcase ``` With this configuration, the card header shows two toggles — **Family** and **Work** — instead of five separate calendar entity entries. Toggling "Family" off hides events from all three family calendars simultaneously. Pair virtual calendars with `combine_calendars: true` if family members or colleagues share events across their individual calendars. Combined with virtual calendars, duplicate events will be merged and shown once using the primary matching calendar color. If the duplicate sources are inside the same virtual group, that is the virtual calendar color. # Appearance and Colors: Daylight Calendar Card Source: https://docs.daylightcalendar.com/configuration/appearance Customize calendar colors, event color mode, header style, background images, font sizes, and dark mode for the Daylight Calendar Card. The Daylight Calendar Card gives you extensive control over its visual presentation. You can assign distinct colors to each calendar, choose how those colors are applied to event chips, style the header independently from the card body, and even set a background image — all through YAML configuration. Looking for font size, event text, time text, or location text settings? Font-related display options are documented in [Display Options](/configuration/display), including: * `event_font_size` * `event_time_font_size` * `event_location_font_size` * `event_font_colors` ## Calendar Colors A map of calendar entity IDs to hex color strings. Each calendar's events are rendered in the color you specify. If you omit a calendar, the card assigns it an automatic color from its built-in palette. ```yaml theme={null} colors: calendar.family: "#4CAF50" calendar.work: "#2196F3" calendar.holidays_in_united_states: "#FF5722" ``` A map of calendar entity IDs to hex color strings for the text rendered on event chips. Use this when the auto-contrast logic does not produce readable text against your chosen calendar color. ```yaml theme={null} event_font_colors: calendar.family: "#ffffff" calendar.work: "#ffffff" ``` ## Event Color Modes Controls how the calendar color is applied to event chips. Three modes are available: * **`classic`** — the entire event chip background is filled with the calendar color, matching the look of most traditional calendar applications * **`left-neutral`** — the chip has a neutral background with a colored vertical bar on the left edge; good for maintaining readability with dark colors * **`left-tint`** — the chip has a lightly tinted background (derived from the calendar color) with a colored left bar The hex background color applied to event chips when `event_color_mode` is `left-neutral`. Only this option — not `colors` — affects the chip background in this mode. A value from `0` to `100` controlling how strongly the calendar color tints the chip background in `left-tint` mode. `0` produces a fully neutral background; `100` produces a fully saturated background. The width in pixels of the colored left border applied to event chips in `left-neutral` and `left-tint` modes. ## Header Appearance The background color of the card header. Accepts a hex string (e.g. `#1A1A2E`), a CSS variable (e.g. `var(--primary-color)`), or the special value `match-card-background` to make the header blend seamlessly with the card body. The color of text and icon elements inside the header. Accepts a hex string. When omitted, the card calculates a contrasting color automatically based on `header_color`. The transparency of the header background, from `0` (fully opaque) to `100` (fully transparent). Values between these extremes produce a semi-transparent header. Useful when you set a background image and want the image to show through the header. Legacy shortcut for a fully transparent header. When `header_background_opacity` is not set, `true` is equivalent to `header_background_opacity: 100`. ## Card Background The card inherits Home Assistant theme values for its background, border radius, border width, border color, and box shadow. If your active HA theme sets `ha-card-background`, `ha-card-border-radius`, `ha-card-border-width`, `ha-card-border-color`, or `ha-card-box-shadow`, the card picks them up automatically. The built-in light/dark card color is only used as a final fallback when none of those theme values are defined. The transparency of the card body background, from `0` (fully opaque) to `100` (fully transparent). Setting this to `100` lets the underlying dashboard wallpaper or HA theme background show through. Legacy shortcut for a fully transparent card body. When `background_opacity` is not set, `true` is equivalent to `background_opacity: 100`. The color used for Month and Week Compact grid lines, Schedule dividers and hour lines, and Agenda dividers. It accepts normal CSS color values, including hex colors and CSS variables. When omitted, the card keeps its light or dark default; transparent backgrounds use a readable translucent white. ```yaml theme={null} background_opacity: 100 grid_color: "#ffffff" ``` A URL pointing to an image to display behind the calendar grid. Local Home Assistant paths (e.g. `/local/calendar-bg.jpg`) and remote URLs are both supported. CSS `background-size` value for the background image. Options: `cover`, `contain`, `auto`. CSS `background-position` value for the background image. Options: `center`, `top`, `bottom`, `left`, `right`. CSS `background-repeat` value for the background image. Options: `no-repeat`, `repeat`, `repeat-x`, `repeat-y`. ## Layout Make the card fit precisely into its parent container's height instead of expanding to fit its content. This is especially useful in Home Assistant **Panel** dashboards and fixed-height grid layouts. In a Panel dashboard, the parent container is usually the full available dashboard viewport, so `compact_height: true` makes Daylight Calendar Card automatically size itself to fill the screen height. Use this when: * the card should fill a wall-tablet or kiosk screen * the card is inside a fixed-height grid area * Agenda view should scroll internally instead of making the whole dashboard taller * Month/Schedule view should compress vertically to fit the available space Avoid this in normal masonry/sidebar layouts where the card's parent may not have a defined height. In those layouts, use the default content height or adjust `height_scale` for Schedule view. Reduce internal horizontal padding. Use this when the card is placed in a narrow column and you want to maximise the space available for the calendar grid itself. A multiplier applied to the hour-row height in the **Schedule** view (also known as `week-standard`). A value of `1.5` makes each hour slot 50% taller; `0.75` compresses them. Does not affect Month, Week Compact, or Agenda views. ## Light/Dark Mode Controls whether the card renders in light or dark mode. `auto` follows the Home Assistant theme, `light` always uses the light appearance, and `dark` always uses the dark appearance regardless of the theme. ## Today Highlight A simple hex color applied as the background of today's cell in all views. For more control, use `today_style` instead. An advanced object for fine-grained styling of today's cell. You can set any combination of the following keys: | Key | Type | Description | | - | - | - | | `background_color` | hex string | Background fill color | | `opacity` | 0–1 | Opacity of the background fill | | `border_color` | hex string | Color of the cell border | | `border_width` | number | Width of the cell border in pixels | When both `today_background_color` and `today_style` are set, `today_style` takes precedence. ```yaml theme={null} today_style: background_color: "#1A1A2E" opacity: 0.4 border_color: "#E94560" border_width: 2 ``` ## Example The configuration below creates a dark-themed card with a background image, semi-transparent header, and custom event colors: ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family - calendar.work color_scheme: dark colors: calendar.family: "#4CAF50" calendar.work: "#2196F3" event_color_mode: left-tint event_tint_opacity: 60 event_color_bar_width: 14 header_color: "#0D0D1A" header_text_color: "#E0E0E0" header_background_opacity: 20 background_image_url: /local/dark-calendar-bg.jpg background_image_size: cover background_image_position: center background_opacity: 85 compact_height: false height_scale: 1.2 today_style: background_color: "#E94560" opacity: 0.25 border_color: "#E94560" border_width: 2 ``` # Basic Configuration Options for Daylight Calendar Card Source: https://docs.daylightcalendar.com/configuration/basic Configure entities, default view, language, first day of week, and core display settings for the Daylight Calendar Card in Home Assistant. The Daylight Calendar Card requires only a list of calendar entities to get started, but a handful of core options let you tailor the card's behavior to your household. Most of these options are available in the visual editor — you only need YAML if you prefer it or are version-controlling your dashboard. ## Required Options A list of one or more Home Assistant calendar entity IDs to display. This is the only truly required field — every other option has a sensible default. ```yaml theme={null} entities: - calendar.family - calendar.work - calendar.holidays_in_united_states ``` The title displayed in the card header. Set `title: ""` to hide only the title while retaining any other configured header content, such as time, weather, custom header items, or controls. ```yaml theme={null} title: My Calendar ``` ```yaml theme={null} # Hide the title but keep the rest of the header title: "" ``` ## Core Options The view shown when the card first loads. Accepted values: * **`month`** — traditional monthly grid. * **`week`** or **`week-compact`** — compact weekly overview where each day is a column with stacked events. The card normalizes `week` to `week-compact` internally. * **`schedule`** or **`week-standard`** — timed weekly grid with days as columns and hours as rows. Events are positioned as blocks by their actual start and end times. The card normalizes `schedule` to `week-standard` internally. * **`agenda`** — scrollable day-by-day list of upcoming events, rolling forward from today. See [Week](/views/week), [Schedule](/views/schedule), [Month](/views/month), and [Agenda](/views/agenda) for the full per-view docs. The day the week starts on, expressed as a number where `0` = Sunday, `1` = Monday, and so on through `6` = Saturday. An array of day numbers (0–6) to include in week and schedule views. Omitting a day hides it entirely from those views. Defaults to all seven days: `[0, 1, 2, 3, 4, 5, 6]`. Use `[1, 2, 3, 4, 5]` to show Monday through Friday only. The language used for all UI strings — day names, month names, button labels, and more. Supported values: `en`, `fr`, `de`, `nl`, `es`, `et`, `ca`, `da`, `sv`. When omitted, the card automatically detects the language set in your Home Assistant profile. A BCP 47 locale string (e.g. `en-US`, `de-DE`, `fr-CA`) that overrides the default locale associated with the selected language. Use this when you want, for example, German UI strings but Swiss date formatting (`de-CH`). Controls light/dark mode for the card. `auto` follows the Home Assistant theme, `light` forces a light appearance, and `dark` forces a dark appearance. A unique string used as the browser-storage key for saving the user's current view, hidden calendars, [custom event colors](/configuration/event-management#custom-event-colors), and other per-session preferences. When you have multiple Daylight Calendar Cards on different dashboards, give each one a different key so their preferences do not overwrite each other. ## People & Calendar Mapping A map of calendar entity IDs to Home Assistant `person.*` entity IDs. When configured, the card reads each person entity's current location state and displays a small avatar or badge on the calendar to show where household members are. This is especially useful on a family dashboard where you want to see at a glance that a family member is at school, at work, or home. ```yaml theme={null} calendar_person_entities: calendar.ian: person.ian calendar.sarah: person.sarah ``` The key must be a calendar entity ID that is already listed under `entities`. The value must be a valid `person.*` entity ID tracked by Home Assistant's [Person integration](https://www.home-assistant.io/integrations/person/). ## Example The YAML below shows a complete basic configuration that covers the most commonly used options: ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family - calendar.work - calendar.holidays_in_united_states default_view: month first_day_of_week: 1 week_days: - 1 - 2 - 3 - 4 - 5 language: en locale: en-GB color_scheme: auto preference_storage_key: main_dashboard_calendar calendar_person_entities: calendar.family: person.parent ``` The visual editor covers all of these options — and many more — through a point-and-click interface. Open the card editor in Home Assistant, click the card, then select **Edit** to access it. You only need to write YAML manually if you prefer or if you are managing your configuration in version control. # Display & Header Options for Daylight Calendar Card Source: https://docs.daylightcalendar.com/configuration/display Control header visibility, navigation, calendar badge display, and event formatting options for the Daylight Calendar Card in Home Assistant. The Daylight Calendar Card gives you fine-grained control over which interface elements are visible and how individual events are presented. Whether you want a completely frameless calendar embedded in a dashboard or a fully interactive card with navigation controls and calendar toggles, the options below let you build exactly what you need. ## Header Options The header sits at the top of the card and contains the title, navigation arrows, view selector, add-event button, and the dark-mode toggle. You can hide any combination of these controls independently. Hide the entire card header, including the title and all controls. Useful when you want only the calendar grid itself to appear. Remove the year from the date shown in the header. Helpful when space is tight and the year is implied. Hide the previous and next navigation arrows so the card stays fixed on the current period. Hide the view-selector dropdown (Month / Week / Schedule / Agenda) so the card stays locked to its `default_view`. Hide the **Add Event** button from the header. This only hides the control; it does not disable creation from day or time-slot taps. Use [`disable_event_creation`](/configuration/event-management) to block new-event creation everywhere. Hide the light/dark mode toggle button. Hide all controls at once — equivalent to setting `hide_navigation_buttons`, `hide_view_selector`, and `hide_add_event_button` to `true` simultaneously. Collapse the header into a single row by placing the title and controls side by side. This saves vertical space on smaller cards. Show a button in the header that navigates to another Home Assistant dashboard. You must also set `header_dashboard_path` for the button to appear. The path of the dashboard to open when the navigation button is clicked. For example, `/lovelace/calendar` or `/lovelace-custom/overview`. Requires `show_dashboard_nav_button: true`. ## Calendar List Options The calendar list lets users toggle individual calendars on or off from inside the card. These options control whether the list is shown and how each calendar is labelled. Hide the calendar visibility toggle list entirely. Hide the text name next to each calendar's colored dot in the calendar list, showing only the color indicators. A list of calendar entity IDs that should be hidden when the card loads for the first time. The user can still reveal them using the calendar toggle list. Once the user changes their selection it is saved in browser storage and overrides this initial default for that browser. ```yaml theme={null} default_hidden_calendars: - calendar.work - calendar.holidays_in_united_states ``` A map of calendar entity IDs to initial visibility states. Use `show`, `shown`, `visible`, `on`, or `true` to force a calendar visible; use `hide`, `hidden`, `off`, or `false` to hide it initially. This is an alternative to `default_hidden_calendars` when you prefer one map of explicit states. ```yaml theme={null} default_calendar_visibility: calendar.family: show calendar.work: hide ``` Legacy alias for `default_calendar_visibility`. Use `default_calendar_visibility` for new configurations. Override the display name of any calendar in the card UI. The key is the entity ID and the value is the name you want shown. ```yaml theme={null} calendar_names: calendar.family: "Family" calendar.work: "Work" ``` Assign an MDI icon to a calendar. The icon appears as a badge next to the calendar's colored dot in the calendar list and, optionally, on each event from that calendar. ```yaml theme={null} calendar_badge_icons: calendar.family: mdi:home-heart calendar.work: mdi:briefcase ``` A list of calendar entity IDs to exclude from the calendar badge row that appears in the card header. Calendars listed here will still appear in the main calendar grid and in the calendar toggle list — they are only hidden from the compact badge indicator strip at the top of the card. ```yaml theme={null} hide_badge_calendars: - calendar.holidays_in_united_states - calendar.boss_calendar ``` ## Event Display Options The font size (in pixels) of the event title text. The font size (in pixels) of the event start/end time text. The font size (in pixels) of the event location text. ```yaml theme={null} type: custom:daylight-calendar-card event_font_size: 14 event_time_font_size: 12 event_location_font_size: 11 ``` Show the calendar's friendly name beneath the event title in event detail modals. Prepend a prefix to every event title in the calendar grid. Options: * `none` — no prefix * `badge_icon` — prepend the calendar's MDI badge icon (requires `calendar_badge_icons`) * `friendly_name` — prepend the calendar's display name Hide the small colored dot (calendar indicator) that appears on each event chip in the grid. A list of calendar entity IDs for which event start and end times should be hidden. Applies to Month, Week Compact, Schedule, and Agenda views. Useful for all-day or informational calendars where times add clutter. ```yaml theme={null} hide_times_for_calendars: - calendar.holidays_in_united_states ``` Display times in a compact format — for example, `10 AM` instead of `10:00 AM`. Applies to Month, Week Compact, Schedule, and Agenda views. Override the browser or WebView timezone used by the card. Use an IANA timezone name, such as `America/New_York`. Leave this unset to keep the existing behavior, which uses the device's local timezone. If the value is blank or invalid, the card ignores it and falls back to the device timezone. ```yaml theme={null} time_zone: America/New_York ``` Display full weekday names, such as `Monday` and `Tuesday`, instead of abbreviated names like `Mon` and `Tue`. The card formats names using the configured `locale` or `language`, or the locale inherited from Home Assistant when neither is set. ### Week Compact day header These options apply only to the **Week Compact** view. The spacing value controls both the space below the header and its bottom padding. The header continues to size naturally around dates, weather, and day badges. Set the weekday-name font size in pixels. Set the weekday-name color to any CSS color value. Leave it unset to use the existing light, dark, or custom-background color. Set the day header's vertical spacing and bottom padding in pixels. Use a smaller value to shorten the header without imposing a fixed height. ```yaml theme={null} type: custom:daylight-calendar-card default_view: week-compact week_compact_weekday_font_size: 10 week_compact_weekday_color: "#475569" week_compact_day_header_spacing: 4 ``` Control how day badges are arranged in **Week** and **Schedule** day headers. Use `inline` to keep the date and badges on one row, or `stacked` to place badges below the date. Invalid values fall back to `inline`. ```yaml theme={null} day_badge_layout_week: stacked ``` Show the event's location text below the event title. Applies to **Week Compact**, **Schedule**, and **Agenda** views. Also applies to **Month** only when `show_all_details_month` is enabled. When `show_event_location` is also enabled, truncate long location strings to a shorter form so they don't push event blocks taller. Applies to **Week Compact**, **Schedule**, and **Agenda** views. Also applies to **Month** only when `show_all_details_month` is enabled. Controls how events that have already ended are displayed: * `none` — past events appear exactly like future events * `hide` — past events are removed from view entirely * `muted` — past events are shown with reduced opacity to de-emphasise them Legacy alias for `past_event_mode: hide`. Use `past_event_mode` for new configurations because it also supports the `muted` option. Disable touch swipe gestures for navigating between weeks and months. Useful on dashboards where the card is embedded inside another scrollable container. ## Example ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family - calendar.work - calendar.holidays_in_united_states compact_header: true hide_dark_mode_toggle: true hide_add_event_button: false show_dashboard_nav_button: true header_dashboard_path: /lovelace/home default_hidden_calendars: - calendar.holidays_in_united_states calendar_names: calendar.family: "Family" calendar.work: "Work" calendar_badge_icons: calendar.family: mdi:home-heart calendar.work: mdi:briefcase event_font_size: 12 event_time_font_size: 10 shorten_event_times: true time_zone: America/New_York display_full_weekday_names: true day_badge_layout_week: stacked show_event_location: true use_short_location: true past_event_mode: muted hide_times_for_calendars: - calendar.holidays_in_united_states hide_badge_calendars: - calendar.holidays_in_united_states ``` # Managing Calendar Events with the Daylight Calendar Card Source: https://docs.daylightcalendar.com/configuration/event-management Create, edit, and delete calendar events directly from the Daylight Calendar Card, with support for recurring events and read-only calendars. The Daylight Calendar Card supports full create, read, update, and delete (CRUD) operations for calendar events directly from your Home Assistant dashboard. You can add a team meeting, tweak an existing appointment, or remove an event that was cancelled — all without leaving the card. ## Support by Calendar Type What you can do from inside the card depends on the underlying Home Assistant calendar integration. The card adapts its UI to each calendar's capabilities — buttons for unsupported actions are hidden or disabled automatically. | Calendar type | Create | Edit | Delete | | - | :-: | :-: | :-: | | **Local Calendar** (Home Assistant built-in) | ✅ | ✅ | ✅ | | **Google Calendar** | ✅ | ✅ \* | ✅ | | **CalDAV** | ✅ | \* | \* | **\* Google Calendar edits use a safe create-then-delete flow.** The Home Assistant Google Calendar integration does not expose a true update operation, so the card simulates editing by creating a new event with your changes and then deleting the original. From the user's perspective the event appears edited; under the hood it is a brand new event. One side effect: the event's UID changes, and any external links or integrations that reference the original UID will need to be updated. **CalDAV is version dependent.** The card can always add new events to a CalDAV calendar, but editing and deleting existing events is dependent on the CalDAV version. The card reads those capabilities and shows Edit/Delete buttons accordingly. ## Creating Events To create a new event, click the **Add Event** button in the card header. A modal form opens where you fill in: * **Event title** (required) * **Start date and time** * **End date and time** * **All-day toggle** — when enabled, time fields are hidden and the event spans the full day * **Location** — optional venue or address * **Description** — optional free-text notes (supports Markdown and basic HTML) * **Calendar** — choose which calendar the event is saved to from a dropdown of your writable calendars Click **Create Event** to save. The card refreshes immediately to show the new event in the grid. ## Editing Events To edit an existing event, click it anywhere in the calendar grid to open the event detail modal. Then click **Edit Event**. The same form used for creation appears, pre-populated with the event's current data. Make your changes, then click **Save Changes**. The **Edit** button only appears for events on calendars that support editing. See [Support by Calendar Type](#support-by-calendar-type) above for the per-integration matrix. ## Recurring Events When creating or editing an event, toggle the **Recurring** switch to reveal recurrence options: * **Frequency** — `Daily`, `Weekly`, `Monthly`, or `Yearly` * **Interval** — repeat every N frequency units (e.g. every 2 weeks) * **Weekdays** — for weekly recurrence, select which days of the week the event falls on * **End condition** — choose `Never`, `On a date` (enter an end date), or `After N occurrences` ## Deleting Events From the event detail modal, click **Delete**. You will be asked to confirm. For recurring events, a second prompt asks you how to apply the deletion: | Option | Effect | | - | - | | **This event only** | Removes only the single occurrence you clicked | | **This and future events** | Removes this occurrence and every one after it | | **All events** | Removes the entire recurring series | The **Delete** button only appears for events on calendars that support deletion. See [Support by Calendar Type](#support-by-calendar-type) above. ## Custom Event Colors You can override the color of any event directly from the event detail modal without changing the event in Home Assistant or the source calendar. Custom colors are stored in the browser and apply only on that device, which makes them ideal for personalizing shared family calendars or highlighting events on a single dashboard. To set a custom color, click the event in the calendar grid to open the detail modal, then click **Custom Color**. A compact color picker opens with: * A row of preset color swatches * A native color picker (``) * A hex input synced with the picker, validated against `#RRGGBB` format * A live preview of the event chip * **Apply Color**, **Use Default**, and **Cancel** actions Click **Apply Color** to save the override, or **Use Default** to remove any existing override and fall back to the calendar's color and any matching [event style rules](/advanced/event-styles). ### Recurring events When you set a custom color on a recurring event, you're asked how far the override should apply: | Option | Effect | | - | - | | **This event only** | Colors only the single occurrence you clicked | | **This and future events** | Colors this occurrence and every one after it | | **All events** | Colors the entire recurring series | More specific scopes take precedence: a per-occurrence override wins over a future-rule override, which wins over a series-wide override. ### Combined events If you use [combined calendars](/advanced/combine-calendars), the event may appear on more than one source calendar at once. Selecting **Custom Color** on a combined event first prompts you to choose which calendar copy to color, so you can style each source independently. ### How overrides interact with `event_styles` A custom color set from the modal overrides the `background_color` (also known as `color`) supplied by any matching [event style rule](/advanced/event-styles). All other style properties from `event_styles` — icons, opacity, filters, font color, and so on — still apply. If you want to revert to the styled or calendar default, open the modal again and click **Use Default**. Custom colors are persisted in browser storage under the same key as hidden-calendar preferences. Set a unique [`preference_storage_key`](/configuration/basic#param-preference-storage-key) on each card to keep overrides from bleeding across dashboards. Clearing browser data for Home Assistant, or switching to a different device or user profile, resets the overrides. ## Configuration Options Master switch for all event management features. Set to `false` to make the card completely read-only — the Add Event button is hidden and clicking events opens a read-only detail view with no Edit or Delete actions. Prevent creation of new events while leaving management of existing events independent. When `true`, the card hides Add Event controls and blocks creation from Month day taps, Agenda day rows, Schedule time slots, Week day headers, and the **Forward** action. Existing events can still be viewed, edited, custom-colored, or deleted when those actions are otherwise allowed. This is useful when events should be created by automations or other software but still need to be removable from Daylight. A list of calendar entity IDs that should be treated as read-only even when event management is enabled. Events on these calendars can be viewed but not edited or deleted from the card. ```yaml theme={null} readonly_calendars: - calendar.holidays_in_united_states - calendar.boss_calendar ``` Hide the **Add Event** button from the header. This also hides the contextual **Add Event** button in the `show_events` day-events popup (see [Month view](/views/month)). This is a visual option only; it does **not** prevent creation from tappable day/slot surfaces. Use `disable_event_creation: true` when you need to block all new-event creation. Users can still edit and delete existing events unless you also disable event management or mark calendars as read-only. Hide selected actions from the event detail popup. Supported values are `delete`, `custom_color`, `forward`, and `edit`. This option changes only which controls are shown. It does not make a writable calendar read-only; use `readonly_calendars` or `enable_event_management: false` when you need to prevent modifications. ```yaml theme={null} hide_event_actions: - delete - custom_color - forward - edit ``` Set the width of the event management modal. Supported values are `narrow`, `medium`, `wide`, and `full`. Invalid or missing values fall back to `medium`. The setting applies to every event modal — create, edit, view, and delete confirmations. ```yaml theme={null} event_modal_size: wide ``` Minute step for the start and end time pickers in the create and edit event forms. With the default `1` the form uses the browser's native date-time picker. Set `5`, `10`, `15`, `20`, or `30` to replace it with a date field plus hour and minute dropdowns, where the minute list only offers multiples of the step. This is easier to use on touch screens and wall tablets, where the native picker scrolls through all 60 minutes. The hour dropdown follows the card's clock: 00–23 in 24-hour locales and 1–12 with an AM/PM dropdown in 12-hour locales (`use_24hr_schedule` overrides the locale as usual). The stored time is always 24-hour. When you edit an existing event whose minutes fall outside the step, its current minute stays available as an extra option so the time is never moved silently; the extra option disappears once you pick a different minute. Any value other than `1`, `5`, `10`, `15`, `20`, or `30` falls back to `1`. ```yaml theme={null} event_time_step: 5 ``` Let users click the location in the event detail modal to reveal location actions. This does not change event rows in Month, Week, Schedule, or Agenda views. When enabled, clicking a modal location reveals **Open in Google Maps** and **Copy address** actions. Maps open only after the user clicks the action. ```yaml theme={null} location_links: true ``` ## Example ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family - calendar.work - calendar.holidays_in_united_states enable_event_management: true disable_event_creation: false readonly_calendars: - calendar.holidays_in_united_states hide_add_event_button: false hide_event_actions: - delete - forward event_modal_size: wide event_time_step: 5 ``` Event descriptions support Markdown and basic HTML. You can use `**bold**`, `_italic_`, bullet lists, and links in description fields. All HTML is sanitised before rendering, so unsafe tags are stripped automatically. Some events created outside of Home Assistant — for example, events imported from an ICS file or synced from third-party integrations — may be missing a UID field. Without a UID, the card cannot uniquely identify the event and will show a "Cannot Modify" notice instead of Edit and Delete buttons. If you need to modify such an event, recreate it directly from the card or from the source calendar application. # Weather & Time Display in the Daylight Calendar Card Source: https://docs.daylightcalendar.com/configuration/weather Add weather forecasts and a live clock to your Daylight Calendar Card header using Home Assistant weather and time sensor entities. The Daylight Calendar Card can pull current conditions and, when available, a daily forecast from a Home Assistant `weather.*` entity. Current conditions and today's temperature appear in the card header. Per-day forecast icons can appear in Month, Week Compact, Week Standard/Schedule, and Agenda views. ## Weather Forecast The entity ID of a Home Assistant `weather.*` entity. When set, the card: * Reads **current conditions** (state and temperature) directly from the entity for the header summary. * Subscribes to **daily forecasts** through Home Assistant's live forecast API and renders an MDI weather icon plus high/low temperatures for each day. Examples: `weather.home`, `weather.openweathermap`, `weather.met_no`. Controls whether daily forecasts appear inside calendar days. Set this to `false` to keep the current condition, icon, and temperature in the header without requesting or displaying daily forecast data. ### Requirements To display weather data you need: 1. A weather integration installed and configured in Home Assistant — for example, [Met.no](https://www.home-assistant.io/integrations/met/), [OpenWeatherMap](https://www.home-assistant.io/integrations/openweathermap/), or [AccuWeather](https://www.home-assistant.io/integrations/accuweather/). 2. When `show_daily_weather_forecast` is enabled, the `weather.*` entity must support the **daily forecast** type. Home Assistant exposes this as the `FORECAST_DAILY` feature on the entity. Most modern HA weather integrations support daily forecasts out of the box, but a few (especially radar-only or current-conditions-only integrations) do not. With `show_daily_weather_forecast: false`, the card can still show current conditions in the header from a `weather.*` entity that does not provide daily forecasts. ### Example ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family header_weather_sensor: weather.home ``` ### Header-only weather ```yaml theme={null} type: custom:daylight-calendar-card entities: - calendar.family header_weather_sensor: weather.home show_daily_weather_forecast: false ``` Popular weather integrations known to provide daily forecasts: Met.no (free, no sign-up), OpenWeatherMap, AccuWeather, Pirate Weather, and the built-in HA weather platform. Weather icons in the card are rendered using MDI (Material Design Icons), not emoji. They scale crisply at any display size and automatically respect your card's light or dark color scheme without any extra configuration. ### Troubleshooting **Current conditions show but day-cell forecasts are empty.** This usually means the `weather.*` entity does not advertise daily-forecast support. Verify by calling the `weather.get_forecasts` service in Home Assistant Developer Tools with `type: daily`. If the response is empty or errors out, switch to a weather integration that supports daily forecasts (Met.no is a good free option). **Forecasts stop updating after a while.** The card maintains a live subscription to the weather entity's forecast stream. If your weather integration is rate-limited or disconnected, forecasts may go stale. Reload the dashboard tab to re-establish the subscription, and check the integration's status page in Home Assistant. ## Live Time Display In addition to weather, you can display a real-time clock in the card header by pointing the card at a Home Assistant time sensor. The entity ID of a Home Assistant sensor that provides the current time as its state. The most common choice is `sensor.time`, which is provided by the [Time & Date](https://www.home-assistant.io/integrations/time_date/) integration. When set, the current time is shown in the card header and updates automatically each minute. ### Setting Up `sensor.time` If you have not already added the Time & Date integration, enable `sensor.time` by adding the following to your `configuration.yaml`: ```yaml theme={null} sensor: - platform: time_date display_options: - time ``` Then restart Home Assistant and use the sensor in the card: ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family header_time_sensor: sensor.time header_weather_sensor: weather.home ``` ## Custom header items Use `header_items` to add short, structured icon and value pairs after the title, live time, and weather summary. Each item pulls its value from a Home Assistant entity (or from static text) and updates only when that entity changes. Use header items for glanceable data such as sunrise and sunset times, indoor temperature, or a simple label. For the best responsive layout, keep the list to 1–4 short items. Optional list of custom header items. Each item accepts: * `icon`: optional MDI icon shown before the value, such as `mdi:weather-sunset-up`. * `entity`: optional Home Assistant entity ID. When set, the card reads the entity's state. * `attribute`: optional attribute name. When set, the card displays the named attribute instead of the entity state. * `text`: optional static text. Used as a fallback when the entity is missing, or on its own for a static label. * `format`: optional display format. Defaults to `auto`. Supported values are `auto`, `raw`, `time`, `date`, and `datetime`. With `auto`, the card picks a compact format based on the entity: timestamp entities show a local time, date entities show a localized date, entities with a unit of measurement keep their unit, and everything else displays as raw state text. ### Example ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family header_weather_sensor: weather.home header_time_sensor: sensor.time header_items: - icon: mdi:weather-sunset-up entity: sensor.sun_next_rising - icon: mdi:weather-sunset-down entity: sensor.sun_next_setting - icon: mdi:home text: Family ``` Header items hide automatically when their resolved value is empty, `unknown`, or `unavailable`. If an entity is missing and `text` is provided, the card displays the text fallback instead. Values and icon names are escaped before rendering — arbitrary HTML and Jinja templates are intentionally not supported. ## Combined Example The configuration below shows a card that displays both a live clock and a daily weather forecast in the header: ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family - calendar.work header_weather_sensor: weather.home header_time_sensor: sensor.time default_view: month color_scheme: auto ``` # Frequently Asked Questions: Daylight Calendar Card Source: https://docs.daylightcalendar.com/faq Answers to common questions about Daylight Calendar Card covering installation, configuration, Google Calendar, language settings, and HACS updates. The Daylight Calendar Card is a custom Lovelace card for Home Assistant that brings a full-featured calendar view to your dashboards. Whether you're just getting started or looking to understand a specific configuration option, this page answers the questions users ask most often. If you run into a specific problem rather than a general question, see the [Troubleshooting](/troubleshooting) page instead. Yes — the card is completely free and open source, published under the MIT license. You can use it on as many Home Assistant instances as you like without any cost or subscription. If you find the card useful and want to support the developer's ongoing work, you can do so via GitHub Sponsors or Buy Me a Coffee. Links are available on the [project's GitHub page](https://github.com/superdingo101/daylight-calendar-card). Yes. Connect your Google Calendar to Home Assistant using the built-in Google Calendar integration. Once connected, each calendar appears as a `calendar.*` entity (for example, `calendar.my_google_calendar`) that you can add to the card's `entities` list. **Important limitations with Google Calendar:** * **Editing events** is not natively supported through the Home Assistant Google Calendar integration. Google Calendar edits are simulated via create-then-delete, which changes the event's UID. To truly edit an event, use the Google Calendar app or website directly. * **Deleting events** does work through Home Assistant and the card. * **Creating new events** works if the calendar is writable in HA. These limitations come from the Home Assistant Google Calendar integration, not from the card itself. They apply regardless of which calendar UI you use in HA. Any integration that exposes a `calendar.*` entity in Home Assistant will work with the card. This includes: * **Google Calendar** (via the HA Google Calendar integration) * **CalDAV** — covers Nextcloud Calendar, iCloud Calendar, Fastmail, Radicale, Baikal, and any other CalDAV-compatible server * **Local Home Assistant calendars** (created directly in HA) * Any third-party integration that creates `calendar.*` entities If you can see an entity in **Developer Tools → States** with a `calendar.` prefix, you can use it with the card. Yes. Add as many entity IDs as you need to the `entities` list: ```yaml theme={null} type: custom:daylight-calendar-card entities: - calendar.personal - calendar.work - calendar.family_shared ``` Each calendar is automatically assigned a distinct color. You can override individual colors using the `colors` map: ```yaml theme={null} colors: calendar.personal: "#4A90D9" calendar.work: "#E94E4E" ``` Users can also toggle individual calendars on and off using the calendar filter controls in the card header. They are the same card. The project was originally named **Skylight Calendar Card** and was later renamed to **Daylight Calendar Card**. Both card type identifiers continue to work: ```yaml theme={null} type: custom:daylight-calendar-card # current name type: custom:skylight-calendar-card # legacy name, still supported ``` The JavaScript file is still named `skylight-calendar-card.js` for backwards compatibility — renaming it would break existing installations. You do not need to change anything if you installed the card before the rename. New installations should use `type: custom:daylight-calendar-card` in their YAML. Both types register from the same file. 1. Open **HACS** in the Home Assistant sidebar. 2. Go to **Frontend**. 3. Find **Daylight Calendar Card** in the list. 4. If an update is available, click the card entry and then click **Update**. 5. After HACS finishes downloading, hard-refresh your browser with `Ctrl+Shift+R` (Windows/Linux) or `Cmd+Shift+R` (Mac) to ensure the browser loads the new JavaScript file and not a cached version. If the card still shows the old version number after updating, clear your browser cache or open the dashboard in a private/incognito window to confirm the update took effect. HACS showing the latest version confirms that the current files are installed on disk. It does not prove that your browser or dashboard is loading the current frontend resource. This is especially common if you installed the card before the Skylight → Daylight rename. Home Assistant may still have an old resource entry or cached file that points to the previous `skylight-calendar-card` folder, even though the JavaScript filename is still `skylight-calendar-card.js`. Check **Settings → Dashboards → Resources**, remove duplicate or old Skylight resources, and make sure the active HACS resource uses `/hacsfiles/daylight-calendar-card/skylight-calendar-card.js`. Then hard-refresh the browser or try a private/incognito window. See [Updated to the latest version, but still seeing old behavior](/troubleshooting#updated-to-the-latest-version-but-still-seeing-old-behavior) for the full checklist. Yes. The card ships with a visual configuration editor that is accessible directly from the Home Assistant dashboard card editor. Click **Edit Dashboard**, add or edit a Daylight Calendar Card, and the graphical editor appears automatically. It covers all the common options including calendars, view modes, colors, and weather. Advanced options that require manual YAML editing include: * `event_styles` — custom styling rules for individual events * `day_styles` — custom styling rules for specific days * `day_badges` — icons or labels shown on day cells * `virtual_calendars` — computed calendars derived from other data For most users, the visual editor is all that's needed. The card currently supports the following languages: | Code | Language | | - | - | | `en` | English | | `fr` | French | | `de` | German | | `nl` | Dutch | | `es` | Spanish | | `et` | Estonian | | `ca` | Catalan | | `da` | Danish | | `sv` | Swedish | The language is auto-detected from your Home Assistant profile settings. To override it, add the `language` key to your card YAML: ```yaml theme={null} language: fr ``` Language affects UI labels and day/month names. To separately control how dates and times are formatted (e.g. 12-hour vs 24-hour clock, date order), use the `locale` key — for example, `locale: en-GB`. Yes. The card has full dark mode support with three options controlled by the `color_scheme` config key: ```yaml theme={null} color_scheme: auto # follows your system or HA theme (default) color_scheme: light # always use the light theme color_scheme: dark # always use the dark theme ``` A dark mode toggle button is shown in the card header by default, allowing users to switch modes on the fly without editing the config. To hide this button, add: ```yaml theme={null} hide_dark_mode_toggle: true ``` Set `compact_height: true` in your card config: ```yaml theme={null} type: custom:daylight-calendar-card entities: - calendar.my_calendar compact_height: true ``` This tells the card to measure its parent container and expand to fill the available vertical space. It is designed specifically for use in Home Assistant **panel** and **grid** dashboard layouts where the card occupies a fixed-height region. Do not use `compact_height: true` in a standard vertical (sidebar) dashboard layout. In that layout the container has no fixed height, so the card may collapse to zero height. Use `height_scale` to adjust sizing in standard layouts instead. Yes. Use the `event_styles` configuration to define rules that match events and apply `hide: true` to them: ```yaml theme={null} event_styles: - match: title: "Team Standup" style: hide: true ``` Rules can match on any combination of event properties including calendar entity, title, description, and more. Multiple conditions in a single rule are combined with AND logic. See the **Event Styles** documentation for the full list of available conditions and style properties. Set the `header_weather_sensor` key to a valid `weather.*` entity in your Home Assistant instance: ```yaml theme={null} type: custom:daylight-calendar-card entities: - calendar.my_calendar header_weather_sensor: weather.home ``` The card displays current conditions in the header. Daily forecasts are enabled by default and appear in calendar views when the entity supports them. Set `show_daily_weather_forecast: false` to keep the header conditions without requesting or displaying per-day forecasts; in this mode, the entity does not need to support daily forecasts. Not sure what your weather entity is called? Open **Developer Tools → States** in Home Assistant and filter by `weather.` to see all available weather entities. # Installing Daylight Calendar Card in Home Assistant Source: https://docs.daylightcalendar.com/installation Install Daylight Calendar Card via HACS in one click, or manually by downloading the JS file and registering it as a Lovelace resource. You can install Daylight Calendar Card in two ways: through HACS (Home Assistant Community Store), which handles updates automatically and is recommended for most users, or manually by downloading the JavaScript file and registering it as a Lovelace resource yourself. Both methods result in the same card with the same features. ## Install the Card HACS manages the download, registration, and future updates for you. If you haven't installed HACS yet, follow the [official HACS installation guide](https://hacs.xyz/docs/use/) first. Click the button below to open Daylight Calendar Card directly in your Home Assistant's HACS: Open your Home Assistant instance and open a repository inside the Home Assistant Community Store. In your Home Assistant sidebar, click **HACS** to open the Community Store. Click **Frontend** in the HACS navigation to browse Lovelace cards and UI components. Use the search bar to find **Daylight Calendar Card**. Click the result to open its detail page. Click the **Download** button (or **Install** if you see that label). HACS will fetch the latest release and register the resource automatically. Hard-reload your browser (Ctrl+Shift+R on Windows/Linux, Cmd+Shift+R on macOS) so the new JavaScript file is picked up. The card is now ready to use. Manual installation gives you full control over the file location and resource registration. You'll need filesystem access to your Home Assistant configuration directory. Go to the [GitHub releases page](https://github.com/superdingo101/daylight-calendar-card/releases) and download `skylight-calendar-card.js` from the latest release assets. Place the downloaded file in your Home Assistant configuration's `www` directory: ```text theme={null} /www/skylight-calendar-card.js ``` Create the `www` folder if it doesn't exist yet. In Home Assistant, go to **Settings → Dashboards**, then click the **⋮** menu in the top-right corner and select **Resources**. Click **Add Resource** and fill in the following fields: | Field | Value | | - | - | | URL | `/local/skylight-calendar-card.js` | | Resource type | **JavaScript Module** | Click **Create** to save. Hard-reload your browser (Ctrl+Shift+R on Windows/Linux, Cmd+Shift+R on macOS) to load the newly registered resource. The card is now available in your dashboard editor. The card was previously called **Skylight Calendar Card**. It was renamed to Daylight Calendar Card in v4.0.0. If you have existing dashboard YAML that uses `type: custom:skylight-calendar-card`, it will continue to work without any changes — both type names are supported. ## Requirements Before installing, make sure your setup meets the following requirements: * **Home Assistant** — any reasonably recent version with Lovelace dashboards enabled. * **At least one calendar entity** — for example `calendar.family`, `calendar.work`, or any entity provided by a calendar integration such as Google Calendar, CalDAV, or Local Calendar. You can check your available calendar entities under **Settings → Devices & Services** or in **Developer Tools → States** by filtering for the `calendar.` domain. If you don't have a calendar integration set up yet, add one from **Settings → Devices & Services → Add Integration** before proceeding. # Daylight Calendar Card: A Beautiful Home Assistant Calendar Source: https://docs.daylightcalendar.com/introduction Daylight Calendar Card adds a beautiful, family-friendly calendar to your Home Assistant dashboard with multiple views, event management, and weather. Daylight Calendar Card is a custom Lovelace card for Home Assistant that transforms your dashboard into a polished, family-friendly calendar experience. Whether you're tracking household schedules, work meetings, or school events, it brings together all your Home Assistant calendar entities into one beautiful, interactive view — no coding required. ## Feature Highlights Switch between month, week, and agenda views to see your schedule exactly the way you want. Each view is optimized for quick scanning and easy navigation. Display events from multiple Home Assistant calendar entities side by side. Color-code calendars for family members, rooms, or projects so everything stays organized at a glance. Create, edit, and delete calendar events directly from your dashboard without leaving Home Assistant. Tap any event to view its full details or make changes on the spot. Optionally show daily weather forecasts inline with your calendar events so you can plan your week with the full picture in mind. Tailor the card to match your dashboard's style. Adjust colors, fonts, first day of the week, past-event appearance, and dozens of other options through a visual editor or YAML. Install Daylight Calendar Card in seconds through HACS (Home Assistant Community Store) — no build steps, no dependencies, just a single JavaScript file. ## How It Works Daylight Calendar Card reads events directly from your Home Assistant calendar entities — such as `calendar.family` or `calendar.work` — and renders them in whichever view you choose. It communicates with Home Assistant's native calendar API, so any calendar integration already connected to your instance (Google Calendar, CalDAV, Local Calendar, and more) works automatically. You configure the card through Home Assistant's built-in visual Lovelace editor, which exposes all common options as form fields. If you prefer full control, every option is also available as a YAML property, making it easy to version-control your dashboard configuration or share snippets with the community. The card registers under the type name `custom:daylight-calendar-card` (version 4.0.0 and later). Legacy configurations using `custom:skylight-calendar-card` continue to work without any changes, for now. ## Get Started Install the card via HACS or manually in just a few steps. Add the card to your dashboard and show your first calendar in under two minutes. # Quickstart: Add Daylight Calendar Card to Your Dashboard Source: https://docs.daylightcalendar.com/quickstart Add the Daylight Calendar Card to your Home Assistant dashboard in under two minutes using the visual editor or a simple YAML snippet. Once the card is installed, adding it to your Home Assistant dashboard takes less than two minutes. You can configure it entirely through the built-in visual editor — no YAML required — or drop in a short YAML snippet if you prefer to manage your dashboard as code. Either way, you'll have a working calendar on your screen in just a few steps. Make sure you have completed the [installation steps](/installation) before continuing. You'll need at least one Home Assistant calendar entity (for example `calendar.family` or `calendar.work`) available in your instance. ## Add the Card to Your Dashboard The visual editor exposes all common options as form fields, so you can get a calendar up and running without writing any configuration by hand. Open the dashboard where you want to add the card, then click the **pencil icon** (Edit) in the top-right corner to enter edit mode. Click **+ Add Card** at the bottom of the dashboard. In the card picker, type **Daylight** in the search box, then select **Daylight Calendar Card** from the results. In the **Entities** field, search for and select the calendar entities you want to display — for example `calendar.family` or `calendar.work`. You can add as many calendars as you like. Set a **Title** for the card (for example "Family Calendar") and choose a **Default View** — `month`, `week-compact`, `week-standard`, or `agenda`. Explore the other options such as first day of the week, past event appearance, and weather integration to suit your preferences. Click **Save** to add the card to your dashboard, then click **Done** to exit edit mode. Your calendar is now live. If you prefer to configure your dashboard in YAML — or want to share or version-control your setup — you can define the card with a minimal snippet and expand it as needed. **Minimal configuration** This is all you need to get started. It displays events from a single calendar entity using the card's default settings. ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family ``` **Expanded configuration** The example below adds a second calendar, sets the default view to month, starts the week on Monday (`1`), and mutes past events so they don't dominate the view. ```yaml theme={null} type: custom:daylight-calendar-card title: Family Calendar entities: - calendar.family - calendar.work default_view: month first_day_of_week: 1 past_event_mode: muted ``` To use this YAML, enter dashboard edit mode, click **+ Add Card**, scroll to the bottom of the card picker, and select **Manual**. Paste your YAML into the editor and click **Save**. Each value under `entities` must be a valid Home Assistant calendar entity ID. You can find your available calendar entities in **Developer Tools → States** by filtering for the `calendar.` domain. ## Next Steps Now that your calendar card is on the dashboard, explore what else you can do with it. Learn how the month view works and how to customize its layout and event display. Browse all available configuration options — colors, fonts, weather, and more. # Daylight Calendar Card: Troubleshooting Common Issues Source: https://docs.daylightcalendar.com/troubleshooting Fix common problems with the Daylight Calendar Card including missing events, blank cards, event editing errors, weather not showing, and layout issues. The Daylight Calendar Card is designed to work out of the box with any Home Assistant calendar integration, but a few common configuration issues can cause unexpected behavior. This page walks you through the most frequently encountered problems and how to resolve them. Work through the section that matches your symptom, and if nothing here helps, see the bug report guidance at the bottom of this page. This error means Home Assistant has not loaded the card's JavaScript file as a dashboard resource. The card UI will not render at all until the resource is registered. **Steps to fix:** 1. In Home Assistant, go to **Settings → Dashboards → Resources** (you may need to enable Advanced Mode in your profile first). 2. Check that `skylight-calendar-card.js` is listed and its type is set to **JavaScript Module**. 3. If the entry is missing, add it manually. The URL should match your installation path, for example `/hacsfiles/daylight-calendar-card/skylight-calendar-card.js` (HACS) or `/local/skylight-calendar-card.js` (manual). 4. Hard-refresh your browser with `Ctrl+Shift+R` (Windows/Linux) or `Cmd+Shift+R` (Mac) to force the browser to reload the resource. If you installed via HACS, the resource entry is usually added automatically. If it's missing, try removing and re-downloading the card in HACS, then check Resources again. A blank calendar most often means the card cannot find any events from the configured entities, or the entities themselves are not returning data. **Things to check:** * Verify that the entity IDs in your `entities` list exactly match calendar entities in Home Assistant. Entity IDs are case-sensitive. * Open the **Calendar** view in the Home Assistant sidebar and confirm your events appear there. If they don't, the problem is with the calendar integration itself, not the card. * Review your YAML for typos in the `entities` block: ```yaml theme={null} type: custom:daylight-calendar-card entities: - calendar.my_google_calendar - calendar.family ``` * Temporarily remove any filters that could be hiding all events, such as: ```yaml theme={null} past_event_mode: hide default_hidden_calendars: - calendar.my_google_calendar ``` Open your browser's developer console (F12) and look for any errors from the card while the dashboard loads. Connection errors may indicate that Home Assistant is slow to deliver calendar data — try refreshing the page after a few seconds. If HACS shows the latest version but new frontend behavior is missing, the most common cause is a stale dashboard resource or browser cache. HACS confirms that the files are installed. It does not confirm that Home Assistant or your browser is loading the current file. This is especially likely if you installed the card before the Skylight → Daylight rename. The filename is still `skylight-calendar-card.js` for compatibility, but the HACS folder path should now be the Daylight folder. **Symptoms:** * New options or features are missing * Documented options have no effect * The card editor looks outdated * The card editor is missing the **About / Diagnostics** section **Steps to fix:** 1. **Confirm HACS version** Open **HACS → Frontend → Daylight Calendar Card** and confirm it shows the version you expect. This only confirms installation, so continue with the resource checks below if the dashboard still looks old. 2. **Check Dashboard Resources** In Home Assistant, go to **Settings → Dashboards → Resources**. Look for every resource entry that points to `skylight-calendar-card.js`. 3. **Remove old Skylight resources** Delete duplicate or old entries that point to the pre-rename folder, such as: ```text theme={null} /hacsfiles/skylight-calendar-card/skylight-calendar-card.js ``` 4. **Keep only the current Daylight resource** For a HACS install, the resource should use the Daylight folder: ```text theme={null} /hacsfiles/daylight-calendar-card/skylight-calendar-card.js ``` The filename is intentionally still `skylight-calendar-card.js`. The important part is the folder path: `daylight-calendar-card`, not `skylight-calendar-card`. 5. **Refresh or restart** Hard-refresh your browser with `Ctrl+Shift+R` (Windows/Linux) or `Cmd+Shift+R` (Mac). If the old UI still appears, try a private/incognito window, clear your browser cache, or restart Home Assistant. 6. **Verify the current editor loads** Edit the card in your dashboard and scroll to the bottom of the card editor. Seeing the **About / Diagnostics** section is a good sign that the current frontend/editor is loading. If that section is missing, an old frontend resource is probably still being loaded. 7. **Include details when opening an issue** If you still need help, include screenshots of: * The HACS version shown for Daylight Calendar Card * **Settings → Dashboards → Resources** * The bottom of the card editor, especially whether **About / Diagnostics** appears This checklist is most useful when HACS shows the latest version but new options or editor sections are missing. Other bugs can have different causes. The **Add Event** button is hidden when event management is disabled or no writable calendar is available. Check each of the following in your card YAML: * `enable_event_management: false` — set this to `true` to enable event management. * `disable_event_creation: true` — set this to `false` or remove the line if you want to create new events from the card. * `hide_add_event_button: true` — set this to `false` or remove the line entirely. * All of your calendar entities are listed under `readonly_calendars` — remove any calendars you want to write to from that list. ```yaml theme={null} type: custom:daylight-calendar-card entities: - calendar.my_calendar enable_event_management: true disable_event_creation: false hide_add_event_button: false readonly_calendars: [] ``` At least one calendar entity must be writable (i.e., your Home Assistant integration must support creating events for that calendar). Read-only integrations — such as some holiday calendars — cannot receive new events regardless of card settings. There are several reasons an event might not be editable or deletable: **Google Calendar events** Editing events is not supported through the Home Assistant Google Calendar integration. Google Calendar edits are simulated via create-then-delete, which changes the event's UID. To truly edit an event, use the Google Calendar app or website directly. Deletion does work through HA. **Event is missing a UID** Some calendar integrations do not attach a UID to every event. Without a UID, the card cannot uniquely identify the event to send an edit or delete request. The only fix is to delete the event and recreate it through a source that generates UIDs. **Calendar is marked read-only in the card config** Check whether the calendar is listed under `readonly_calendars`: ```yaml theme={null} readonly_calendars: - calendar.work_holidays ``` Remove it from the list if you want to allow editing. **Event management is disabled globally** Confirm `enable_event_management` is not set to `false` in your card config. Never store sensitive data in calendar event titles or descriptions with the expectation that the card's read-only setting will protect it. `readonly_calendars` only affects the card UI — the underlying HA integration may still allow edits through other means. Weather icons require a valid `weather.*` entity that provides a daily forecast. **Steps to fix:** 1. Confirm you have set `header_weather_sensor` in your card config: ```yaml theme={null} header_weather_sensor: weather.home ``` 2. Open **Developer Tools → States** in Home Assistant and search for your weather entity (e.g. `weather.home`). Verify it exists and has a valid state. 3. Confirm that the weather integration provides a **daily forecast**. Some integrations only provide hourly forecasts, which the card does not use for day-cell icons. 4. If the entity exists and has a daily forecast but icons still don't appear, check the browser console for errors related to the weather subscription. On slower Home Assistant instances, weather data may take a few seconds to arrive after the page loads. Refresh the page and wait a moment before concluding the icons are broken. Height behavior depends on the dashboard layout you're using. **Using a panel or grid dashboard layout** Enable compact height mode to let the card fill its container: ```yaml theme={null} compact_height: true ``` This tells the card to measure its parent container and size itself to fit the available vertical space. It works correctly in HA panel and grid dashboard layouts. **Using a sidebar or standard layout** The card auto-sizes to its content in standard layouts. If it appears clipped, check whether `compact_height: true` is set — this mode is not appropriate for sidebar layouts and may cause the card to collapse. Remove it or set it to `false`. **Fine-tuning the height** Use `height_scale` to proportionally scale the card taller or shorter: ```yaml theme={null} height_scale: 1.2 # 20% taller than default height_scale: 0.85 # 15% shorter than default ``` `compact_height: true` requires the card to be placed in a grid or panel dashboard layout. In a standard vertical layout, use `height_scale` instead. If you see the same event appearing twice (or more), you likely have multiple calendar entities that both contain that event — for example, a personal Google Calendar and a shared family calendar that both include the same entry. Enable calendar combining to automatically deduplicate events that share the same normalized title, start time, end time, and location: ```yaml theme={null} combine_calendars: true ``` Deduplication does not rely on event UIDs. If duplicates persist after enabling `combine_calendars`, compare the event title, start time, end time, and location across calendars. Any difference in those fields makes the card treat the entries as distinct events. The card auto-detects your language from Home Assistant's locale settings. If detection produces the wrong language or date format, you can override both explicitly. **Set the display language:** ```yaml theme={null} language: de ``` Supported language codes: `en` (English), `fr` (French), `de` (German), `nl` (Dutch), `es` (Spanish), `ca` (Catalan), `da` (Danish), `sv` (Swedish). **Set the date and time locale:** ```yaml theme={null} locale: en-US ``` The `locale` key controls how dates and times are formatted (e.g. `MM/DD/YYYY` vs `DD.MM.YYYY`) and is independent of the `language` key. If you share a dashboard with users in different regions, set both `language` and `locale` explicitly so formatting is consistent regardless of individual HA profiles. If the card header appears but the calendar body is missing, check whether your dashboard card has an explicit `grid_options.rows` value that is too small. This can happen in v4.5.0 and newer because the card body now fills the available height of the Home Assistant dashboard card. If the dashboard card is only one row tall, the calendar body may collapse and only the header remains visible. **Fix:** ```yaml theme={null} grid_options: rows: 8 ``` If you currently have `rows:` set to anything less than 4, it is probably too small. The safest approach remains removing `rows:` entirely and letting the card size naturally. The card keeps a local snapshot of the last successful calendar fetch so it can render events immediately when Home Assistant reloads, even before a fresh refresh completes. The snapshot is stored in the browser (IndexedDB) and is scoped to your current card configuration. **What you might see:** * A brief flash of previously known events on startup before the current data loads. * A small **"Calendar data may be stale"** warning if no successful refresh has completed for 30 minutes (for example, when Home Assistant is unreachable or a calendar integration is failing). * Events that were deleted on your calendar still appearing until the next successful refresh finishes. This is expected behavior. A successful refresh — including one that legitimately returns no events — replaces the cached snapshot. Failed refreshes leave the last-known-good data in place instead of blanking the card. **If cached data looks wrong or you want to force a clean reload:** 1. Edit the card and scroll to **About / Diagnostics**. 2. Select **Flush event cache**. 3. The card clears its stored snapshots and triggers a fresh fetch from Home Assistant. Flushing only removes Daylight Calendar Card snapshots from your browser. It does not delete any events from your calendar integrations. If none of the above resolves your issue, please open a GitHub issue so the maintainer can investigate. **Before submitting, gather the following:** * Which dashboard view and card position is affected * Your complete card YAML configuration (remove any sensitive entity names if needed) * Screenshots or a screen recording of the problem * Your Home Assistant version (found in **Settings → About**) * Your browser and version * Any errors shown in the browser developer console (F12 → Console tab) Incomplete bug reports are much harder to diagnose. Including your full YAML config and HA version is the single most helpful thing you can do. Open an issue at [github.com/superdingo101/daylight-calendar-card](https://github.com/superdingo101/daylight-calendar-card/issues). # Agenda View: Scrollable Rolling Day List Source: https://docs.daylightcalendar.com/views/agenda The Agenda view shows a scrollable rolling day list starting from today, perfect for an always-current event feed on your Home Assistant dashboard. The Agenda view is a forward-rolling, day-by-day event list that always starts from today and looks ahead a configurable number of days. Unlike the timed-grid Week and Schedule views, the Agenda view is a flat, linear list anchored to the present moment. Every time you open the card, the list begins at today's date so you never have to scroll back to find where you are. This makes it the best choice for dashboards where you want an always-current "what's coming up" feed that requires no navigation. ## Activating Agenda View Set `default_view` to `agenda` in your card configuration: ```yaml theme={null} type: custom:daylight-calendar-card default_view: agenda ``` ## Configuration Options Used by **Agenda** only. The number of days ahead the Agenda view covers, counting from today. Set it to `7` for a one-week lookahead, or `30` for a rolling month. The list stops after this many days regardless of whether there are events remaining. Used by **Agenda** only. When `true`, event rows use a denser layout with reduced padding and smaller text, fitting more events on screen at once. Enable this when you have a high event volume or a small card footprint and want to maximise the number of visible rows. Used by **Agenda** only. When `true`, days with no events are omitted from the list. Combined with a long `rolling_days_agenda`, this creates a tight feed that jumps directly from one event-filled day to the next, skipping quiet days entirely. Used by **Month**, **Week**, **Schedule**, and **Agenda**. When `true`, event times are abbreviated — for example `2 PM` instead of `2:00 PM`. Pair this with `agenda_compact_events: true` for the most space-efficient Agenda layout. Used by **Month**, **Week**, **Schedule**, and **Agenda**. Despite the name, it is used by the shared event-time formatter, not only the Schedule view. When `true`, event times use 24-hour format (e.g. `14:00`) instead of 12-hour format with AM/PM. Used by **Week**, **Schedule**, and **Agenda**. Also applies to **Month** only when `show_all_details_month` is enabled. When `true`, the location field of each event is shown on a line below the event title. Particularly useful in an agenda context where you're planning your day and need to know where to be. Used by **Week**, **Schedule**, and **Agenda**. Also applies to **Month** only when `show_all_details_month` is enabled. Has no visible effect unless `show_event_location` is also enabled. Truncates long addresses to a shorter form so they don't push event rows taller. Used by **Month**, **Week**, **Schedule**, and **Agenda**. An array of calendar entity IDs whose events should not display time labels. Useful for all-day-style calendars where exact times are noise. Used by **Month**, **Week**, **Schedule**, and **Agenda**. Controls how events that have already ended are handled across the card. Accepted values: * `none` — past events look the same as upcoming events (default). * `muted` — past events are rendered at reduced opacity to draw attention to what's still coming. * `hide` — past events are removed from the list entirely, leaving only future events visible. ## Jump to Today If you scroll the Agenda list forward to browse upcoming events, a **Jump to Today** button appears in the card header. Tapping it instantly resets the scroll position back to today's date section so you never lose your place. This button only appears when you have scrolled away from today — it is hidden when today's section is already visible at the top of the list. ## Example Configuration The following configuration sets up Agenda view with a 30-day rolling window, compact event rows, hidden empty days, and location display: ```yaml theme={null} type: custom:daylight-calendar-card default_view: agenda rolling_days_agenda: 30 agenda_compact_events: true hide_empty_days: true shorten_event_times: true past_event_mode: muted show_event_location: true use_short_location: false ``` ## Tips For a "daily briefing" style tile on your main dashboard, combine `rolling_days_agenda: 7`, `hide_empty_days: true`, and `past_event_mode: hide`. The card will always show a clean, forward-looking week of events with no clutter from things that have already passed. If you want the Agenda view inside a fixed-height grid card, add `compact_height: true` to prevent the list from expanding the card's vertical footprint as the event count grows. The list will scroll internally within the fixed container instead. Prefer one-line compact event titles? Use `uix.style` to truncate them with an ellipsis: ```yaml theme={null} uix: style: | .calendar-container.agenda-compact-events .agenda-event-title { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } ``` # Month View: Full Monthly Calendar Grid Source: https://docs.daylightcalendar.com/views/month The Month view displays a monthly calendar grid with event chips. Configure overflow, week numbers, and detail options for your Home Assistant card. The Month view renders a classic calendar grid — one row per week, one column per day — giving you an at-a-glance picture of the entire month. Events appear as colored chips on each day cell, and you can tap any chip to open the event detail panel. Use the arrow buttons in the card header to move between months, or swipe left and right directly on the grid. ## Activating Month View Set `default_view` to `month` in your card configuration to open the card on the monthly grid by default: ```yaml theme={null} type: custom:daylight-calendar-card default_view: month ``` Users can still switch to other views using the view selector buttons in the card header. To hide those buttons and lock the card to Month view, add `hide_view_selector: true`. ## Configuration Options Used by **Month** only. By default, day cells truncate their event list and show a **+N more** overflow label when there are more events than fit in the cell. Set this to `true` to expand every day cell and display all events without truncation. This increases the row height dynamically, so the card will grow taller on busy weeks. Used by **Month** only. When `true`, each event chip in the month grid includes the event start time and any additional detail text alongside the event title. This is also the flag that enables `show_event_location` / `use_short_location` rendering in Month — otherwise location is omitted from Month event chips. Used by **Month** only. Adds an ISO week-number column on the left edge of the grid (e.g., **CW 23** in English, **wk 23** in Dutch). The prefix is localized automatically — use `week_number_prefix` to override it. Handy for work or project planning where teams reference week numbers. Used by **Month** and **Week** when their week-number options are enabled. Controls the text shown before ISO week numbers in the Month grid and Week header. Three modes: * **Omit the option** (or set it to `null`) to use the localized default for the card's language (`CW` in English, `wk` in Dutch, `Sem` in French, and so on). * **Set a custom string** to replace the prefix. Surrounding whitespace is trimmed and the card adds exactly one space between the prefix and the number. * **Set an empty string** (`""`) to hide the prefix entirely and show only the week number. In the Month grid, the accessibility label always announces the full localized `Week {number}` phrase for screen readers regardless of the visible prefix. ```yaml theme={null} type: custom:daylight-calendar-card show_week_numbers_month: true # Custom prefix renders "Week 23" week_number_prefix: Week ``` ```yaml theme={null} type: custom:daylight-calendar-card show_week_numbers_month: true # Number only renders "23" week_number_prefix: "" ``` Used by **Month** only. Controls what happens when you tap an empty part of a day cell (tapping an event chip always opens that event's detail). Accepted values: * **`create`** (default) — preserves the existing behavior: * if event management is enabled, `disable_event_creation` is `false`, **and** there is at least one writable calendar → open the new-event form prefilled with that date; * otherwise, if the day has visible events → open the day-events popup (see below); * otherwise (a day with no visible events and no way to create one) → nothing happens. * **`show_events`** — tapping a day that **has visible events** opens a popup listing that day's **visible** events (i.e. after hidden-calendar, hidden-style, and `past_event_mode` filtering); tap any event there to view, edit, or delete it. **Empty days still open the new-event form** when event management is enabled, `disable_event_creation` is `false`, and a writable calendar exists; otherwise an empty day does nothing. In the `show_events` popup, an **Add Event** button (prefilled with that date) is shown when **all** of the following are true: event management is enabled, `disable_event_creation` is `false`, at least one writable calendar exists, and [`hide_add_event_button`](/configuration/event-management) is `false`. Within the popup, closing an event's details — or adding, editing, or deleting an event — returns you to the day-events list (refreshed), rather than dropping back to the calendar. This is handy on phones, where a busy day's chips can be hard to read in the grid. Used by **Month** only. By default, Month view snaps to a full calendar month — every cell from the 1st to the last day of the current month, padded with neighboring days to fill complete weeks. Set `rolling_weeks` to a positive integer to switch to a **rolling N-week window** that always starts on the current week and looks forward `N` weeks. For example, `rolling_weeks: 4` renders four week rows: this week plus the next three. Navigation arrows shift the window one week at a time instead of one month. Used by **Month**, **Week Compact**, and **Schedule**. In Week Compact and Schedule, only affects normal week mode — it is ignored in rolling-days mode. The day number (0–6) that anchors the left edge of the grid. Set to `1` to start each row on Monday. Used by **Month**, **Week**, **Schedule**, and **Agenda**. When `true`, event time labels are abbreviated — for example `10 AM` instead of `10:00 AM`. In Month, time labels only appear on event chips when `show_all_details_month` is enabled. Used by **Month**, **Week**, **Schedule**, and **Agenda**. Despite the name, it is used by the shared event-time formatter, not only the Schedule view. When `true`, event times use 24-hour format (e.g. `14:00`) instead of 12-hour format with AM/PM. Used by **Week**, **Schedule**, and **Agenda**. Also applies to **Month** only when `show_all_details_month` is enabled — it does not affect normal Month event chips. When `true`, the location field of each event is displayed below the event title. Used by **Week**, **Schedule**, and **Agenda**. Also applies to **Month** only when `show_all_details_month` is enabled. Has no visible effect unless `show_event_location` is also enabled. Truncates long location strings to a shorter form so they don't push event chips taller. Used by **Month**, **Week**, **Schedule**, and **Agenda**. An array of calendar entity IDs whose events should not display time labels. Useful for all-day-style calendars where exact times are noise. Used by **Month**, **Week**, **Schedule**, and **Agenda**. Controls how events that have already ended are handled across the card. Accepted values: * `none` — past events look identical to upcoming events (default). * `muted` — past events are rendered at reduced opacity so today's and future events stand out. * `hide` — past events are not rendered at all. ## Example Configuration The following configuration activates Month view with week numbers, full event lists, and muted past events: ```yaml theme={null} type: custom:daylight-calendar-card default_view: month show_all_events_month: true show_all_details_month: false show_week_numbers_month: true past_event_mode: muted ``` ## Tips If you place the Daylight Calendar Card inside a **panel** or **grid** dashboard layout where the card is expected to fill a fixed container, add `compact_height: true`. This makes the card match its parent container's height exactly instead of expanding to fit all content, preventing layout overflow on busy months. Combine `show_all_events_month: false` (the default) with `past_event_mode: muted` for the cleanest month view: upcoming events pop visually while past events fade into the background without disappearing entirely. # Schedule View: Timed Weekly Grid for Daylight Calendar Source: https://docs.daylightcalendar.com/views/schedule Schedule view renders a timed weekly grid with days as columns and hours as rows, positioning events as blocks by their actual start and end times. Schedule view renders your week as a **timed grid** — days as columns, hours as rows. Events appear as blocks positioned by their real start and end times, so you can see event duration, gaps between commitments, overlapping meetings, and where the current moment falls relative to what's coming next. This is the right view when you care about **time-of-day precision**, not just which day something is on. ## Activating Schedule View Set `default_view` to `schedule` (or its canonical name `week-standard`) in your card configuration: ```yaml theme={null} type: custom:daylight-calendar-card default_view: schedule entities: - calendar.family ``` `schedule` and `week-standard` refer to the same timed grid view. The card normalizes `schedule` to `week-standard` internally. New examples use `schedule` because that is the user-facing label in the view selector. ## When to use Schedule Schedule is the right choice when you want to: * See **meetings** laid out on a real timeline. * Plan a **workday** and know exactly when things start and end. * **Spot gaps and conflicts** at a glance — overlapping blocks are visually obvious. * **View event duration spatially** — a one-hour event and a three-hour event look proportionally different. ## Configuration Options Used by **Schedule** only. The earliest hour row displayed in the timed grid, in 24-hour format (0–23). Without `lock_schedule_hours`, the grid expands upward as needed to include any event that starts before this hour. Used by **Schedule** only. The latest hour row displayed in the timed grid, in 24-hour format (0–23). Without `lock_schedule_hours`, the grid expands downward to accommodate late events. Used by **Schedule** only. When `true`, the hour range is fixed to exactly `week_start_hour` through `week_end_hour` regardless of where events fall. The grid will not expand to show events outside that window. Use this to keep the Schedule view anchored to working hours and prevent layout shifts when outlier events exist. Used by **Schedule** only. When `true`, renders a horizontal "now" line across today's column at the current time of day, giving you a live "you are here" marker against your scheduled events. Used by **Week**. Ignored in those views when their `rolling_days_*` option is set. An array of day numbers controlling which days appear as columns. Days are numbered `0` (Sunday) through `6` (Saturday). Pass `[1,2,3,4,5]` to show Monday through Friday only. Used by **Month**, **Week**, and **Schedule**. In Week Compact and Schedule, only affects normal week mode — it is ignored in rolling-days mode. The day number (0–6) that anchors the left edge of the week. Set to `1` to start each week on Monday. Used by **Schedule** only. By default Schedule snaps to full calendar weeks. Set `rolling_days_schedule` to a positive integer to switch to a rolling window of that many days starting from today, rather than aligning to week boundaries. When set, `week_days` and `first_day_of_week` are ignored in this view. Used by **Month**, **Week**, **Schedule**, and **Agenda**. Despite the name, it is used by the shared event-time formatter, not only the Schedule view. When `true`, event times use 24-hour format (e.g. `14:00`) instead of 12-hour format with AM/PM. Used by **Month**, **Week**, **Schedule**, and **Agenda**. When `true`, event time labels are abbreviated — for example `10 AM` instead of `10:00 AM`, or `10h` in 24-hour mode. Useful when columns are narrow. Used by **Week**, **Schedule**, and **Agenda**. Also applies to **Month** only when `show_all_details_month` is enabled (it does not affect normal Month event bubbles). When `true`, the location field of each event is displayed on a second line below the event title. Used by **Week**, **Schedule**, and **Agenda**. Also applies to **Month** only when `show_all_details_month` is enabled. Has no visible effect unless `show_event_location` is also enabled. Truncates long location strings to a shorter form so they don't push event blocks taller. Used by **Month**, **Week**, **Schedule**, and **Agenda**. An array of calendar entity IDs whose events should not display time labels. Useful for all-day-style calendars where exact times are noise. Used by **Month**, **Week**, **Schedule**, and **Agenda**. Controls how events that have already ended are handled across the card. Accepted values: * `none` — past events look identical to upcoming events (default). * `muted` — past events render at reduced opacity to de-emphasise them. * `hide` — past events are not rendered. ## Example Configuration A workday-oriented Schedule view from 8 AM to 6 PM, Monday through Friday, with the current-time bar enabled and past events muted: ```yaml theme={null} type: custom:daylight-calendar-card default_view: schedule entities: - calendar.family - calendar.work week_days: [1, 2, 3, 4, 5] week_start_hour: 8 week_end_hour: 18 lock_schedule_hours: true show_current_time_bar: true shorten_event_times: true past_event_mode: muted ``` ## Tips Pair `lock_schedule_hours: true` with a tight `week_start_hour` / `week_end_hour` range to keep the grid anchored to your working day, even if a late-evening event slips into your calendar. All-day events are rendered in a separate banner row at the top of the grid, above the timed columns. They are always visible regardless of the `week_start_hour` / `week_end_hour` range. Looking for a simpler weekly overview without an hourly grid? See [Week Compact view](/views/week). # Week View: Glanceable Weekly Calendar Layout Source: https://docs.daylightcalendar.com/views/week Week view shows each day of the week as a column with stacked events, providing a clean, glanceable layout for family dashboards and wall tablets. Week view shows each day of the week as its own column, with that day's events stacked beneath the date. It is designed for **quick scanning** rather than minute-by-minute planning: you see what is happening on each day at a glance, without an hourly grid. For a full hourly grid with event blocks positioned by their start and end times, use the [Schedule view](/views/schedule) instead. ## Activating Week View Set `default_view` to `week-compact` (or its shorthand `week`) in your card configuration: ```yaml theme={null} type: custom:daylight-calendar-card default_view: week-compact entities: - calendar.family ``` Both `week` and `week-compact` refer to the same view. The card normalizes `week` to `week-compact` internally. ## When to use Week Compact Week Compact is the right choice when you want: * **Family wall dashboards** that need to be readable from across the room. * A **weekly overview** without the visual weight of a time-grid. * **Narrow dashboard columns** or sidebar placements where a full timed grid wouldn't fit. * **Quick weekly planning** — see what each day looks like without zooming into hours. ## Configuration Options Used by **Week** and **Schedule**. Ignored in those views when their `rolling_days_*` option is set. An array of day numbers controlling which days appear as columns. Days are numbered `0` (Sunday) through `6` (Saturday). Pass `[1,2,3,4,5]` to show Monday through Friday only, making each column wider and easier to read on smaller screens. Used by **Month**, **Week**, and **Schedule**. In Week Compact and Schedule, only affects normal week mode — it is ignored in rolling-days mode. The day number (0–6) that anchors the left edge of the week. Set to `1` to start each week on Monday. Used by **Week** only. By default Week Compact snaps to full calendar weeks. Set `rolling_days_week_compact` to a positive integer to switch to a rolling window of that many days starting from today, rather than aligning to week boundaries. When set, `week_days` and `first_day_of_week` are ignored in this view. Used by **Week** only. Shows the ISO week number in the header. If the visible dates span multiple ISO weeks, the header shows the visible week range (for example, **CW 37–38**). A range that crosses the ISO year boundary is split instead of shown as a descending range (for example, **CW 52–53 / 1**). The prefix is localized automatically and can be customized or hidden with `week_number_prefix`. Used by **Week** and **Schedule** day headers only. It does not change Month, Agenda, or day badge matching. * `inline` — the default. The day number and matching day badges share one row. * `stacked` — matching day badges appear below the day number. This gives icon-and-text badges more room on tablet dashboards. ```yaml theme={null} day_badge_layout_week: stacked ``` Used by **Month**, **Week**, **Schedule**, and **Agenda**. When `true`, event time labels are abbreviated — for example `10 AM` instead of `10:00 AM` — saving horizontal space in narrow columns. Used by **Week**, **Schedule**, and **Agenda**. Also applies to **Month** only when `show_all_details_month` is enabled (it does not affect normal Month event bubbles). When `true`, the location field of each event is displayed on a second line below the event title. Used by **Week**, **Schedule**, and **Agenda**. Also applies to **Month** only when `show_all_details_month` is enabled. Has no visible effect unless `show_event_location` is also enabled. Truncates long location strings to a shorter form so they don't push event blocks taller. Used by **Month**, **Week**, **Schedule**, and **Agenda**. Despite the name, it is used by the shared event-time formatter, not only the Schedule view. When `true`, event times use 24-hour format (e.g. `14:00`) instead of 12-hour format with AM/PM. Used by **Month**, **Week**, **Schedule**, and **Agenda**. An array of calendar entity IDs whose events should not display time labels. Useful for all-day-style calendars where exact times are noise. Used by **Month**, **Week**, **Schedule**, and **Agenda**. Controls how events that have already ended are handled across the card. Accepted values: * `none` — past events look identical to upcoming events (default). * `muted` — past events render at reduced opacity. * `hide` — past events are not rendered. Timed-grid options like `week_start_hour`, `week_end_hour`, `lock_schedule_hours`, and `show_current_time_bar` belong to the [Schedule view](/views/schedule). They do not apply here because Week Compact does not render an hourly grid. ## Example Configuration A Monday-to-Friday compact week with shortened event times — useful for a narrow sidebar card: ```yaml theme={null} type: custom:daylight-calendar-card default_view: week-compact entities: - calendar.family - calendar.work week_days: [1, 2, 3, 4, 5] shorten_event_times: true ``` ## Tips Removing weekend columns with `week_days: [1,2,3,4,5]` makes each weekday column noticeably wider. On a narrow sidebar card this can be the difference between readable event titles and truncated text. Want a moving "today + next few days" view instead of a fixed calendar week? Set `rolling_days_week_compact: 6` to show today plus the next six days.