=== Mobile-Refuel Tischreservierungen ===
Contributors: maksim85
Tags: table reservation, restaurant booking, online booking, table reservation, reservation system
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 3.0.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Professional table reservation system for restaurants. Manage bookings, opening hours, and guest communications.

== Description ==

A professional and comprehensive table reservation solution for restaurants, cafes, and food trucks looking to digitize and streamline their booking process. Through an intuitive, multi-step form, your guests can find and book available tables in real-time.

In the backend, you always have full control. Manage all reservations, adjust their status, add manual bookings, and communicate directly with your guests. Guests can also cancel their reservations independently via a secure link in their confirmation email. Thanks to flexible settings, you can perfectly adapt the system to the needs of your restaurant, cafe, or food truck.

This is a premium plugin with a **free trial period**. After the trial expires, a valid license is required to continue using all features.

== Main Features ==

* **Setup Wizard:**
  - Guides new users step-by-step through the most important settings.
  - Configures basic data, opening hours, and capacity in just a few minutes.
  - Can be reset and restarted at any time via the settings.

* **Dashboard:**
  - Graphical overview of the current day's reservations.
  - Lists for "Upcoming Today," "Recently Received," and "Next Upcoming."
  - Quick actions to confirm or reject reservations directly from the dashboard.
  - Key statistics at a glance (reservations today, pending, total capacity).
  
* **Reservation List:**
  - Detailed list of all reservations, divided into "Upcoming," "Past," and "All."
  - **Flexible View Modes:**
    - **Card View:** Modern card-based layout, ideal for mobile devices and touch interfaces. Default view on first visit.
    - **Table View:** Classic table layout with comprehensive information at a glance.
    - Toggle button to switch between views. Your preference is automatically saved.
  - Powerful search and filter functionality.
  - CSV and PDF export for all reservations (via export modal, choose format and layout).
  - Bulk actions to change the status of or delete multiple entries at once.

* **Calendar View:**
  - Complete calendar view in the backend with FullCalendar.
  - Month, week, and day views.
  - Dynamic time slots: Week view shows earliest to latest time across all days, day view shows specific opening hours.
  - Automatic adjustment based on configured opening hours.
  - Clicking on a reservation opens a detailed modal.
  - Status changes can be made directly from the calendar.

* **Calendar Subscription (iCal Feed):**
  - Subscribe to your reservations in external calendar applications.
  - Support for Google Calendar, Outlook, Apple Calendar, Thunderbird.
  - Color-coded events (green for confirmed, orange for pending).
  - Token-based authentication for secure access.
  
* **Event Management:**
  - Define special event types for occasions like birthdays, weddings, corporate events, etc.
  - Configurable event duration for each event type (e.g., birthday: 120 min, wedding: 240 min).
  - **Availability types:** Events can be restricted to specific weekdays (e.g., "Weddings only on Fridays & Saturdays") or tied to hand-picked special dates (e.g., fixed event nights).
  - **Tile-based date selection:** For special_dates events, guests pick from visual date tiles instead of a calendar — no date confusion, no unavailable-day clicks.
  - **Single-event mode:** If exactly one event type is configured, the event tile displays the event name directly and activates without showing a dropdown.
  - **Events override closed weekdays:** A day that is normally closed can be opened automatically when an event is scheduled on it — configured per event type.
  - **Slot validation:** Only time slots where the full event duration fits before closing time are shown to guests, preventing uncompletable bookings.
  - Display event duration in frontend (optional).
  - Separate event booking flow in reservation form.
  - Customizable form headings for event-specific steps.
  - Events are considered in capacity planning with their specific duration.
  - Backend displays event type instead of message field when applicable.
  - Admin manual reservation form supports the same event-aware date filtering (tile selection for special_dates, weekday filtering for weekday-type events) as the frontend.

* **Capacity Planning:**
  - Configurable time interval for reservations (e.g., every 30 minutes).
  - Maximum number of seats to prevent overbooking.
  - Adjustable guest stay duration for realistic capacity planning.
  - Event-specific duration automatically applied to event reservations.
  - **Kitchen Capacity Planning:** Optionally limit the maximum number of guests that can start dining within the same time interval (kitchen throughput limit). When enabled, a time slot becomes unavailable as soon as the sum of guests already booked in that interval plus the current request would exceed the configured threshold – even if overall restaurant capacity is not yet reached.

* **Opening Hours & Holidays:**
  - Flexible management of weekly opening hours.
  - Holidays & Special Opening Hours:
    - Define any number of individual dates with different rules.
    - Option to close for reservations for an entire day (e.g., holidays, company vacation).
    - Option to set custom opening hours for a specific day that differ from the regular weekly settings (e.g., for events).
  - **Vacation & Season Management:** Define closed periods (e.g. company holidays, seasonal breaks) that automatically block all days within the range for reservations. Configured vacation dates are highlighted in orange in all backend datepickers (Settings, New Reservation).
  
* **Email System:**
  - Language-specific Email Templates:
    - Separate, customizable templates for 4 different occasions per language:
        1.  **Reservation Request** (Automatic email sent immediately after guest booking)
        2.  **Reservation Confirmed** (Manual email from admin)
        3.  **Reservation Rejected** (Manual email from admin)
        4.  **Reservation Canceled** (Automatic email after guest cancellation)
  - Placeholders for personalizing emails ({name}, {date}, {time}, etc.).

* **Cancellations:**
  - Guests can cancel reservations themselves via a link in the email.
  - Adjustable deadline for when a cancellation is possible (e.g., 24 hours in advance).
  - Display of a phone number for late cancellation requests.
  - Admin notification email when a guest cancels a reservation.
  - Separate email template for admin cancellation notifications.

* **Direct Messaging (WhatsApp / Telegram):**
  - Send a personal confirmation directly to the guest's smartphone via WhatsApp or Telegram.
  - Works when creating a new reservation manually in the backend and when confirming a reservation from the list.
  - The message is pre-filled from a customizable template with all booking details.
  - Configurable template with placeholders ({reservation_info}, {restaurant_name}).
  - Each service (WhatsApp / Telegram) can be enabled or disabled independently in the settings.

* **Design Customization:**
  - Live preview of frontend form in the backend design settings.
  - Real-time design updates - see changes immediately while adjusting colors and styles.
  - Customizable colors for form background, text, and buttons.
  - Adjustable corner radius for a modern or classic design.
  
* **Internationalization:**
  - Support for 10 languages/formats:
    - German (de_DE)
    - English (en_US) - 24-hour format
    - English (en_US_AMPM) - 12-hour format (AM/PM)
    - English (en_GB) - UK format
    - Dutch (nl_NL)
    - Italian (it_IT)
    - Spanish (es_ES)
    - French (fr_FR)
    - Polish (pl_PL)
    - Russian (ru_RU)
  - Complete translation of frontend, backend, and emails.
  - Fully localized datepickers and calendar views for all languages.

* **Progressive Web App (PWA) / Mobile App:**
  - **Install as App:**
    - Convert your reservation system into a standalone mobile app.
    - Works on iOS (iPhone/iPad) and Android devices.
    - No app store required - install directly from your website.
    - QR code generation for easy mobile installation.
  - **Mobile-Optimized Interface:**
    - Bottom navigation bar for easy one-handed operation.
    - Touch-friendly card-based layouts.
    - Responsive design optimized for smartphones and tablets.
    - PWA-specific header with streamlined navigation.
  - **Push Notifications:**
    - Real-time push notifications for new reservations (optional).
    - VAPID key-based secure authentication.
    - Works even when app is closed.
    - Automatic key generation or use external generator.
    - Test notification feature to verify setup.
  - **Customization:**
    - Custom app name and short name.
    - Configurable app icon (512x512px recommended).
    - Theme color customization for app interface.
  - **Standalone Experience:**
    - Runs in fullscreen mode without browser UI.
    - App icon on home screen like native apps.
    - Fast loading with service worker caching.
    - Works offline with cached data.


== Installation ==

**Installation via WordPress Dashboard (recommended):**

1. Navigate to `Plugins` > `Install` in your WordPress admin area.
2. Search for "Mobile-Refuel Table Reservations Pro".
3. Click `Install Now` and then `Activate`.
4. After activation, a free trial period will start. Configure the plugin under the new menu item `Reservations`.
5. Add the shortcode `[reservierungsformular]` to the page where you want the form to be displayed.

**Manual Installation:**

1. Download the plugin file (`.zip`).
2. Extract the `.zip` file on your computer.
3. Upload the plugin folder to the `/wp-content/plugins/` directory on your server.
4. Go to `Plugins` in your WordPress admin area and activate "Mobile-Refuel Table Reservations Pro".
5. Add the shortcode `[reservierungsformular]` to the desired page.

== Usage ==

=== Getting Started ===

1. **Configure General Settings:**
   - Go to `Reservations` > `Settings` > "General" tab
   - Enter restaurant name
   - Configure email address for notifications
   - Set maximum number of people and stay duration

2. **Set Up Opening Hours:**
   - "Opening Hours" tab > "Regular Weekly Opening Hours"
   - Activate desired weekdays
   - Set opening hours (start and end) for each day
   - Configure time interval (default: 30 minutes)

3. **Add Holidays:**
   - "Opening Hours" tab > "Holidays & Special Opening Hours"
   - Select a date in the calendar
   - Click "Configure Selected Date"
   - Choose "Close entire day" or "Special opening hours"
   - Save settings

4. **Set Up Events (Optional):**
   - "Events" tab in Settings
   - Enable "Activate Events"
   - Add event types (e.g., Birthday - 120 minutes, Wedding - 240 minutes)
   - Optionally display duration next to event names in frontend
   - Customize form headings for event-specific booking steps
   - Events are automatically considered in capacity planning

5. **Customize Email Templates:**
   - "Emails" tab
   - Select desired language
   - Customize subject and message for each email type
   - Use placeholders for dynamic content: {name}, {email}, {phone}, {date}, {time}, {persons}, {persons_text}, {message}, {restaurant_name}, {cancellation_link}
   - The {cancellation_link} placeholder automatically generates a secure cancellation link for guests (only shown if cancellation is enabled)

5. **Customize Design:**
   - "Design" tab
   - Select background color for the form
   - Adjust text and button colors
   - Set corner radius (0-50 pixels)

6. **Select Language:**
   - "Language" tab
   - Select desired language for frontend and backend
   - All texts are automatically translated

7. **Embed Form:**
   - Create a new page or edit an existing one
   - Add the shortcode `[reservierungsformular]`
   - Publish the page

8. **Set Up Events (Optional):**
   - "Events" tab in Settings
   - Enable "Activate Events"
   - Add event types (e.g., Birthday - 120 minutes, Wedding - 240 minutes)
   - Optionally display duration next to event names in frontend
   - Customize form headings for event-specific booking steps
   - Events are automatically considered in capacity planning

9. **Set Up Mobile App (Optional):**
   - "App" tab in Settings
   - Enable PWA/Mobile App functionality
   - Configure app name (e.g., "Restaurant Reservations")
   - Set short name for home screen icon (max 12 characters)
   - Upload app icon (512x512px PNG recommended)
   - Choose theme color for app interface
   - **Push Notifications (Optional):**
     - Enable push notifications
     - Click "Generate Keys" to create VAPID keys automatically
     - Test notifications with "Send Test" button
   - **Installing the App:**
     - Scan QR code with smartphone camera
     - Or click "Open in Browser" and follow installation instructions
     - iOS: Safari > Share > Add to Home Screen
     - Android: Chrome > Menu (⋮) > Add to Home screen
   - The app will appear on your home screen like a native app
   - Access your reservation system with bottom navigation and mobile-optimized interface

=== Managing Reservations ===

**Reservation List:**
- Go to `Reservations` > `Reservations`
- **View Mode Toggle:**
  - Click the toggle button in the top-right to switch between Card View and Table View.
  - **Card View:** Modern, mobile-friendly card layout with visual status indicators. Default on first visit.
  - **Table View:** Classic table format showing all information in columns.
  - Your view preference is automatically saved and restored on next visit.
