diff --git a/agents/skills/grill-me/SKILL.md b/agents/skills/grill-me/SKILL.md
new file mode 100644
index 00000000000000..f19dd749bd43db
--- /dev/null
+++ b/agents/skills/grill-me/SKILL.md
@@ -0,0 +1,10 @@
+---
+name: grill-me
+description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me".
+---
+
+Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
+
+Ask the questions one at a time.
+
+If a question can be answered by exploring the codebase, explore the codebase instead.
\ No newline at end of file
diff --git a/agents/skills/prd-to-plan/SKILL.md b/agents/skills/prd-to-plan/SKILL.md
new file mode 100644
index 00000000000000..a5da1c2f1fbc3c
--- /dev/null
+++ b/agents/skills/prd-to-plan/SKILL.md
@@ -0,0 +1,107 @@
+---
+name: prd-to-plan
+description: Turn a PRD into a multi-phase implementation plan using tracer-bullet vertical slices, saved as a local Markdown file in ./plans/. Use when user wants to break down a PRD, create an implementation plan, plan phases from a PRD, or mentions "tracer bullets".
+---
+
+# PRD to Plan
+
+Break a PRD into a phased implementation plan using vertical slices (tracer bullets). Output is a Markdown file in `./plans/`.
+
+## Process
+
+### 1. Confirm the PRD is in context
+
+The PRD should already be in the conversation. If it isn't, ask the user to paste it or point you to the file.
+
+### 2. Explore the codebase
+
+If you have not already explored the codebase, do so to understand the current architecture, existing patterns, and integration layers.
+
+### 3. Identify durable architectural decisions
+
+Before slicing, identify high-level decisions that are unlikely to change throughout implementation:
+
+- Route structures / URL patterns
+- Database schema shape
+- Key data models
+- Authentication / authorization approach
+- Third-party service boundaries
+
+These go in the plan header so every phase can reference them.
+
+### 4. Draft vertical slices
+
+Break the PRD into **tracer bullet** phases. Each phase is a thin vertical slice that cuts through ALL integration layers end-to-end, NOT a horizontal slice of one layer.
+
+
+- Each slice delivers a narrow but COMPLETE path through every layer (schema, API, UI, tests)
+- A completed slice is demoable or verifiable on its own
+- Prefer many thin slices over few thick ones
+- Do NOT include specific file names, function names, or implementation details that are likely to change as later phases are built
+- DO include durable decisions: route paths, schema shapes, data model names
+
+
+### 5. Quiz the user
+
+Present the proposed breakdown as a numbered list. For each phase show:
+
+- **Title**: short descriptive name
+- **User stories covered**: which user stories from the PRD this addresses
+
+Ask the user:
+
+- Does the granularity feel right? (too coarse / too fine)
+- Should any phases be merged or split further?
+
+Iterate until the user approves the breakdown.
+
+### 6. Write the plan file
+
+Create `./plans/` if it doesn't exist. Write the plan as a Markdown file named after the feature (e.g. `./plans/user-onboarding.md`). Use the template below.
+
+
+# Plan:
+
+> Source PRD:
+
+## Architectural decisions
+
+Durable decisions that apply across all phases:
+
+- **Routes**: ...
+- **Schema**: ...
+- **Key models**: ...
+- (add/remove sections as appropriate)
+
+---
+
+## Phase 1:
+
+**User stories**:
+
+### What to build
+
+A concise description of this vertical slice. Describe the end-to-end behavior, not layer-by-layer implementation.
+
+### Acceptance criteria
+
+- [ ] Criterion 1
+- [ ] Criterion 2
+- [ ] Criterion 3
+
+---
+
+## Phase 2:
+
+**User stories**:
+
+### What to build
+
+...
+
+### Acceptance criteria
+
+- [ ] ...
+
+
+
diff --git a/agents/skills/worldcup-fixtures/SKILL.md b/agents/skills/worldcup-fixtures/SKILL.md
new file mode 100644
index 00000000000000..b0523ee73dec54
--- /dev/null
+++ b/agents/skills/worldcup-fixtures/SKILL.md
@@ -0,0 +1,114 @@
+---
+name: worldcup-fixtures
+description: Fetch 2026 FIFA World Cup match fixtures from the official FIFA API, update a local JSON file, and add newly fetched games to the Cal.diy app calendar. Merges new games without duplicating existing ones, then opens a PR with the updated data. Use when asked to update World Cup fixtures, sync FIFA schedule, refresh World Cup game times, add World Cup games to calendar, or fetch match data for a specific country.
+---
+
+# World Cup Fixtures Updater
+
+## Quick start
+
+```
+/worldcup-fixtures country=BR
+```
+
+Fetches all 2026 FIFA World Cup matches for the given country filter, merges them into `data/worldcup-2026-fixtures.json`, and opens a draft PR.
+
+## Workflow
+
+1. **Accept parameters**
+ - `country` (required) — FIFA country code (e.g. `BR`, `US`, `DE`). Filters to matches involving that country.
+ - `output` (optional) — path to the local fixtures file (default: `data/worldcup-2026-fixtures.json`).
+
+2. **Fetch from FIFA API**
+
+ The tournament spans ~2 months; a single API call may not return all matches. Make **two requests** using date-window splits to ensure complete coverage:
+
+ ```
+ # Request 1 — group stage + round of 16
+ GET https://api.fifa.com/api/v3/calendar/matches
+ ?idCompetition=17
+ &idSeason=285023
+ &count=500
+ &language=en
+ &from=2026-06-01T00:00:00Z
+ &to=2026-07-01T00:00:00Z
+
+ # Request 2 — quarter-finals through final
+ GET https://api.fifa.com/api/v3/calendar/matches
+ ?idCompetition=17
+ &idSeason=285023
+ &count=500
+ &language=en
+ &from=2026-07-01T00:00:00Z
+ &to=2026-07-20T00:00:00Z
+ ```
+
+ Merge results from both requests by `IdMatch` before filtering.
+
+ Key response fields per match:
+ | Field | Description |
+ |---|---|
+ | `IdMatch` | Unique match ID — use as deduplication key |
+ | `Date` | UTC datetime string (`2026-06-11T19:00:00Z`) |
+ | `LocalDate` | Local kickoff time |
+ | `StageName[0].Description` | Phase (Group Stage, Round of 16…) |
+ | `GroupName[0].Description` | Group letter (null for knockout rounds) |
+ | `Home.IdCountry` | Home team's FIFA country code |
+ | `Home.TeamName[0].Description` | Home team name |
+ | `Away.IdCountry` | Away team's FIFA country code |
+ | `Away.TeamName[0].Description` | Away team name |
+ | `Stadium.Name[0].Description` | Venue name |
+ | `Stadium.CityName[0].Description` | Host city |
+ | `MatchStatus` | `0` = scheduled, `1` = live, `3` = finished |
+
+3. **Filter by country** — keep only matches where either `Home.IdCountry` or `Away.IdCountry` equals the requested country code. Check **both** fields for every match — a country can appear as home or away in any match. If no country filter is requested keep all matches.
+
+4. **Load the existing file** — read `output` path. If the file doesn't exist, treat the existing list as `[]`.
+
+5. **Merge without duplicates** — build a set of existing `IdMatch` values. Append only matches whose `IdMatch` is not already present. Never modify existing entries.
+
+6. **Write the updated file** — output format:
+
+ ```json
+ {
+ "updatedAt": "2026-05-19T14:00:00Z",
+ "country": "BR",
+ "matches": [
+ {
+ "id": "300438203",
+ "date": "2026-06-11T19:00:00Z",
+ "localDate": "2026-06-11T15:00:00Z",
+ "stage": "Group Stage",
+ "group": "Group F",
+ "home": "Brazil",
+ "away": "Mexico",
+ "venue": "SoFi Stadium",
+ "city": "Los Angeles",
+ "status": "scheduled"
+ }
+ ]
+ }
+ ```
+
+ Map `MatchStatus` → `status`: `0` → `"scheduled"`, `1` → `"live"`, `3` → `"finished"`.
+
+7. **Matches are shown as busy times in the Cal.diy scheduling calendar** — the fixtures JSON file is read server-side by `packages/features/busyTimes/lib/getWorldCupBusyTimes.ts`, which injects the matches as `EventBusyDetails` into the availability engine in `packages/features/availability/lib/getUserAvailability.ts`. No extra step is needed here — updating the JSON file is sufficient to make the matches appear as busy on the scheduling page.
+
+8. **Report the result** — print a summary:
+ - How many matches were fetched from the API
+ - How many were new (added)
+ - How many were skipped (already existed)
+ - Total matches now in the file
+
+9. **Open a draft PR** — commit the updated file and open a draft PR with title:
+ ```
+ chore(fixtures): update 2026 World Cup fixtures for [COUNTRY] ([DATE])
+ ```
+
+## Notes
+
+- The FIFA API returns UTC dates. Always preserve both `Date` (UTC) and `LocalDate` in the output so callers can choose.
+- `IdSeason=285023` is the 2026 FIFA World Cup Canada/Mexico/USA season ID.
+- `IdCompetition=17` is the FIFA World Cup competition ID (permanent).
+- The API supports `from` and `to` query params (ISO datetime) if you need to limit the date window.
+- If the API returns no matches, warn the user — the season ID may have changed. Verify at: `https://api.fifa.com/api/v3/calendar/matches?idCompetition=17&count=5&language=en&from=2026-01-01T00:00:00Z`
diff --git a/agents/skills/write-a-prd/SKILL.md b/agents/skills/write-a-prd/SKILL.md
new file mode 100644
index 00000000000000..6869e486c5d091
--- /dev/null
+++ b/agents/skills/write-a-prd/SKILL.md
@@ -0,0 +1,55 @@
+This skill will be invoked when the user wants to create a PRD. You should go through the steps below. You may skip steps if you don't consider them necessary.
+
+1. Ask the user for a long, detailed description of the problem they want to solve and any potential ideas for solutions.
+
+2. Explore the repo to verify their assertions and understand the current state of the codebase.
+
+3. Interview the user relentlessly about every aspect of this plan until you reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one.
+
+4. Once you have a complete understanding of the problem and solution, use the template below to write the PRD. The PRD should be written in the `plans/prd-name.md` file.
+
+
+
+## Problem Statement
+
+The problem that the user is facing, from the user's perspective.
+
+## Solution
+
+The solution to the problem, from the user's perspective.
+
+## User Stories
+
+A LONG, numbered list of user stories. Each user story should be in the format of:
+
+1. As an , I want a , so that
+
+
+1. As a mobile bank customer, I want to see balance on my accounts, so that I can make better informed decisions about my spending
+
+
+This list of user stories should be extremely extensive and cover all aspects of the feature.
+
+## Implementation Decisions
+
+A list of implementation decisions that were made. This can include:
+
+- The modules that will be built/modified
+- The interfaces of those modules that will be modified
+- Technical clarifications from the developer
+- Architectural decisions
+- Schema changes
+- API contracts
+- Specific interactions
+
+Do NOT include specific file paths or code snippets. They may end up being outdated very quickly.
+
+## Out of Scope
+
+A description of the things that are out of scope for this PRD.
+
+## Further Notes
+
+Any further notes about the feature.
+
+
diff --git a/agents/skills/write-a-skill/SKILL.md b/agents/skills/write-a-skill/SKILL.md
new file mode 100644
index 00000000000000..221c6006bb46b7
--- /dev/null
+++ b/agents/skills/write-a-skill/SKILL.md
@@ -0,0 +1,112 @@
+# Writing Skills
+
+## Process
+
+1. **Gather requirements** - ask user about:
+ - What task/domain does the skill cover?
+ - What specific use cases should it handle?
+ - Does it need executable scripts or just instructions?
+ - Any reference materials to include?
+
+2. **Draft the skill** - create:
+ - SKILL.md with concise instructions
+ - Additional reference files if content exceeds 500 lines
+ - Utility scripts if deterministic operations needed
+
+3. **Review with user** - present draft and ask:
+ - Does this cover your use cases?
+ - Anything missing or unclear?
+ - Should any section be more/less detailed?
+
+## Skill Structure
+
+```
+skill-name/
+├── SKILL.md # Main instructions (required)
+├── REFERENCE.md # Detailed docs (if needed)
+├── EXAMPLES.md # Usage examples (if needed)
+└── scripts/ # Utility scripts (if needed)
+ └── helper.js
+```
+
+## SKILL.md Template
+
+```md
+---
+name: skill-name
+description: Brief description of capability. Use when [specific triggers].
+---
+
+# Skill Name
+
+## Quick start
+
+[Minimal working example]
+
+## Workflows
+
+[Step-by-step processes with checklists for complex tasks]
+
+## Advanced features
+
+[Link to separate files: See [REFERENCE.md](REFERENCE.md)]
+```
+
+## Description Requirements
+
+The description is **the only thing your agent sees** when deciding which skill to load. It's surfaced in the system prompt alongside all other installed skills. Your agent reads these descriptions and picks the relevant skill based on the user's request.
+
+**Goal**: Give your agent just enough info to know:
+
+1. What capability this skill provides
+2. When/why to trigger it (specific keywords, contexts, file types)
+
+**Format**:
+
+- Max 1024 chars
+- Write in third person
+- First sentence: what it does
+- Second sentence: "Use when [specific triggers]"
+
+**Good example**:
+
+```
+Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when user mentions PDFs, forms, or document extraction.
+```
+
+**Bad example**:
+
+```
+Helps with documents.
+```
+
+The bad example gives your agent no way to distinguish this from other document skills.
+
+## When to Add Scripts
+
+Add utility scripts when:
+
+- Operation is deterministic (validation, formatting)
+- Same code would be generated repeatedly
+- Errors need explicit handling
+
+Scripts save tokens and improve reliability vs generated code.
+
+## When to Split Files
+
+Split into separate files when:
+
+- SKILL.md exceeds 100 lines
+- Content has distinct domains (finance vs sales schemas)
+- Advanced features are rarely needed
+
+## Review Checklist
+
+After drafting, verify:
+
+- [ ] Description includes triggers ("Use when...")
+- [ ] SKILL.md under 100 lines
+- [ ] No time-sensitive info
+- [ ] Consistent terminology
+- [ ] Concrete examples included
+- [ ] References one level deep
diff --git a/apps/web/app/(booking-page-wrapper)/booking-successful/[uid]/page.tsx b/apps/web/app/(booking-page-wrapper)/booking-successful/[uid]/page.tsx
index 36d5e3a34206f6..3259fbc078ec38 100644
--- a/apps/web/app/(booking-page-wrapper)/booking-successful/[uid]/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/booking-successful/[uid]/page.tsx
@@ -3,6 +3,7 @@
import { useParams } from "next/navigation";
import dayjs from "@calcom/dayjs";
+import { ChristmasEasterEgg } from "~/bookings/components/ChristmasEasterEgg";
import { DecoyBookingSuccessCard } from "~/bookings/components/DecoyBookingSuccessCard";
import { useDecoyBooking } from "~/bookings/hooks/useDecoyBooking";
@@ -23,6 +24,9 @@ export default function BookingSuccessful() {
const endTime = booking.endTime ? dayjs(booking.endTime) : null;
const timeZone = booking.booker?.timeZone || booking.host?.timeZone || dayjs.tz.guess();
+ // dayjs month() is 0-indexed, so December = 11
+ const isChristmas = startTime ? startTime.month() === 11 && startTime.date() === 25 : false;
+
const formattedDate = startTime ? startTime.tz(timeZone).format("dddd, MMMM D, YYYY") : "";
const formattedTime = startTime ? startTime.tz(timeZone).format("h:mm A") : "";
const formattedEndTime = endTime ? endTime.tz(timeZone).format("h:mm A") : "";
@@ -34,17 +38,20 @@ export default function BookingSuccessful() {
const attendeeEmail = booking.booker?.email || null;
return (
-
+ <>
+ {isChristmas && }
+
+ >
);
}
diff --git a/apps/web/modules/bookings/components/Booker.tsx b/apps/web/modules/bookings/components/Booker.tsx
index f2f6179d9429b8..e0d8b147299cdd 100644
--- a/apps/web/modules/bookings/components/Booker.tsx
+++ b/apps/web/modules/bookings/components/Booker.tsx
@@ -49,6 +49,7 @@ import { HavingTroubleFindingTime } from "./HavingTroubleFindingTime";
import { LargeCalendar } from "./LargeCalendar";
import { OverlayCalendar } from "./OverlayCalendar/OverlayCalendar";
import { SlotSelectionModalHeader } from "./SlotSelectionModalHeader";
+import { ChristmasEasterEgg } from "./ChristmasEasterEgg";
import { NotFound } from "./Unavailable";
import { VerifyCodeDialog } from "./VerifyCodeDialog";
@@ -120,6 +121,11 @@ const BookerComponent = ({
shallow
);
const { selectedTimeslot, setSelectedTimeslot, allSelectedTimeslots } = slots;
+
+ // dayjs month() is 0-indexed: December = 11
+ const isChristmasSelected = selectedDate
+ ? dayjs(selectedDate).month() === 11 && dayjs(selectedDate).date() === 25
+ : false;
const [dayCount, setDayCount] = useBookerStoreContext(
(state) => [state.dayCount, state.setDayCount],
shallow
@@ -623,6 +629,7 @@ const BookerComponent = ({
/>
+ {isChristmasSelected && }
>
);
diff --git a/apps/web/modules/bookings/components/ChristmasEasterEgg.tsx b/apps/web/modules/bookings/components/ChristmasEasterEgg.tsx
new file mode 100644
index 00000000000000..3cc832c88696b7
--- /dev/null
+++ b/apps/web/modules/bookings/components/ChristmasEasterEgg.tsx
@@ -0,0 +1,233 @@
+"use client";
+
+import { useEffect, useState } from "react";
+
+export function ChristmasEasterEgg() {
+ const [visible, setVisible] = useState(true);
+
+ useEffect(() => {
+ const timer = setTimeout(() => setVisible(false), 4000);
+ return () => clearTimeout(timer);
+ }, []);
+
+ if (!visible) return null;
+
+ return (
+