- Use filters to display specific reservations (All, Pending, Today, Future, Past)
- Sort by various criteria (ID, Name, Date, Time, Persons, Status)
- Pagination with customizable entries per page (10, 20, 40, 50, 100)
- Click on any reservation row or card to open detailed modal view
- Modal shows all reservation information in organized tile layout:
  - Basic information (ID, Name, Date, Time, Persons)
  - Message from guest
  - Contact information (Email, Phone)
  - Current status with color-coded badge
  - Action buttons (Edit, Send Message, Confirm, Reject, Delete)
- Status color legend for quick visual reference
- Responsive design: automatically adapts to screen size
- Click "Confirm" or "Reject" to change status directly from modal
- Click "Edit" to change reservation details
- Click "Send Message" to communicate directly with guest via email
- Click "Delete" to remove a reservation (with confirmation dialog)

**Add Manual Reservation:**
- Go to `Reservations` > `New Reservation`
- Fill in all fields
- Select date and time (special opening hours are automatically considered)
- Optional: Send email confirmation to guest
- Click "Create Reservation"

**Calendar View:**
- Go to `Reservations` > `Calendar`
- View all reservations in a calendar format using FullCalendar
- Switch between month, week, and day views
- Navigate between months using previous/next buttons
- Click on a reservation to view details in a modal with tile-based layout
- View reservation information including name, date, time, persons, contact details, and status
- Change status (Confirm, Reject) or delete reservations directly from the calendar modal
- Color-coded events: green for confirmed, orange for pending, red for rejected/cancelled
- Status indicators in event titles for pending reservations
- Fully responsive design for all screen sizes
- Supports all 6 languages with translated calendar interface

**Calendar Subscription (iCal Feed):**
- Go to `Reservations` > `Calendar`
- Scroll to "Subscribe to Calendar" section
- Choose whether to include past appointments (last 2 weeks)
- Select your calendar application (Google, Outlook, Apple, Thunderbird)
- Click "Generate Calendar URL"
- Copy the URL and add it to your calendar application
- Note: Outlook updates approximately once daily, Google Calendar every 8-24 hours

**CSV & PDF Export:**
- Go to `Reservations` > `Reservations`
- Optionally select a filter
- Click "Exportieren" to open the export modal
- **CSV Export:** Select "CSV" and click the export button. The file downloads immediately and is compatible with Excel and Google Sheets.
- **PDF Export:** Select "PDF", then choose a layout:
  - **Table:** A4 landscape, all reservations in a compact table with color-coded status rows. Ideal for overview prints.
  - **Cards:** A4 portrait, three reservation cards per row, each with status color stripe. Ideal for handouts.
- The PDF opens in a new browser tab ready to print or save.
- The export always respects the currently active filter.

== Frequently Asked Questions ==

= How do I add the reservation form to my website? =

Add the shortcode `[reservierungsformular]` to the text editor of any page or post.

= Can I customize the form colors? =

Yes. Go to `Reservations` > `Settings` > "Design" tab. There you can adjust the background, text, and button colors as well as the corner radius.

= How do I set a day off, e.g. Monday? =

Go to `Reservations` > `Settings` > "Opening Hours" tab > "Regular Weekly Opening Hours". Simply uncheck "Allow reservations on this day" for "Monday" and save the changes.

= How do I close my restaurant for a specific holiday? =

Go to `Reservations` > `Settings` > "Opening Hours" tab > "Holidays & Special Opening Hours". Select the desired date in the calendar and click "Configure Selected Date". Make sure the "Close entire day" option is selected and save the settings.

= How do I set special opening hours for a day, e.g. December 24 from 2-6 PM? =

Go to `Reservations` > `Settings` > "Opening Hours" tab > "Holidays & Special Opening Hours". Select the date (e.g. December 24) in the calendar, click "Configure Selected Date", choose "Special opening hours" and enter the times (14:00 - 18:00). Save the settings.

= Which languages are supported? =

The plugin supports 10 languages/formats: German, English (US - 24h), English (US - AM/PM), English (UK), Dutch, Italian, Spanish, French, Polish, and Russian. The default language on first installation is English.

= How do I change the plugin language? =

Go to `Reservations` > `Settings` > "Language" tab and select the desired language. After saving, the entire interface will be displayed in the new language.

= Are emails sent in the selected language? =

Yes. Emails are automatically sent in the language selected in the plugin settings. You can create separate email templates for each language.

= Can I design email templates differently for different languages? =

Yes. Switch to the desired language in settings and customize the email templates. Each language has its own templates.

= How can I switch between card and table view in the reservation list? =

Click the toggle button in the top-right corner of the reservation list page. The button shows an icon and text indicating which view you'll switch to. Your preference is automatically saved in your browser and will be remembered on your next visit. Card view is ideal for touch devices, while table view provides a comprehensive overview.

= Can I install the reservation system as a mobile app? =

Yes! Go to `Reservations` > `Settings` > "App" tab and enable the PWA functionality. You can then:
- Scan the QR code with your smartphone
- Or click "Open in Browser" to access the app URL
- Follow the installation instructions for your device (iOS/Android)
- The app will appear on your home screen like a native app
The mobile app includes a bottom navigation bar, touch-optimized interface, and optional push notifications.

= How do I enable push notifications for the mobile app? =

1. Go to `Reservations` > `Settings` > "App" tab
2. Enable PWA functionality if not already enabled
3. Scroll to "Push Notifications" section
4. Check "Enable push notifications"
5. Click "Generate Keys" to create VAPID keys (or use external generator)
6. Click "Send Test" to verify the setup
7. Users must install the app and allow notifications when prompted
Note: Push notifications require HTTPS and only work when the app is installed on a device.

= How does availability checking work? =

The system considers:
- Regular opening hours of the weekday
- Special opening hours for the selected date (if available)
- Existing reservations
- Maximum number of people
- Stay duration per reservation
- Minimum advance time

= Can guests cancel their reservations? =

Yes. Guests can cancel reservations directly from the confirmation email using a secure cancellation link. The cancellation link is automatically included in confirmation emails when you use the {cancellation_link} placeholder. You can configure:
- Enable/disable guest cancellations in "Settings" > "Emails" tab
- Minimum hours before the appointment that cancellation is allowed (default: 24 hours)
- Phone number to display if cancellation is too late
- Guests will receive a confirmation email when they cancel

= How do I enable guest cancellation? =

1. Go to `Reservations` > `Settings` > "Emails" tab
2. Check "Enable cancellation" checkbox
3. Set the minimum hours before appointment (e.g., 24 hours)
4. Optionally enter a phone number for late cancellations
5. Make sure to include {cancellation_link} in your email templates where you want the cancellation link to appear

= How do I set up events for special occasions? =

1. Go to `Reservations` > `Settings` > "Events" tab
2. Check "Activate Events" to enable the event system
3. Click "Add Event" to create new event types
4. Enter event name (e.g., "Birthday", "Wedding", "Corporate Event")
5. Set duration in minutes (e.g., 120 for birthday, 240 for wedding)
6. Optionally enable "Show duration in frontend" to display event duration to guests
7. Customize form headings for event-specific booking steps
8. Events will automatically appear as booking options in the frontend form
9. Event durations are automatically considered in capacity planning

= How does event capacity planning work? =

When events are enabled, guests can choose between regular table reservations and event bookings. Event reservations use the configured event duration instead of the standard guest stay duration. For example, if a birthday event is set to 180 minutes, the system will block that table for 3 hours instead of the regular stay duration. This ensures proper capacity planning for longer occasions.

= Is this plugin free? =

The plugin offers a fully functional free trial period. To continue using it after this period, a license purchase is required. You can manage and purchase your license under `Reservations` > `License`.

== Screenshots ==

1. The user-friendly, multi-step reservation form in the frontend.
2. The reservation list with card view - modern, touch-friendly layout with visual status indicators.
3. The reservation list with table view - classic comprehensive table format.
4. View toggle button to switch between card and table view.
5. The clear reservation list in the admin area with filter options and pagination.
6. The calendar view with FullCalendar integration showing all reservations.
7. The calendar subscription section with iCal feed generation.
8. The modal-based reservation detail view with tile layout.
9. The status color legend in the reservation overview.
10. The settings page for regular weekly opening hours.
11. The management of holidays and special opening hours.
12. The design settings with color selection and corner radius for the form.
13. The email template management with language selection.
14. The language selection with 10 supported languages.
15. The PWA/Mobile App settings with installation QR code and push notifications.
16. The mobile app interface with bottom navigation and optimized layout.
17. The license management page with trial period status.
18. The event management settings with customizable event types and durations.
19. The frontend event booking selection with regular reservation and event options.

== Changelog ==
= 3.0.2 =
* FIXED (27.10.2026): More robust license check. If the license server cannot be reached, is busy or returns an error, the license stays active. Only a real server answer (invalid, expired, revoked or limit reached) changes the status; after 72 hours without a successful check the status changes to error. The license page checks at most every 12 hours, saving the key checks right away. After an error the plugin waits one hour (backoff) before the next request, also for update and trial checks. On a signature error the site registers again automatically, once. The license page shows a neutral notice instead of "License problem (Status: error)".
* IMPROVED (28.10.2026): License and update checks now use the new address mrstudio.codes.
* IMPROVED (28.10.2026): New contact address for license and support: plugins@mrstudio.codes.
* IMPROVED (28.10.2026): Renew now opens the secure checkout directly.
= 3.0.1 =
* IMPROVED: On the license page, Extend support adds one year of support and updates for this license. After payment you return to the license page, where a notice shows the new end date in the plugin language. The invoice is sent by email.
= 3.0.0 =
* IMPROVED: On the license page the key is stored on your site and only the last characters are shown. Leave the field empty to keep the saved key. Update checks run in the background.
* FIXED: In the dark design, the “No active license” label is light and easy to read. The plugin menu item is green again.
* NEW: Reservations can be exported and erased with the WordPress privacy tools. Plugin data is removed on uninstall only when the matching checkbox is enabled.
* IMPROVED: Internal restructuring. Settings, the shortcode and stored reservations stay as they are.
= 2.10.13 =
* FIXED: Booking form datepicker: the previous/next month buttons show the plugin's rounded button again (button color with white arrow, same look as in the backend) instead of tiny, cut-off arrows on the calendar header.
= 2.10.12 =
* FIXED: App (PWA): the blue "Update now" banner no longer appears on every start. The app's service worker already activates new versions automatically, so the banner is no longer needed.
* FIXED: App (PWA): the service worker keeps the URL it is already registered with (standard or fallback URL) instead of switching between them, which the browser treated as a new update each time.
* IMPROVED: App (PWA): the service worker file is never stored by page cache plugins and is delivered without any foreign output.
= 2.10.11 =
* FIXED: The guest cancellation page no longer shows any reservation details unless the cancellation link is valid. Invalid links and unknown reservations now show the same general "invalid link" message.
* FIXED: The plugin's sender name and address are now only applied to the plugin's own e-mails. Other e-mails of the website (e.g. password reset, WooCommerce) keep their usual sender again. If the notification e-mail field is empty or invalid, the WordPress default sender is used, so e-mails are always sent.
* FIXED: The confirm, reject and view links in the admin notification e-mail now work for all users with the "mrtr_manage_reservations" capability, not only administrators. Users who are not logged in are taken to the login page first.
* FIXED: Booking out events and time slots on the dashboard now works for all users with the "mrtr_manage_reservations" capability.
* FIXED: Calendar subscription: the option "include past reservations" had no effect.
* IMPROVED: Without a valid license or active trial, locked pages (settings, calendar, events, new reservation) now redirect to the license page (administrators) or the dashboard (staff) with a notice instead of showing a WordPress error page.
* IMPROVED: Changing a status via the link in the reservation list now redirects correctly afterwards (no more "headers already sent" warning in the debug log).
= 2.10.10 =
* SECURITY: Guest data (name, e-mail, phone, message, custom fields) is now escaped everywhere it is shown in the reservation list and calendar detail windows.
* SECURITY: New capability "mrtr_manage_reservations" protects all reservation pages and actions (settings, exports, status changes, deleting, details, calendar feed token, setup wizard, messages). Administrators always have it; existing staff accounts receive it automatically on update. Access can be granted per user in the user profile, and the required capability can be changed with the filter "mrtr_required_capability".
* SECURITY: "Send message to guest" only sends to the guest of an existing reservation; subject and message are sanitized and length-limited.
* SECURITY: Database error details are no longer shown to visitors; they are written to the debug log when WP_DEBUG is enabled.
* SECURITY: Settings can only be saved with an active license or trial, matching the settings page itself.
* SECURITY: Reservation status changes only accept the known statuses.
* NEW: Invisible spam protection for the public reservation form (honeypot field and minimum fill-in time). No captcha, nothing changes for real guests. Filters: "mrtr_min_form_fill_seconds", "mrtr_is_spam_submission".
* IMPROVED: Server-side validation and length limits for name, e-mail, phone and message of public reservations.
* REMOVED: Unused development files from the plugin package.
= 2.10.9 =
* FIXED: Saving the events page could silently drop the newest event (and even existing ones) when the form exceeded PHP's max_input_vars (default 1000), while still showing "Events gespeichert". The form now submits all events as one JSON field (mrtr_events_json); the server decodes and validates it exactly like before. Without JavaScript the classic fields remain as fallback.
* NEW: Truncation guard: declared event count plus a trailing sentinel field. If the request was cut off, nothing is saved, existing events stay untouched and an admin error explains max_input_vars and how to raise it.
* IMPROVED: "Events gespeichert" only appears when the option was really updated ("no changes" and database errors get their own notices). Events without a name are reported instead of being dropped silently, and an empty required name in a hidden event tab now opens that tab.
* NEW: Notice (without JavaScript) when the events form nears the server's max_input_vars.
= 2.10.8 =
* FIXED: The ChangeLog and New Features window showed outdated or duplicated entries (for example the same feature card twice) and hid the latest version notes. All version blocks are now listed completely and in order, so newly shipped changelog and feature entries appear immediately after reloading the settings page.
= 2.10.7 =
* NEW: The event settings are restructured: all individual settings live behind a collapsible "Einstellungen für das Event" panel with a live counter badge, the option tiles keep fixed positions in a 2-column grid (hidden options leave an empty cell instead of shifting the layout), and per-date/per-slot fields sit directly under each date or opening time in the same tile design. Options only appear when they are relevant (availability type and number of dates/time windows), and activating an event-wide setting hides only its direct counterpart (persons, kitchen, seats).
* NEW: "Individuelle Küchenkapazität pro Öffnungszeit" for events with specific weekdays: a separate kitchen capacity per time slot, empty fields fall back to the event-wide or global value. Activating it excludes the event-wide kitchen capacity (and vice versa).
* NEW: "Individuelle maximale Sitzplatzanzahl" for special-dates events, event-wide or per date, overriding the global Maximum Seats for that event only. Counterparts exclude each other as well.
* NEW: Live validation in the event form for all combinations: maximum persons per reservation must not exceed the seat count or the effective kitchen capacity (event-wide, per opening time, per date), with inline warnings at the field, live updates on every change, and a submit gate that scrolls to the first conflict. Placeholder (gray) values count as the event/global value and are validated from the start.
* NEW: Dashboard availability card: events with "Reguläre Öffnungszeiten" now show the day's opening-time rows with the interval selection (including per-slot blocking) just like regular table reservations. Days without active opening hours show a gray "Geschlossen" badge instead of block buttons.
* FIXED: Per-date and per-slot "Maximale Personenanzahl" no longer lowers the effective capacity below the configured seats: the per-reservation limit only caps the party size, while the capacity check uses the seat count (e.g. 5 booked + 5 requested with 10 seats is bookable again at the same time).
* FIXED: The "Event hinzufügen" template no longer renders "undefined" text and now includes all option blocks before saving; the settings badge plural is translated correctly (the plural lookup previously fell back to German).
= 2.10.6 =
* FIXED: With events disabled in the settings, picking a date now jumps straight to the next step again (or shows "Weiter") — the step-1 completion check wrongly required a reservation type that doesn't exist without events.
* FIXED: Hardened the datepicker against themes and jQuery-UI themes that restyle it on customer sites: the prev/next buttons keep the plugin's arrow styling (no more oversized theme icons or button colors), and the "Closed"/"Booked" tooltip emoji is capped at 12px so it can no longer render as a giant icon.
= 2.10.5 =
* NEW: Mobile and tablet refinements for the Sidebar-Layout (v2): the step menu sits left-aligned in its own row under the title with the compact icon style kept (only the active step shows its label), the two reservation-type tiles stack vertically on smartphones, and the navigation buttons share one row (Zurück left, Weiter right).
* NEW: On the confirmation step (mobile/tablet) the buttons stack — "Reservierung absenden" on top, "Zurück" below, both full width — so the long submit text no longer gets cut off.
* FIXED: On smartphones the Details step now always shows the "Weiter" button — browser autofill does not fire input events, so the live validation previously kept the button hidden even with all fields filled.
* FIXED: On mobile, every step change now scrolls the form smoothly to its top, so the viewport no longer lands somewhere in the middle of the details or confirmation content after scrolling in the time selection. The card also gets a minimum height on smartphones to keep the layout from jumping between steps.
= 2.10.4 =
* NEW: The "Next" button in the Sidebar-Layout (v2) only appears once the current step's data is complete (type/event/date, party size + time, or all required guest details) and updates live while the guest fills the form. Fresh visitors see no clickable button with error messages anymore; when navigating back from a later step, the button is immediately visible because the data is already there.
* NEW: Custom-field checkboxes ("Ich stimme zu" and similar) now render as a toggle with the text next to it — in the classic layout and in the Sidebar-Layout (v2) alike — instead of a native checkbox stacked above the label.
* CHANGED: Single-select dropdowns from the form builder (Mehrfachauswahl off) now use the same polished dropdown UI with toggle switches as the multi-select, limited to one choice via radio behavior, instead of a plain native select.
* NEW: Scrollbars inside the form (v2) are now thin and rounded in the design colors (button color as thumb, tile color as track) without arrow buttons. The website's own scrollbar is intentionally untouched.
* FIXED: Number and URL/website custom fields in the Sidebar-Layout (v2) now use the same field styling as the other inputs (background, border, focus ring, filled tile state) instead of the unstyled browser default.
= 2.10.3 =
* NEW: "Event rules" in Holidays & Special Opening Hours. For any date you can now pick a specific event and either block it completely for that day ("An diesem Tag nicht buchbar" — the day itself stays bookable for regular reservations) or give it its own opening-hours window for that day. The frontend datepicker automatically disables the blocked dates per event, the time slots are limited to the rule window, and the booking validation enforces both server-side. Closed days are shown in red and stay unselectable in the rule datepicker.
* CHANGED: "Maximum number of persons per opening time" in the event settings is now only visible when it matters: the event must use "Specific weekdays" and at least one enabled weekday must have more than one time window. The save routine discards the mode when the condition is no longer met, so the individual maximum for the whole event takes over again.
* FIXED: The event-level "Individual maximum number of persons" no longer overrides the global restaurant capacity (Maximum Seats) and the kitchen capacity interval — it now only limits the party size per booking as documented. Previously a value of 4 silently reduced the whole event capacity to 4 seats, so unrelated table reservations blocked event time slots.
* NEW: Mobile and tablet optimization for the Sidebar-Layout (v2): the guided step-1 card flow (type → event → date, one card at a time) now also runs on tablets up to 900px, the header shows title and step icons in one line with the active step in the desktop gradient style, type tiles stay in two columns with compact icons and centered content, date tiles are back to three per row on tablet, navigation buttons span the full width, and extra bottom padding keeps tile glows from clashing with the glass card. Glass-mode tiles are now translucent with their own blur instead of opaque black boxes, and tile glows are damped while glass is enabled.
* FIXED: Sidebar-Layout (v2) polish: spacing between custom-field rows in the classic summary, removed the classic hover stripe on top of event tiles, option-tile icon color in the settings live preview now follows the tile text color, legal notice font size is 12px on all devices, and multi-select toggles work in the backend preview.
* FIXED: The dashboard availability card now formats all dates in the active plugin language (previously date_i18n mixed the WordPress site language into the heading, e.g. "Oktober" in an English UI) and includes the spelled-out weekday, e.g. "Availability for Monday, 10/12/2026".

= 2.10.2 =
* NEW: Second selectable frontend form layout "Sidebar-Layout (v2)". Choose it in Design settings (Formular-Layout dropdown) or override per shortcode with [reservierungsformular layout="sidebar"] / [reservierungsformular layout="classic"] — handy for presenting several layouts on a demo page. The v2 layout shows the steps in a left sidebar with a "Ihre Auswahl" summary card that builds up row by row, reveals the time slots only after the party size is picked, and reuses all existing design settings (colors, radius, icons) and booking logic unchanged.
* NEW: Glass morphism option for the v2 layout. Once the sidebar layout is selected, a "Glas-Morphismus" checkbox appears in the design settings; when enabled, the form card becomes semi-transparent (opacity, blur and glow sliders) so the page background shimmers through. Browsers without backdrop-filter support automatically fall back to the opaque form.
* NEW: The v2 layout shows a legal notice above the submit button: the terms sentence is always shown, and a cancellation sentence with the configured minimum hours is added only when guest cancellations are enabled in the settings.
* NEW: v2 polish: back button in the same outline/glow style as the next button, name/e-mail/phone inputs and country-code button with tile-colored 2px border and rounded corners, section titles centered with separator lines on both sides, "Gästinformation" heading on the details step (translatable), the three date tiles always in one row on desktop, and a narrower form card (1020px) with the summary card and legal notice kept horizontally centered.
* FIXED: Sidebar-Layout v2 visual pass: sidebar steps are left-aligned (the classic centering no longer bleeds in), the "Reservierung" sidebar title and "Ihre Auswahl" heading use the button color, selection check marks on people/time/date/event tiles are forced against the classic styles, and summary rows render as plain list rows instead of tile-colored bars.

= 2.10.1 =
* FIXED: Quick-confirm now behaves identically everywhere: with WhatsApp (or Telegram) enabled but "Automatically prepare WhatsApp message" disabled, clicking Confirm on a card in the reservation overview and on a dashboard tile now opens the custom green confirmation dialog with the "Additional Confirmation as Direct Message" section (WhatsApp/Telegram manually selectable), exactly like the confirm button inside the reservation details modal. Previously the overview fell back to the native browser confirm and the dashboard to a plain dialog without the direct message option.
* FIXED: Dashboard period tiles now stack vertically below 1300px viewport width (tablet/laptop) so each period shows as a full-width, equally sized table; the three-column side-by-side layout starts at 1300px instead of auto-fitting, which previously squeezed columns at mid-size screens.
* FIXED: The production demo SQL generator now uses one guaranteed invalid phone number (+49 0000000000) for all demo reservations, so the direct-message send feature can never reach a real recipient by accident.

= 2.10.0 =
* NEW: Per-opening-time maximum persons for events. Events can now switch between the event-wide "Individuelle maximale Personenanzahl" and a new "Maximale Personenanzahl pro Öffnungszeit" mode (mutually exclusive). Each weekday time slot gets its own "Max. Pers. pro Reservierung" input which overrides the global capacity per slot. The frontend people grid, duration-mode slot loop and the final submit validation respect these per-slot limits; slots that cannot fit the requested party size are shown as disabled options ("max. X Pers.") instead of hiding the whole day.
* NEW: Events admin: the weekday availability grid now uses one row per weekday so all slot inputs (including the new per-slot max persons) fit comfortably.
* NEW: Slot-level availability kill-switch. The dashboard availability card can now block or release each opening-time slot individually (key eventIdx_YMD_HH:MM) in addition to whole events and whole days - server-side gated in the booking form, so blocked slots show "Ausgebucht" immediately.
* NEW: Dashboard redesign - three period tiles ("Heute", "Morgen und Rest der Woche", "Nächste Woche und weiter") with pending reservations (occasion and party size), cancellations below and totals per tile, plus a bottom bar with confirmed totals for today / this week / next week and beyond. Admin width increased to 1600px on large screens. Light mode, dark mode and PWA are fully styled.
* NEW: Open reservation tiles in the dashboard have a soft yellow background (light and dark mode) with inline Confirm/Reject buttons stacked below the details - running the exact same confirmation flow as the reservation overview, including the custom dialogs, the auto-WhatsApp flow and the payment-link dialog. After confirming, the tile fades out and the tile counter and total line update live without a page reload.
* NEW: Dashboard availability card now covers 14 days ahead. Arrow navigation (left disabled on today, right disabled at day 14) swaps only the card via AJAX - no full page reload - with a "Tag X/14" counter badge, date tooltips, an extended info tooltip and a graceful empty state for days without events. Future days can be pre-blocked per event or per time slot.
* NEW: "Add opening time" now continues logically: the new slot starts at the end time of the previous slot (end = start + 2h, capped at 23:59) instead of always resetting to the default times. Applies to the events weekday slots and to the regular weekly opening hours in the settings.
* NEW: Modern slim scrollbars (no arrow buttons) for the dashboard period lists, color-matched for light and dark mode.
* FIXED: If a day only offers informative disabled time options (per-slot max hints or blocked slots), the booking form shows them with the "Uhrzeit wählen" placeholder instead of wrongly claiming "Keine Zeiten verfügbar".
* FIXED: Mobile/PWA layout polish: the dashboard bottom bar stacks ("Bestätigt" on its own line, then today / this week / next week & beyond), the reservation card header keeps the name and confirm button on one row, the mobile "Tabellenansicht" toggle button is hidden on smartphones, and the period list scrollbars match the theme.
* TRANSLATION: Added all new strings (per-slot limits, dashboard periods, availability navigation, confirm dialogs) to the POT file and to all 10 PO files with matching translations.

= 2.9.7 =
* NEW: On smartphones/PWAs the email confirm flow ("Bestätigen" button in the admin notification email) now always opens the green confirmation dialog with WhatsApp preselected - even with "WhatsApp-Nachricht automatisch vorbereiten" active and the payment link toggle disabled. The tap on "Bestätigen" inside the dialog is a real user gesture, so the native whatsapp:// intent launches the installed WhatsApp/WhatsApp Business app immediately and seamlessly, without Android's "Weiter zu WhatsApp Business?" browser prompt. The server-side redirect now decides this based on the user agent and the standalone-mode cookie, and the list script applies the same rule as a safety net. Desktop and normal WordPress admin sessions keep the fully automatic direct WhatsApp flow.

= 2.9.6 =
* FIXED: Mobile/PWA WhatsApp confirm flow now triggers the installed WhatsApp app directly via the native whatsapp:// scheme (custom anchor click) instead of opening the wa.me page in an in-app browser tab. The intermediate "Sende eine WhatsApp-Nachricht an..." share screen, the "App öffnen" click and the redirect to web.whatsapp.com are skipped; the app chooser (WhatsApp / WhatsApp Business) opens immediately with the prefilled message. Desktop behavior is unchanged (wa.me link triggers the registered desktop app handler). Applies to the quick confirm tiles, the confirmation dialog, the email-confirm redirect flow, and both manual reservation forms.
* FIXED: Opening an admin notification email link on a smartphone now lands in the correct PWA environment: the pwa-install script stores a standalone-mode cookie, and when the installed PWA opens a plugin URL without the pwa=1 parameter (e.g. an email confirmation link captured by Android into the app), the server redirects to the same URL with pwa=1 - so the WordPress admin menu/frame stays hidden and the reservation opens inside the app UI with PWA header and mobile layout.

= 2.9.5 =
* NEW: The "Edit reservation" screen (`page=db-reservierungen&aktion=bearbeiten`) now matches the "New reservation" screen: when the status is set to "Bestätigt", a confirmation email toggle plus WhatsApp/Telegram direct message buttons, message box, and payment link toggle/URL field appear. The message is built live from the template (including {payment_message} handling) and opened on save, exactly like in "New reservation".
* NEW: The confirmation email is now actually sent when an existing reservation is set to "Bestätigt" in the edit screen with the email toggle active (only on the transition to "Bestätigt", using the same template as the automatic confirmation).
* FIXED: Dark mode no longer "resets" to light when opening admin links from notification emails. The dark mode cookie is now issued with SameSite=Lax (previously Strict, which blocked the cookie on top-level navigations from external pages) and is transparently migrated on any admin page load.
* FIXED: The "Bearbeiten" button in the reservation details modal (AJAX view) now contains a valid nonce and works from every context.
* FIXED: Confirming a reservation from a pending tile no longer steals the browser focus: the WhatsApp tab now opens in the background (window.open reference + blur/focus-back within the user gesture), and the reservation list is updated in place instead of reloading - so several pending reservations can be confirmed one after another (each opens its own background WhatsApp tab) while the overview stays in focus and keeps the scroll position. In the "Ausstehend" filter, confirmed cards fade out gracefully and the pending counter is decremented live.

= 2.9.4 =
* NEW: Payment link integration for direct messages (WhatsApp/Telegram). A new toggle "Zahlungslink zur Nachricht hinzufügen" in Settings > E-Mails adds a payment message template with the {payment_link} placeholder. The template card is only visible when the toggle is active.
* NEW: Payment link toggle and individual URL input in the confirmation dialog (reservation list) and in manual reservations. The payment message is inserted into the direct message live and the {payment_link} placeholder is replaced with the individually entered URL.
* NEW: {payment_message} placeholder for the direct message template to control the exact position of the payment message. If a payment link is entered in the confirmation dialog, the payment message is inserted at the placeholder position; without a payment link the placeholder is completely removed (never sent as a raw string). Without the placeholder, the payment message is appended at the end as before.
* NEW: "WhatsApp-Nachricht automatisch vorbereiten" option. When active, confirming a reservation automatically preselects WhatsApp and opens the confirmation dialog with the prepared message (reservation list) or preselects the WhatsApp button when the status is set to "Bestätigt" in manual reservations.
* FIXED: Payment message template card in the settings is now reliably hidden when the "Zahlungslink zur Nachricht hinzufügen" toggle is deactivated (CSS specificity fix with the mrtr-grid-hidden state class).
* FIXED: Payment link toggles in the confirmation dialog and manual reservations now use toggle switches instead of standard checkboxes.
* TRANSLATION: Added the new payment message and WhatsApp auto-prepare strings to the POT file and to all 10 PO files with matching translations.

= 2.9.3 =
* NEW: Multiple Choice for dropdown fields. A dropdown field can now be switched to multiple selection, rendering as an expandable checkbox list in the frontend form. Multiple options can be selected at once; the value is saved comma-separated and shown accordingly in the reservation "More info" details.
* IMPROVED: Multiple choice options are displayed in a two-column grid with spacing between options, centered checkboxes and labels. Checked options are highlighted using the tile color from the design settings (fully driven by the global design variables).
* IMPROVED: Dark mode styles for the "Add new field" type modal in the form builder (type tiles, inputs, close button and overlay now match the dark admin design).
* TRANSLATION: Added the four new multiple choice strings to the POT file and to all 10 PO files with matching translations.

= 2.9.2 =
* NEW: Dark mode styles for the form builder. Form cards, the builder header (back button and form name input), badges, and buttons now match the rest of the dark admin design.
* NEW: The currently selected form card is now highlighted with a green glowing border (matching the green edit button) in both light and dark mode.
* IMPROVED: Live preview in Settings > Design now uses the correct form (including custom fields) when clicking through the preview for a specific event, matching the frontend behavior.
* IMPROVED: Form preview in Settings > Form now always shows the fields of the selected form (e.g. Babyshower) instead of the default form - when clicking a form card, when editing, and live while editing fields. Fields are transferred via postMessage and update instantly without iframe reloads.
* NEW: Device preview buttons (desktop, tablet, smartphone) for both the design and form preview open a large modal in the respective device size; the buttons use the app-green color (#31C442) and the modal shows the currently selected form with the correct design.
* FIXED: Dropdown and input fields in the form preview now look exactly like in the desktop frontend (mobile media queries no longer apply to the narrow preview box).
* TRANSLATION: Added the three new device view strings to the POT file and to all 10 PO files with matching translations.

= 2.9.1 =
* IMPROVED: Live preview in Settings > Design now uses the correct form (including custom fields) when clicking through the preview for a specific event, matching the frontend behavior.
* IMPROVED: Form preview in Settings > Form now always shows the fields of the selected form (e.g. Babyshower) instead of the default form - when clicking a form card, when editing, and live while editing fields. Fields are transferred via postMessage and update instantly without iframe reloads.
* NEW: Device preview buttons (desktop, tablet, smartphone) for both the design and form preview open a large modal in the respective device size; the buttons use the app-green color (#31C442) and the modal shows the currently selected form with the correct design.
* FIXED: Dropdown and input fields in the form preview now look exactly like in the desktop frontend (mobile media queries no longer apply to the narrow preview box).
* TRANSLATION: Added the three new device view strings to the POT file and to all 10 PO files with matching translations.

= 2.9.0 =
* NEW: Multiple reservation forms can now be created in Settings > Form. Each form has its own name, field configuration, and required/optional toggle settings.
* NEW: Events can be assigned a specific reservation form. Normal table reservations use the default form; events use the form assigned to that specific event.
* NEW: Event administration now includes a "Formular" dropdown to select which form should be used for each event.
* NEW: Events can override the global maximum number of persons per reservation via a toggle in event management. When enabled, restaurant and kitchen capacity limits are raised to the same value for availability checks.
* IMPROVED: The "Anmeldeformular" help text in the event administration is now shown via a tooltip icon, aligning the field height with the other event fields.
* IMPROVED: Form builder live preview in Settings > Form now applies the design settings (colors, border radius) from Settings > Design.
* IMPROVED: Corrected translations for "Anmeldeformular(e)" in Russian, Polish, and Dutch (form tab and event dropdown).
* UPDATED: All new strings added for the multi-form and per-event capacity features are now available in all translation files (.pot, .po, .mo, .l10n.php) for all supported languages.

= 2.8.8 =
* IMPROVED: Time slots in the frontend booking form are now grouped and visually separated when multiple opening time windows or event slots exist for a day (e.g. morning and afternoon shifts). Each time window starts on a new line with a subtle divider between groups instead of displaying as one continuous block.
* IMPROVED: Added slot group metadata to the time slot generation backend endpoint (mrtr_get_available_times) to ensure clean grouping and line breaks in both regular opening hours and multi-slot events.

= 2.8.7 =
* NEW: Events with "Bestimmte Wochentage" availability now support multiple opening time slots per weekday (e.g. 08:00-12:00 and 14:00-18:00 on Mondays), matching the regular opening-hours UI with an "+ Weitere Öffnungszeit" button per day.
* IMPROVED: Event weekday selection in the admin now displays full weekday names (Montag, Dienstag, ...) instead of abbreviations for a cleaner, calmer layout.
* IMPROVED: Event weekday time slots are now stacked vertically below the day checkbox, mirroring the design of regular weekly opening hours.
* FIXED: Weekday-based event time bounds are now applied correctly on the server side when generating available time slots; multiple slots per day are honored, clamped by special opening hours, and override closed weekdays or vacation days.
* FIXED: Admin new/edit reservation forms and frontend datepicker now respect the new multi-slot weekday event format for availability checks and time-slot generation.

= 2.8.6 =
* FIXED: Updater now blocks plugin updates when the license is invalid or the support period has expired. Previously the update could still be offered if an old response was cached.

= 2.8.5 =
* NEW: License page now displays support and update status with a badge showing validity or expiration date.
* NEW: Added "Renew Support & Updates" button on the license page (visible whenever a license is active) with license-type-specific WooCommerce renewal links.
* NEW: Added "Support & Updates" card on the general settings page showing current support validity and a renewal button.
* NEW: License server API now returns license_type, support_end, support_active and support_expired fields.
* IMPROVED: Translated all new support/update related strings into all 10 supported languages (de_DE, en_US, en_GB, en_US_AMPM, fr_FR, es_ES, it_IT, nl_NL, pl_PL, ru_RU) and updated POT file.
* FIXED: Fatal error on license server caused by redeclared helper functions; functions are now wrapped with function_exists() checks.

= 2.8.4 =
* FIXED: Added `!important` declarations to all `.ui-datepicker-header` CSS properties to ensure the Flexbox layout, colors, and spacing are correctly applied regardless of conflicting theme or plugin styles.

= 2.8.3 =
* IMPROVED: Modified the mobile layout of the reservation form step 1 to use smaller steps with card overlays and smooth sliding animations.
* IMPROVED: Standardized the mobile form navigation layout by adding clear "Zurück" and "Weiter" buttons at the bottom of the first step.
* IMPROVED: Optimized the styling of the booking summary container (`.mrtr-summary-container`) on mobile devices by reducing the gap to 0px and adjusting vertical padding of items on very small displays.

= 2.8.2 =
* NEW: Added event capacity mode where only the event start time is generated as a single slot, and guests can book until the maximum capacity is reached.
* NEW: Added tooltips explaining the behavior for "Duration (Minutes)" and "Capacity (Persons)" in the Event configuration settings.
* IMPROVED: Adjusted the date tiles in the manual backend reservation form ("New Reservation" page) to match the plugin's Dark Mode styling.
* FIXED: Centered the event delete icon and strengthened the CSS selector for the trash icon color to ensure it renders in red instead of blue in WordPress 7.0+.
* NEW: Added translations for the new capacity/duration labels and tooltips, updating the POT and all PO/MO files.

= 2.8.1 =
* NEW: The phone field in the frontend reservation form now has a country code selector with flags. Guests pick their country from a searchable dropdown and only enter the national number. The dropdown is preselected based on the configured plugin language (for example de_DE shows +49, nl_NL shows +31, fr_FR shows +33). Country names are displayed in the plugin language.
* IMPROVED: The selected country code and the entered number are combined into a single value without spaces, and a leading 0 of the national number is automatically removed. This produces clean international numbers (for example +4917712345678) and fixes wrong values caused by browser autofill that adds a leading 0.

= 2.8.0 =
* IMPROVED: When a guest phone number starts with 0 (national format), the Direct Message function no longer always prepends the German country code (+49). It now reads the currently configured plugin language and automatically selects the matching country code. For example, nl_NL uses +31, fr_FR uses +33, en_GB uses +44. If no match is found, +49 remains the fallback. Applies to both the Reservation List DM modal and the New Reservation DM section.

= 2.7.9 =
* NEW: The "E-Mails" settings tab has been renamed to "Vorlagen" (Templates) and now contains two sections: "E-Mail-Vorlagen" for email templates and a new "Direktnachrichten-Vorlagen" section for WhatsApp/Telegram message templates.
* NEW: Direct Message Template editor in Settings > Vorlagen. Admins can freely edit the message text that is pre-filled when sending a WhatsApp or Telegram confirmation from the "New Reservation" page. Supports two placeholders: {reservation_info} (inserts all booking data automatically) and {restaurant_name}. Language-specific default templates provided for all 10 supported languages.
* NEW: "Bestätigungs-E-Mail senden" toggle on the New Reservation page converted from a checkbox to a proper toggle switch, matching the style of the dwell-time toggle.
* NEW: "Zusätzliche Bestätigung als Direktnachricht" section on the New Reservation page (visible only when status is "Bestätigt"). Allows selecting WhatsApp or Telegram as confirmation channel. The pre-filled message is built from the saved template and updates live as form fields are edited. Clicking "Create Reservation" saves the booking and opens the direct message link in a new tab simultaneously.
* NEW: All new UI strings translated into all 10 supported languages (de_DE, en_US, en_GB, en_US_AMPM, fr_FR, es_ES, it_IT, nl_NL, pl_PL, ru_RU) and added to the POT file.
* FIXED: Icons in action buttons (Bestätigen, Ablehnen, Bearbeiten, Löschen) and the card/table view toggle button are now correctly vertically centered in WordPress 7.0. A targeted CSS rule overrides the changed dashicon baseline behavior introduced in WP 7.0.
* FIXED: The Direct Message template placeholder {reservation_info} is now automatically migrated in existing saved templates that still contained the old placeholder name {reservierungsinfos}. The migration runs once on admin_init.

= 2.7.8 =
* NEW: Tooltip icon added to the "Feiertage & Spezielle Öffnungszeiten" section heading. Explains that special opening hours restrict both the start time and end time for regular reservations and events. Translated into all 10 supported languages.

= 2.7.7 =
* FIXED: Special opening hours now apply both their start time (beginn) and end time (ende) to event reservations. Previously only the end time was capped. Example: event Lunch runs 10:00-14:00, special hours are 11:00-13:00. Guests now correctly see Lunch only from 11:00-12:45 (last slot before 13:00), not 10:00-12:45. This applies to time slot generation (PHP backend) and date availability checking (JS frontend).

= 2.7.6 =
* FIXED: Event dates that have no available time slots due to special opening hours (e.g. event 16:00-20:00 but special hours end at 16:00) are now correctly disabled in the datepicker and on date tiles. A new "Nicht verfügbar" tooltip (neutral grey style) appears on hover for these dates.
* FIXED: Double tooltip on fully-booked datepicker dates. The jQuery UI native title-attribute tooltip no longer appears alongside the custom CSS tooltip for "Ausgebucht" and killed-event dates.

= 2.7.5 =
* NEW: Special closing days ("Ganzen Tag schließen") in Feiertage & Spezielle Öffnungszeiten can now be displayed as "Ausgebucht" instead of "Geschlossen". A new dropdown per entry lets the admin choose the display mode. Guests see the matching tooltip (lock icon + "Ausgebucht" or blocked icon + "Geschlossen") on the date tiles and in the datepicker calendar.
* FIXED: Event time slots now respect special opening hours. When a date has special hours (e.g. 11:00-18:00) and an event has its own weekday times extending beyond that cap (e.g. 12:00-20:00), the event end time is clamped to the special-hours end time. Guests can only book slots up to 18:00 in this example.
* FIXED: jQuery UI datepicker disabled cells blocked mouse events via pointer-events: none on the inner span/a, preventing tooltip hover on the td. Fixed by setting pointer-events: auto on td.ui-state-disabled and none on the inner element.
* NEW: Translation strings "Als Geschlossen anzeigen" and "Als Ausgebucht anzeigen" added to POT file and all 10 PO language files.

= 2.7.4 =
* NEW: Global Dark Mode for the entire plugin backend. A toggle in Settings → Design activates a deep dark color scheme across all admin pages (Dashboard, Reservations, Calendar, Events, Settings, License). The preference is saved as a browser cookie and restored on every page load without server interaction. Covers all UI elements including cards, inputs, modals, the reservation detail tiles, form builder, time pickers, and the sidebar menu highlight.

= 2.7.3 =
* IMPROVED: Eye-toggle buttons (show/hide in frontend) removed from the two tile-text cards ("Reguläre Reservierung" and "Besonderer Anlass") in the Design settings. These tile labels are not form-section headings and should not be individually hidden.
* IMPROVED: Card order in the Design settings now matches the actual frontend form flow: "Überschrift: Buchungstyp" appears before "Überschrift: Datumswahl".
* FIXED: Optional system fields (E-Mail, Telefon) in the reservation form were always rendered as required, regardless of the configuration saved in the form builder. The `required` HTML attribute and the asterisk in the label are now set conditionally based on the saved field config.
* FIXED: JavaScript step-3 validation and the pre-submit check now respect the optional E-Mail and Telefon setting. Format validation (regex) only triggers when the field actually has a value.
* FIXED: Server-side AJAX validation now respects the `required` flag for E-Mail and Telefon from the form field config instead of always requiring both fields.
* NEW: Translation string "Im Frontend anzeigen/ausblenden" added to POT file and all 10 PO language files.

= 2.7.2 =
* NEW: Custom form fields created in the form builder are now shown in the reservation details modal in a new "Weitere Informationen" tile. All field types (phone, email, date, number, select, checkbox, URL) are displayed there. Checkbox values are shown as checkmark or cross.
* IMPROVED: Text and textarea custom fields are merged into the existing "Nachricht" tile (together with the legacy nachricht field), keeping message-type input in one place.
* IMPROVED: The "Status" tile has been removed from the 2x2 modal grid. The status badge is now shown in the "Aktionen" tile header on the right side, keeping the grid clean and making space for the new "Weitere Informationen" tile.
* NEW: The reservation details modal in the calendar view now matches the reservations list modal: "Weitere Informationen" tile with custom form fields and status badge in the "Aktionen" header.
* NEW: A "Nachricht senden" button is now available in the calendar reservation details modal, allowing admins to send a custom email to the guest directly from the calendar view.
* FIXED: Custom fields of type text and textarea were incorrectly shown in both the "Nachricht" tile and the "Weitere Informationen" tile. They are now shown exclusively in "Nachricht".

= 2.7.1 =
* NEW: Bulk-Löschen in der Reservierungsliste. Bei den Filtern „Vergangene“ und „Storniert/Abgelehnt“ erscheint in der Tabellenansicht eine Checkbox pro Zeile sowie eine Auswahl-Checkbox im Tabellenkopf. Eine gelbe Aktionsleiste zeigt die Anzahl der markierten Einträge und ermöglicht das Massenlöschen per AJAX (inkl. Sicherheitsprompt).
* FIXED: "Zurück zur Liste" button in PWA mode was hidden because the CSS rule that hides `.page-title-action` elements was too broad. Back buttons now carry the class `mrtr-back-btn` and are explicitly shown in PWA mode with a proper touch-sized height.
* FIXED: Tapping the "Zurück zur Liste" button on mobile caused a visual jump. Root cause: the `:hover` rule applied `transform: translateY(-2px)` which fires on touchscreen tap. The transform is now scoped to `@media (hover: hover)` so it only applies to real pointer devices.
* FIXED: The Export button was still visible on mobile screens between 783 px and 1200 px wide. It is now hidden across the full mobile range (up to 1200 px) via the `.filter-export-col` rule in `reservierungen.css`.

= 2.7.0 =
* FIXED: Filter toggle button on mobile and in PWA did not work correctly when old CSS files were served from browser or Service Worker cache. The JavaScript now sets the filter visibility via inline styles on page load, which overrides any external CSS regardless of its cached state.
* IMPROVED: Service Worker no longer caches CSS and JS files at all (moved to network-first strategy). Additionally, all URLs containing WordPress version parameters (`?ver=`) and all admin pages are excluded from the cache entirely, ensuring updated assets are always fetched fresh from the server.

= 2.6.9 =
* FIXED: "Show Filters" toggle button in the PWA and on mobile devices had no effect. Root cause: `.reservierungen-filter-container` in `reservierungen.css` declared `display: flex` globally, which always overrode the `display: none` set by the responsive rule in `backend-style.css`. The flex layout is now scoped to a `@media (min-width: 1201px)` block so the toggle works correctly on all screen sizes.
* NEW: Mobile and PWA view of the reservations list now includes a toolbar row beneath the status legend with an "Add New" link and a card/table view switcher. The switcher is synchronised with the desktop toggle and persists the chosen view in localStorage.
* IMPROVED: When the table view is active on mobile or in the PWA, the table container is horizontally scrollable via touch, and the table has a minimum width of 620 px so all columns remain readable.
* IMPROVED: "Open app in browser" and "Copy link" buttons in the App settings tab are now also visible on desktop. Previously they were hidden on screens wider than 782 px.

= 2.6.8 =
* IMPROVED: The "+more" link in the calendar (month/week/day view) no longer opens FullCalendar's native popover, which was clipped by the scrollable container. It now opens a centered, styled modal with all events for that day listed as clickable color-coded cards.
* FIXED: Default calendar view is now always the week view, regardless of device. Previously, mobile devices started in month view.
* FIXED: The date header in the new "more events" modal was displayed in black instead of white. The header now renders in white with correct padding on all sides.
* IMPROVED: Export button in the reservations list moved from below the content into the filter row as a right-aligned second column, making the layout more compact.

= 2.6.7 =
* FIXED: Time values in PDF exports were always displayed in 24-hour format, even when the plugin language was set to English AM/PM (`en_US_AMPM`). The time format is now determined by the plugin language: `en_US_AMPM` uses 12-hour AM/PM format (e.g. "11:00 AM", "12:45 PM"), all other languages use 24-hour format. This applies to all three PDF output methods (table layout, card layout, HTML fallback).
* FIXED: Confirming or rejecting a reservation from the calendar in the mobile app (PWA) caused the app to leave the PWA and open the regular browser UI. Root cause: the action URLs and the post-action redirect URL were built without the `pwa=1` parameter. All calendar URLs passed to JavaScript (`mrtrKalender.urls`) are now wrapped with `mrtr_maybe_add_pwa_param()`, so the PWA context is preserved through status changes, deletion, and navigation back to the calendar.

= 2.6.6 =
* FIXED: PDF export (HTML fallback) now respects the plugin language setting for date formatting. The header line (e.g. "17. April 2026") is now rendered in the configured language instead of always using the WordPress site language. This is achieved via `switch_to_locale()` using the plugin's current locale at the start of each output method.
* FIXED: The meta line in PDF exports always showed "Einträge" in German regardless of language. Root cause: the msgid was passed as an HTML entity string (`Eintr&auml;ge`) which never matched the UTF-8 PO entry. Fixed to use the real UTF-8 string `Einträge`.
* FIXED: The print button in the HTML fallback PDF page was hardcoded in German ("Drucken / Als PDF speichern"). It is now translatable via `__()` and translated into all 10 supported languages.
* NEW: Translation string "Drucken / Als PDF speichern" added to POT file and all 10 PO language files.

= 2.6.5 =
* NEW: Export modal in the reservations list. The new "Exportieren" button opens a dialog where you can choose between CSV and PDF export.
* NEW: PDF export for reservations in two layouts: Table view (A4 landscape, ideal for overview) and Card view (3 cards per row on A4 portrait, ideal for printing). The PDF opens in a new browser tab.
* IMPROVED: CSV export now includes an "Anlass" (occasion) column showing the event name, or "-" when the reservation has no event.
* NEW: 7 new translation strings for the export modal added to all 10 language versions (de_DE, en_US, en_GB, en_US_AMPM, es_ES, fr_FR, it_IT, nl_NL, pl_PL, ru_RU).

= 2.6.4 =
* FIXED: Confirmation email ("Reservierung bestätigt"), rejection email, guest cancellation email, and admin cancellation notification all showed the wrong event name. The `event_type` column stores the event name as a string since v2.1.8, but all four email functions called `intval()` on it, which always returns 0, making them look up index 0 (first event) regardless of the actual booking. All functions now use `mrtr_get_event_name_from_index()` which correctly handles both stored name strings and legacy numeric indices from old reservations.

= 2.6.3 =
* FIXED: Event special-dates datepicker (Event-Verwaltung) now blocks past dates (`minDate: 0`) – it was previously possible to select dates in the past, which could never be booked by guests.
* IMPROVED: Event special-dates datepicker now visually highlights vacation days (orange), special closed days (red), and regularly closed weekdays (gray) using the same CSS classes as all other backend datepickers. All highlighted days remain selectable because events are allowed to override closed-day restrictions.
* FIXED: Events with explicit time bounds (`Spezielle Termine`) now correctly provide available time slots even when the selected date falls within a configured vacation period. Previously the vacation check ran before the event-time override, always returning "Betrieb geschlossen (Urlaub)".
* FIXED: Events with explicit time bounds now correctly provide available time slots even when the selected date is configured as a special closed day ("Ganzen Tag schließen" under Feiertage & Spezielle Öffnungszeiten). Previously the special-day closed check ran before the event-time override, always returning "An diesem Tag geschlossen (Spezial)".
* IMPROVED: Vacation range entries in the Urlaub & Saison Verwaltung list are now automatically sorted chronologically after a new entry is added – the list no longer shows entries in insertion order.
* NEW: `spezielleTageKonfiguration` (array of YYYY-MM-DD date keys) added to `mrtrEinstellungen` JS object – used by the event datepicker to highlight special closed days.

= 2.6.2 =
* FIXED: In the booking confirmation and admin notification emails, the wrong event was always shown (always the first event in the list). Root cause: the event name was already resolved and stored as a string, but the email-building code called `intval()` on it again, which always returns 0, so it looked up index 0. Both email blocks now use the already-resolved event name directly.
* FIXED: In the calendar details modal (`get_reservierung_details_ajax`), the event name was resolved with the same broken `intval()` logic and always showed the first event. Fixed to use `mrtr_get_event_name_from_index()` directly.
* FIXED: In the calendar event list (`get_calendar_events_ajax`), the event type was not included in `extendedProps` at all, so it was never visible in the calendar tiles. The resolved event name is now passed as `event_type` in `extendedProps`.
* IMPROVED: Calendar event tiles (week and day view) now show the time and name on the first line (name truncated with ellipsis if too long), and persons plus event name on the second line (e.g. "5 Personen - Oster Special Dinner"), also truncated with ellipsis if too long.
* IMPROVED: Pending (yellow) calendar events now use dark text color (#D18E00) instead of white for better readability on the yellow background.
* FIXED: When "Nur Event-Reservierungen erlauben" was enabled, the "Was mochten Sie buchen?" step was skipped entirely and the event tiles were shown directly. The "Besonderer Anlass" tile is now always shown in step 1. Only the "Regulare Reservierung" tile is hidden in events-only mode. Event tiles appear after clicking "Besonderer Anlass" as usual.

= 2.6.1 =
* FIXED: Multiple instances of [reservierungsformular] on the same page no longer interfere with each other. JavaScript is now initialised per-instance inside a .mrtr-reservierung-container.each() closure, giving every form its own isolated state (currentStep, selectedDate, selectedPeople, selectedTime, selectedEventIndex) and scoped jQuery selectors.
* FIXED: Update loop resolved. After installing an update, WordPress immediately showed the same version as "available" again. Root cause: check_for_updates ran again within the same PHP request (after the upgrade) using the stale in-memory $this->version (old version) instead of the newly installed version. The check now reads the actual installed version from $transient->checked (populated fresh by WordPress from plugin file headers) and explicitly removes the plugin from $transient->response to clean up orphaned entries. clear_cache_after_update now also removes the plugin from the cached update_plugins transient before deleting it.

= 2.6.0 =
* FIXED: After installing a plugin update, WordPress continued to show "Update available" until the user manually clicked "Check for Updates". The updater now hooks into `upgrader_process_complete` and immediately deletes both the custom update-info cache transient and the WordPress `update_plugins` site transient, so WordPress knows instantly that the installed version is the latest.

= 2.5.9 =
* IMPROVED: Admin notification email is now fully Outlook-compatible — rebuilt with proper `<!DOCTYPE html>` structure, outer `<table>` wrapper, `bgcolor` HTML attributes on all cells (Outlook ignores CSS `background`), and table-based two-column data rows (label | value) replacing `<p>` tags. Action buttons now use VML roundrects (`<!--[if mso]>`) for correct rendering in all Outlook versions.
* IMPROVED: Guest confirmation emails now use the same Outlook-compatible structure (DOCTYPE + table wrapper + bgcolor attributes). Content section uses proper `<table>` rows instead of bare `<div>` containers, ensuring consistent rendering in Outlook 2016/2019/365.
* IMPROVED: Both email templates now render an "intro strip" (green left-border highlight row) between header and data, matching the PocketEvents Pro email style.

= 2.5.8 =
* FIXED: AJAX response blocking fixed — the booking form confirmation is now sent to the browser immediately after saving the reservation to the database. Admin and guest emails are sent afterwards via PHP background execution (Connection-Close trick + fastcgi_finish_request). This prevents slow SMTP servers (e.g. shared hosting mail queues) from delaying the form response.
* FIXED: Date picker (jQuery UI) z-index increased from 1000 to 9999 to prevent it from appearing behind theme elements such as sticky headers, overlays, or page builders that use high z-index stacking contexts.

= 2.5.7 =
* FIXED: Timezone-safe server time — `serverTime` in the frontend is now based on `time()` (real UTC) instead of `current_time('timestamp')` (WordPress local time as fake UTC). Prevents date tiles from being incorrectly disabled too early on sites with a non-UTC timezone.
* FIXED: Closing-time comparisons for date tiles and event date chips in the booking form now use a pure UTC calculation (`Date.UTC() / timezone offset`) instead of `Date.setHours()`, which was browser-timezone-dependent. Reservations are now correctly enabled/disabled based on the WordPress site timezone, regardless of the visitor's browser timezone.
* NEW: `timezoneOffset` (WordPress site timezone offset in seconds, DST-aware) is now passed to the frontend via `wp_localize_script`, enabling fully correct date/time arithmetic in JavaScript.
* FIXED: "Heute" (Today) date tile was disabled for events configured for the current weekday when accessed after the restaurant's opening time — caused by the combination of the `current_time()` fake-UTC issue and `setHours()` browser-timezone issue above.
* FIXED: `mrtr_get_event_name_from_index()` was only defined in `admin/reservierungen-liste.php`. When the Dashboard page loaded without the reservation list, the function was unavailable and event names (e.g. "Lunch") were not shown in the "Nächste Reservierungen" section. The function is now defined in `reservation-plugin-main.php` (always loaded) with a fallback guard in `reservierungen-liste.php`.
* FIXED: Dashboard "Nächste Reservierungen" — upcoming reservation comparison now uses `new DateTime($date, wp_timezone())->getTimestamp()` vs `time()` instead of `strtotime()` vs `current_time('timestamp')`, preventing reservations from disappearing or appearing incorrectly due to timezone offset.
* NEW: Events submenu item in the WordPress admin sidebar now has an icon (🎉) matching the style of the other menu items.
* IMPROVED: Special-dates compact tile grid on mobile (≤768px and ≤480px) now shows exactly 4 tiles per row (`repeat(4, 1fr)`). Desktop layout remains flexible (`auto-fill, minmax(80px, 1fr)`).
* NEW: Dashboard kill-switch card "Heutige Verfügbarkeit" — Events and regular table reservations can now be blocked instantly from the dashboard. Guests see "Ausgebucht" instead of "Geschlossen". The regular reservation entry is hidden when "Events only" mode is active.
* NEW: Kill-switch support for regular table reservations in the booking form — killed regular-reservation dates are shown as fully booked in the datepicker and date tiles, matching the existing event kill-switch behaviour.
* NEW: Events-only mode — when "Nur Event-Reservierungen erlauben" is enabled in settings, the "Was möchten Sie buchen?" step is skipped entirely in the frontend form. Event tiles are shown directly; the booking-type selection card is hidden.
* NEW: Auto-advance in the booking form — after selecting type, event (if applicable), and date in step 1, the form advances to step 2 automatically (200 ms delay). After selecting persons and time in step 2, the form advances to step 3 automatically. Going back and changing a selection re-triggers the auto-advance.
* FIXED: Event time fields (weekday times and special dates) were not saved correctly when the plugin language was set to en_US_AMPM. The AM/PM text values were rejected by the server's 24h format validation and silently reset to 12:00. A convert-back step on form submit now ensures the correct 24h value is sent to the server.
* FIXED: When adding a new opening-time slot via the "+ Add Opening Time" button in en_US_AMPM mode, the new fields appeared as a native 24h time picker instead of the AM/PM text format used by all existing fields. The conversion function is now called after inserting the new row.
* NEW: Translation added for the Event settings info text ("Die Event-Verwaltung (Events erstellen, bearbeiten und sortieren) finden Sie jetzt unter:") to the POT file and all 10 language files (de_DE, en_US, en_US_AMPM, en_GB, fr_FR, es_ES, it_IT, nl_NL, pl_PL, ru_RU).
* NEW: Translation added for the "Zur Event-Verwaltung" button in Event settings to the POT file and all 10 language files.

= 2.5.6 =
* IMPROVED: CSS styling for form navigation buttons – `.mrtr-form-button.next` and `.mrtr-form-button.back` now have `border: none !important;` to ensure consistent button appearance across all browsers and themes.

= 2.5.5 =
* NEW: HTML email builder for admin notifications (`mrtr_build_admin_html_email()`) — admin new-reservation emails now use the same styled card layout as guest emails, with a colored header that picks up the plugin's design colors (container background + text color) and the configured email logo.
* NEW: Custom form-editor fields now appear in the confirmation summary (step 4) of the booking form dynamically — the hardcoded "Bemerkung" row has been replaced by a JS-rendered container that shows only the custom fields actually present in the current form config, in the order defined in the form editor.
* NEW: Custom form-editor fields are now shown in the admin notification email directly after the Personen row, in the order defined in the form editor. The hardcoded "Nachricht" row has been removed from both admin and guest emails since it is no longer a built-in form field.
* IMPROVED: Guest confirmation email — custom fields are now inserted directly after the "Personen:" line (matching the form editor order) instead of being appended at the end of the email after the sign-off.
* IMPROVED: Guest emails no longer contain an empty "Ihre Nachricht:" line when no message field is present in the form editor. The line is stripped for all supported languages.
* FIXED: Double-colon bug in custom field labels — field labels ending with ":" (e.g. "Allergene wählen:") no longer produce "Allergene wählen:: Nüsse" in emails; trailing colons are now stripped before formatting.
* FIXED: Email preview panel (Email settings tab) now hides automatically when switching to any other settings tab (Design, General, Opening Hours, etc.) instead of remaining visible and overlapping other UI elements.

= 2.5.4 =
* IMPROVED: Design-Tab – Live Preview is now positioned fixed directly to the right of the admin wrap content area, so it stays aligned with the content rather than drifting to the right edge on wide/4K displays.
* IMPROVED: Live Preview width increased to 600px on Full HD displays (≥1600px) and automatically expands to 800px on displays wider than 1920px for a larger preview area.
* IMPROVED: Removed the hard `max-width: 900px` cap on the Design tab content — the Design settings grid now uses the full admin wrap width (1000px) just like all other tabs, eliminating the narrower appearance and overlap with the tab navigation.

= 2.5.3 =
* FIXED: WordPress `wp_enqueue_style` / `wp_enqueue_script` handle names (`formular-style`, `formular-script`, `reservierungen-style`) collided with PocketBooking Pro, causing the second plugin's CSS and JS to silently not load. All handles are now prefixed with `mrtr-` (`mrtr-formular-style`, `mrtr-formular-script`, `mrtr-reservierungen-style`).
* FIXED: JavaScript and HTML-ID conflicts when both Tischreservierungen Pro and PocketBooking Pro are active on the same page — both plugins shared identical HTML element IDs (`#datum`, `#name`, `#email`, `#time-selection`, `#reservierung-formular`, etc.) and generic CSS class names (`.form-button`, `.time-option`, `.people-option`, `.form-gruppe`, `.summary-item`, etc.), causing jQuery selectors and event handlers to cross-trigger between forms. All frontend HTML IDs and generic class names in the table reservation plugin are now prefixed with `mrtr-` to ensure complete isolation.

= 2.5.2 =
* FIXED: CSS and JavaScript class name conflicts between the Tischreservierungen plugin and PocketBooking Pro when both are active on the same site — all shared frontend class names (`.reservierung-container`, `.reservierung-step`, `.date-option`, `.date-selection-options`, etc.) in the table reservation plugin are now prefixed with `mrtr-` in the template, CSS, and JavaScript files, so they no longer interfere with each other's styles or behaviour.
* FIXED: Inline design CSS was injected into `:root {}` (global scope), causing CSS custom properties (colours, border-radius) to leak into other plugins' forms. The variables are now scoped to `.mrtr-reservierung-container` only.

= 2.5.1 =
* Fixed plugin updates not being available during the trial period — the update checker now sends `is_trial=1` using `mrtr_has_full_access()`, covering valid license, active trial, and fresh installs (trial never started) alike. Previously the `is_trial` parameter was missing entirely from the API request.

= 2.5.0 =
* IMPROVED: Admin manual reservation & edit reservation forms – the email address field is now optional. Administrators creating or editing a reservation on behalf of a guest (e.g. phone bookings) no longer need to provide an email address. Confirmation emails are still sent if a valid address is present and the option is enabled.

= 2.4.9 =
* FIXED: Kitchen capacity planning now correctly uses a per-interval counter (only reservations starting within the current time slot) instead of the full overlap counter. Previously a 15-person reservation at 11:00 with 60-min stay duration would block 11:00–11:45 for kitchen capacity, even though only the 11:00 slot should be kitchen-full. Now 11:00 is correctly blocked (15/15 kitchen capacity reached), while 11:15–11:45 remain available for up to 5 additional guests (bounded by the overall seat limit of 20–15=5), and 12:00 onwards is fully open again.

= 2.4.8 =
* FIXED: Person count in the time slot dropdown now shows only guests whose reservation is active exactly at the slot's start time (point-in-time count), instead of summing up all reservations whose window overlaps with the entire new booking duration. This prevents misleading totals where, e.g., a 17:00 reservation (2 persons, 90 min) and an 18:00 reservation (20 persons, 90 min) would both be summed on 17:15 simply because a 90-minute new booking would overlap both. Now 17:00–17:45 correctly shows "2 Pers." and 18:00–18:30 shows "20 Pers.". Capacity checking (fully booked detection) continues to use the full overlap logic.
* FIXED: Translation string `Nächste Reservierungen` (dashboard section heading "Next Reservations") was missing from all language files. Added to POT and all 10 PO/l10n.php files (de_DE, en_GB, en_US, en_US_AMPM, es_ES, fr_FR, it_IT, nl_NL, pl_PL, ru_RU).

= 2.4.7 =
* IMPROVED: Admin manual reservation & edit reservation forms – the time slot dropdown now shows the number of already-booked persons for each interval. Slots with existing bookings but remaining capacity display "(X Pers.)" next to the time. Fully booked slots (shown in orange) now read "(Fully booked · X Pers.)" so admins can see at a glance how many people are already reserved for any given slot before deciding to overbook.

= 2.4.6 =
* FIXED: Dashboard "Today's Reservations" – the upcoming reservations section now lists all confirmed reservations for today whose time has not yet passed, instead of showing only the single next one.

= 2.4.5 =
* NEW: Confirmation modal message is now customizable from the backend (Settings > Design tab). A new textarea tile "Text: Erfolgsmeldung nach Absenden" allows overriding the success popup text shown to guests after a reservation is submitted. Language-specific default texts are used as fallback when the field is left empty. Translations added to all 9 supported languages (de_DE, en_US, en_US_AMPM, en_GB, fr_FR, it_IT, es_ES, nl_NL, pl_PL, ru_RU) in both .pot and .po files.

= 2.4.4 =
* FIXED: Selected event type (Anlass) was missing from the reservation summary in step 4 of the frontend booking form. Root cause: `#event_type` is a hidden `<input>` storing the numeric event index – not a `<select>` element. The code incorrectly called `.find('option:selected').text()` on it, which always returned an empty string. Fixed by reading the event name directly from the `eventsData` array using the stored index.

= 2.4.3 =
* IMPROVED: Icon picker for "Icon: Tischreservierung" – replaced `dashicons-heart` (Herz) with `dashicons-buddicons-groups` (Gruppe), `dashicons-businessman` (Person) with `dashicons-buddicons-community` (Community), `dashicons-groups` (Personengruppe) with `dashicons-buddicons-friends` (Freunde), and `dashicons-smiley` (Smiley) with `dashicons-clipboard` (Clipboard).
* IMPROVED: Icon picker for "Icon: Besonderer Anlass" – replaced `dashicons-smiley` with `dashicons-clipboard`, `dashicons-camera` with `dashicons-megaphone`, `dashicons-performance` with `dashicons-store`, `dashicons-flag` with `dashicons-buddicons-groups`, `dashicons-awards` with `dashicons-calendar-alt`, `dashicons-heart` with `dashicons-coffee`, `dashicons-tickets-alt` with `dashicons-buddicons-friends`, `dashicons-bell` with `dashicons-food` (moved to position 1), and `dashicons-star-filled` (Stern) moved to position 8.

= 2.4.2 =
* NEW: Kitchen Capacity Planning ("Kapazitätsplanung – Küche") – a new toggle in Settings > General allows limiting the maximum number of guests that can be booked into the same time interval, independent of the overall restaurant seat count. This reflects kitchen throughput: even if the restaurant is not fully seated, a slot is blocked when the sum of already-booked guests in that interval plus the current request exceeds the configured per-interval maximum. Admins are exempt from this limit and can always overbook manually.
* NEW: "Maximale Personenanzahl pro Intervall" input field – configures the kitchen throughput ceiling per time slot (1–500 guests). Displayed when Kitchen Capacity Planning is enabled; hidden when disabled.

= 2.4.1 =
* NEW: Custom dwell time per reservation ("Verweildauer für diese Reservierung") – when creating a manual reservation in the admin backend, a toggle switch now allows overriding the default or event-specific dwell time for that single reservation. When the toggle is off, the effective dwell time (standard setting or event duration) is displayed as an info hint. When toggled on, the admin can enter any duration (5–720 min); this value is stored in the new `custom_duration` database column and used exclusively for capacity calculation of that booking. Useful for large groups that require extended kitchen capacity beyond the normal block time.
* NEW: `custom_duration` column added to the `{prefix}_reservierungen` database table. Existing installations are automatically migrated on next page load via the plugin's built-in migration routine.
* NEW: Capacity calculation now respects per-reservation `custom_duration` – when computing time-slot availability, existing reservations with a saved `custom_duration` use that value (highest priority), falling back to the event duration and then the global dwell time setting.
* FIXED: Manual admin reservations now send the same confirmation email template configured in Settings > Emails ("Reservation Confirmed" template with all placeholders: `{name}`, `{date}`, `{time}`, `{persons_text}`, `{event}`, `{cancellation_link}`, etc.) instead of a separate hardcoded plain-text fallback.
* FIXED: Event type (Anlass) with index `0` (first event in list) was never saved when creating a manual reservation in the admin backend. Root cause: PHP's `!empty('0')` evaluates to `false`, silently discarding the value. Fixed by checking `!== ''` instead.
* NEW: Admin name appended automatically to the Nachricht field when saving a manual reservation – e.g. "Manuell erstellt von Max Mustermann (admin)". If the admin also entered a message, the note is appended on a new line.
* NEW: Effective dwell time appended automatically to the Nachricht field when saving a manual reservation – e.g. "Verweildauer für diese Reservierung: 90 Min." The value reflects the actual dwell time that will be used for capacity calculation (custom override > event duration > global standard setting).
* NEW: Edit reservation form (`page=db-reservierungen&aktion=bearbeiten`) now matches the new-reservation form feature-for-feature: Anlass (event type) dropdown, Verweildauer toggle with custom duration input (pre-filled from saved `custom_duration`), Personen combobox, vacation/special-date tile highlighting, and overbooked slot coloring. Event type and custom_duration are saved correctly on form submit (including NULL-safe SQL for clearing custom_duration).
* IMPROVED: Edit reservation form – the Verweildauer hint text now reflects the actual saved state in three contextual modes: "Manuell gespeichert: X Min." when a custom override is active, "Aktive Verweildauer: X Min. (EventName)" when an event is selected, and "Aktive Verweildauer: X Min. (Standard-Einstellung)" otherwise. Previously always showed the global standard setting.
* FIXED: Edit reservation form – Verweildauer toggle state and custom_duration input are now pre-filled from the database when editing an existing reservation. Previously the toggle always appeared as OFF with the standard 15 min value.
* IMPROVED: Auto-generated Nachricht strings ("Manuell erstellt von..." and "Verweildauer für diese Reservierung: ... Min.") now use the plugin's configured language instead of the WordPress site locale. The creation date in "Manuell erstellt" is formatted according to the plugin language (DD.MM.YYYY for de_DE/pl_PL/ru_RU, MM/DD/YYYY for en_US/en_US_AMPM, DD/MM/YYYY for en_GB/it_IT/es_ES/fr_FR). All 10 supported languages are covered with full translations.

= 2.4.0 =
* NEW: Vacation & Season Management – define closed periods (e.g. holidays, seasonal breaks) in Settings > Opening Hours. All days within defined periods are automatically blocked for reservations.
* NEW: Vacation dates are visually highlighted in orange in all backend datepickers – in the Holidays & Special Opening Hours settings page and the New Reservation admin form.
* NEW: Translations for all Vacation & Season Management strings added for all 10 supported languages (de_DE, en_GB, en_US, en_US_AMPM, nl_NL, it_IT, es_ES, fr_FR, pl_PL, ru_RU).

= 2.3.9 =
* IMPROVED: Datepicker prev/next navigation buttons now use the correct plugin CSS variable `--reservierung-button-color` instead of the wrong `--simpbook-button-color` carried over from the sibling plugin.
* IMPROVED: Disabled calendar days now use `--reservierung-tile-bg` (instead of `--simpbook-tile-bg` or `--reservierung-container-bg`) for a consistent tile background color across all datepicker instances.
* FIXED: Prev/next button arrows in the frontend datepicker (`formular-style.css`) were rendered using `mask-image` with the text color variable, making them barely visible on the colored button. Switched to `background-image` with a white SVG arrow, matching all other datepicker CSS files.
* IMPROVED: Prev/next navigation buttons now appear as a square with rounded corners (`padding: 4px`, `border-radius: 4px`, `align-self: center`) instead of a tall rectangle stretching to the full header height. Applies to all datepicker CSS files (formular-style, neue-reservierung, reservierung-bearbeiten, admin-einstellungen).

= 2.3.8 =
* IMPROVED: Admin manual reservation form – time slots that are already fully booked by existing reservations are now shown in orange with "(Fully booked)" label but remain selectable, allowing admins to intentionally overbook a slot.
* IMPROVED: Admin manual reservation form – the persons field is now a combobox: a free numeric input (no upper limit) combined with a preset dropdown listing the configured standard capacity. Admins can type any number directly or pick from the preset list.
* FIXED: When creating a manual reservation in the admin backend, the entered person count no longer influenced the "Fully booked" display. A slot is only marked as fully booked when existing reservations alone reach the configured maximum capacity – the new booking's person count is excluded from the availability indicator until the reservation is actually saved.

= 2.3.7 =
* FIXED: Date validation in `mrtr_reservierung_speichern()` now correctly accepts MM/DD/YYYY and MM/DD/YY formats when the plugin language is set to English (AM/PM). Previously, only the European DD.MM.YYYY format was parsed, causing the reservation to fail with a date format error. The function now tries all supported formats in sequence (DD.MM.YYYY → DD.MM.YY → MM/DD/YYYY → MM/DD/YY), consistent with all other date-parsing functions in the plugin.
* FIXED: The date format error message was returned as a plain (untranslated) string – wrapped in `__()` so all PO file translations are now applied correctly.
* FIXED: en_US_AMPM translation of the date format error message corrected from "Please use DD.MM.YYYY" to "Please use MM/DD/YYYY".
* IMPROVED: Admin weekday availability panel now uses CSS `flex-wrap` instead of a media query for the stacked mobile layout, ensuring the layout works correctly even when WordPress admin CSS overrides the 782px breakpoint.

= 2.3.6 =
* NEW: Styled floating tooltip for unavailable/closed days – replaced browser-native "Nicht verfügbar" title tooltip in the jQuery UI datepicker ("Anderes Datum") and on disabled date tiles (Heute/Morgen) with a custom cursor-following tooltip showing "⛔ Geschlossen". The tooltip uses a consistent design across both the tile selection and the calendar picker.
* IMPROVED: Disabled date tiles no longer show any text change on hover – tile size stays fixed; the closed label appears exclusively as a floating tooltip next to the cursor.
* NEW: "Geschlossen" translation string added to POT file and all 10 PO language files (de_DE, en_GB, en_US, en_US_AMPM, nl_NL, it_IT, es_ES, fr_FR, pl_PL, ru_RU) with correct per-language translations.
* IMPROVED: Event weekday availability panel redesigned from a single-column table to a 2-column CSS grid – each day item now shows the checkbox, day name, and Von/Bis time inputs all in one horizontal row: [☑ Mo  Von 10:00  Bis 14:00].

= 2.3.5 =
* NEW: Per-weekday time configuration for events with "Bestimmte Wochentage" availability – each weekday can now have its own start and end time instead of a single time range for all days. The availability panel now shows a table with a checkbox and individual Von/Bis time inputs per day. Time fields are disabled when the day is unchecked. Frontend and admin reservation form both respect the day-specific times for slot filtering and availability checking. Existing events with the old flat time_from/time_to format are automatically migrated on display.

= 2.3.4 =
* FIXED: Dashicons (tile icons) were not displayed for non-logged-in users in the frontend reservation form. WordPress only loads the Dashicons stylesheet by default for logged-in users (due to the admin bar). Added explicit `wp_enqueue_style('dashicons')` to the frontend enqueue function so icons are now correctly shown to all visitors regardless of login status.

= 2.3.3 =
* NEW: Icon picker for reservation tile icons in the Design settings tab – choose from 9 icons each for the regular reservation tile and the special occasion (event) tile. The selected icon is saved per option and applied automatically in the frontend form.
* IMPROVED: Icon picker UI replaced with a compact trigger button showing the currently active icon – clicking it opens a modal overlay with all available icons displayed in a grid. Selecting an icon closes the modal immediately; no extra save step needed.
* NEW: Drag & Drop reordering for event types in the admin settings – order can be changed via a grab handle above the remove button; the new order is reflected immediately in the frontend form.
* IMPROVED: Event-Verwaltung tooltip extended to inform users that the order of events can be adjusted via Drag & Drop.
* FIXED: Special closing days (Spezielle Schließtage) were not being respected when a weekday-based event filter was active. The closed-day check now always runs first, regardless of any active event filter.
* IMPROVED: Star icon removed from individual event type tiles in the frontend form; tiles now display only the event name (and optional duration).
* UPDATED: All language files (POT + 10 PO files) extended with translations for: "Icon: Tischreservierung", "Icon der regulären Reservierungskachel im Frontend anpassen.", "Icon: Besonderer Anlass", "Icon der Event-Kachel im Frontend anpassen.", "Icon ändern", "Icon wählen".

= 2.3.2 =
* FIXED: Phantom datepicker appearing at the bottom of the page (showing "January 0") when selecting a reservation type or event in the frontend form. Root cause: `datepicker('refresh')` was called immediately after `slideDown()`, which sets the element to `display:block` before the animation completes – causing jQuery UI to detect the input as visible and re-trigger the calendar in an uninitialized state. Fixed by removing all `datepicker('refresh')` calls (redundant, as `beforeShowDay` re-evaluates filters dynamically on each open) and replacing them with `datepicker('hide')` to cleanly dismiss any open calendar when switching between reservation types.

= 2.3.1 =
* IMPROVED: Admin manual reservation form – closed weekdays (e.g. regular days off) and special closed dates (e.g. holidays) are now visually marked in the datepicker but remain selectable by the administrator. This allows manual bookings to be created on normally closed days without changing the general settings.
* IMPROVED: Time slot loading for admin manual reservations now bypasses the closed-day restriction – when an admin selects a closed day, available time slots based on the restaurant's regular opening hours are shown instead of a "closed" message. Capacity rules and the configured maximum seat count still apply.

= 2.3.0 =
* NEW: Single-event mode – if only one event type is configured, the event tile displays the event name directly and activates without a dropdown.
* NEW: Tile-based date selection for special_dates events – guests select from visual date tiles instead of the calendar picker; no unavailable-day confusion.
* NEW: Admin manual reservation form now supports full event-aware date filtering – tile selection for special_dates events and weekday calendar filtering for weekday-type events, matching frontend behavior exactly.
* NEW: Weekday name prefix on all date displays in the backend (e.g., "Donnerstag, 07.03.2026") – shown in the reservation list, modal detail view, calendar events, and reservation edit view.
* FIXED: Events now correctly override normally-closed weekdays – event time bounds are applied before the closed-day check, allowing guests to book on days the restaurant is usually closed when an event is scheduled on it.
* FIXED: Slot validation for events – only time slots where the full event duration fits before the closing time are displayed; slots that would run past closing time are hidden.
* IMPROVED: Design settings – Formular-Überschriften cards for "Reguläre Reservierung" and "Besonderer Anlass" moved to the top of the headings grid for faster access.

= 2.2.0 =
* FIXED: Capacity planning incorrectly blocked time slots before an existing reservation when Events were enabled. If no event type was selected by the guest, the system falsely used the first event's duration (e.g. 90 min) instead of the configured standard guest stay duration for calculating the new booking window. This caused slots like 11:00–11:45 to appear as fully booked even though no reservations existed in that time range. Root cause: `intval('')` evaluates to `0`, which matched event index 0. Fixed by explicitly checking for an empty string before treating the value as a valid event index.

= 2.1.9 =
* NEW: Live preview of frontend form in design settings tab
* NEW: Real-time design updates - see changes immediately in preview while adjusting settings
* NEW: Two-column layout in design tab - settings on left, live preview on right
* NEW: Admin notification email when guest cancels a reservation
* NEW: Configurable email template for admin cancellation notifications
* NEW: Complete translation support for admin cancellation emails in all 10 languages
* IMPROVED: Enhanced cancellation email system with separate templates for guests and admins
* IMPROVED: Cancellation emails now include all relevant information (name, email, phone, date, time, persons, occasion)
* IMPROVED: Design settings workflow with interactive preview for better user experience

= 2.1.8 =
* IMPROVED: Event system terminology - "Event-Typ" renamed to "Anlass" (Occasion) for better clarity
* IMPROVED: Dropdown text changed to "Bitte wählen Sie einen Anlass aus" (Please select an occasion)
* IMPROVED: Simplified reservation type selection - removed redundant subtitle texts
* IMPROVED: Renamed "Tischreservierung" to "Reguläre Reservierung" (Regular Reservation) for consistency
* NEW: Occasion/Event name now displayed in guest and admin emails
* FIXED: First event (index 0) now correctly displayed in reservation list
* UPDATED: All 10 language files updated with new terminology (de_DE, en_GB, en_US, en_US_AMPM, es_ES, fr_FR, it_IT, nl_NL, pl_PL, ru_RU)

= 2.1.7 =
* BUG FIXES

= 2.1.6 =
* IMPROVED: Update check now displays results directly in settings card instead of banner notification
* IMPROVED: Centralized version management with MRTR_VERSION constant
* FIXED: Date formatting issue in emails (resolved timezone display bug)
* FIXED: Update check now correctly sends 'action' parameter to license server
* FIXED: License key option name now consistent (mrtr_lizenz_key) across all components

= 2.1.5 =
* NEW: Event Management system for special occasions (birthdays, weddings, corporate events, etc.)
* NEW: Configurable event types with custom durations
* NEW: Separate event booking flow in reservation form
* NEW: Event-specific capacity planning with automatic duration consideration
* NEW: Customizable form headings for event booking steps
* NEW: Optional display of event duration in frontend
* NEW: Dutch (nl_NL) language support added - complete translation of all strings
* NEW: Calendar week view now default on desktop (improved for daily use)

= 2.1.0 =
* NEW: Progressive Web App (PWA) / Mobile App functionality
* NEW: Install reservation system as standalone mobile app (iOS/Android)
* NEW: Push notifications for new reservations (optional, VAPID-based)
* NEW: Mobile-optimized interface with bottom navigation
* NEW: QR code generation for easy app installation
* NEW: Card View and Table View toggle in reservation list
* NEW: User preference saved for view mode selection
* IMPROVED: Touch-friendly card-based layouts for mobile devices
* IMPROVED: Responsive design for all admin pages

= 2.0.2 =
* NEW: Dynamic calendar time slots - Week and day views automatically adjust to opening hours
* IMPROVED: Week view now shows earliest to latest time across all weekdays
* IMPROVED: Day view displays only the specific day's opening hours
* IMPROVED: Closed days automatically fall back to global time range
* IMPROVED: All calendar view buttons (Month/Week/Day) now visible on mobile devices

= 2.0.1 = 
* NEW: Russian (ru_RU) language support added
* NEW: English (UK) (en_GB) language support added
* IMPROVED: Language dropdown now shows all 9 supported languages

= 2.0 =
* NEW: Setup wizard for easy initial configuration.
* NEW: Calendar view in backend with FullCalendar integration
* NEW: iCal feed subscription for external calendar applications (Google Calendar, Outlook, Apple Calendar, Thunderbird)
* NEW: Modal-based reservation detail view with tile layout
* NEW: Status indicator in calendar event titles for pending reservations
* IMPROVED: Responsive design for reservation overview and modal
* IMPROVED: Better mobile experience with optimized layouts


= 1.1.3 =
* NEW: Complete internationalization with 6 supported languages (DE, EN, IT, ES, FR, PL)
* NEW: Language-specific email templates with standard templates for all languages
* NEW: Translated calendars (months and weekdays) in frontend and backend
* NEW: Corner radius setting for form design
* NEW: Special opening hours are considered when manually creating reservations

= 1.1.0 =
* NEW: Management for holidays and special opening hours added. Days can now be completely closed or given different hours.
* NEW: CSV export function for reservations.
* Improvement of license and trial period logic.

= 1.0.0 =
* First release of the plugin.
* Main features: Online reservation form, backend management, customizable emails, and weekly opening hours.


== Support ==

For support, questions, or feedback, please visit https://mrstudio.codes

== Credits ==

Developed by Maxim Ristow / maksim85 for MRStudio.
