# Changelog: 1.0.0

1.0.0 is a redesign of the imported UI over `@v-office/website-headless` 1.0.0, with no 0.x
compatibility. The package now covers six platform surfaces (`SearchBar`, `Showcase`,
`SearchResults`, `Quote`, `Booking`, `ContactForm`), one `RentalCard` for every list, eleven
rental-page blocks, `RichText`, `BookingReturn`, `AvailabilityCalendar` and the maps. Behaviour
lives in headless; the components render its stores. Facts about the business are required props,
presentation defaults are the fleet majority, and one site's rulings are props a site sets, no
longer behaviour for everyone. Storage keys, URL keys and the gate markers are unchanged.
`MIGRATION.md` lists what to change, in order.

## Added

### Surfaces and their bindings

- `ContactForm` and `useContactForm`: the contact and inquiry form, a PMS write with validation,
  the sixth surface. The SDK loads on the first submit; `supportEmail` is required (`null` when the
  business has no publishable inbox).
- Bindings for a site's own UI over the headless stores: `useSearchForm`, `useSearchStore` (with
  `browserHistory` and `DEFAULT_STORE_KEY`), `useQuoteFlow`, `useCheckoutFlow`, `useGuestForm`,
  `useContactForm`. Importing one without the surface's component makes the surface `custom` in the
  site manifest.

### Search and results

- `RentalJump` (the rental-name combobox, standalone or as `SearchBar rentalJump`), `SearchCount`,
  `SearchSort`, `SearchFilters`, `SearchFilterChips`, `SearchQuickFilters`, `OfferCampaignFilter`
  and `PrerenderedResults` (the undated listing for crawlers), all over the page's one search store.
- `SearchResults` `trailingTile` and `trailing`: a site tile after the last card.

### The card, the rental page, text

- `RentalCard`: the one card of `Showcase`, `SearchResults`, `PrerenderedResults` and the map
  popup, configured by one `RentalCardOptions` object.
- The rental-page blocks: `RentalHeading`, `RentalActions`, `RentalGallery`, `RentalFactList`,
  `RatingBadge`, `RentalDescription`, `RentalAmenities`, `RentalRooms`, `RentalReviews`,
  `RentalProperty`, `RentalDistances`. They server-render without a client directive and are bound
  by the layout's headless `enhance()`.
- `AvailabilityCalendar` (a read-only occupancy calendar that joins the rental's quote flow),
  `BookingReturn` (the payment-return page body), `RichText` (sanitized PMS text and legal
  documents).

### Maps (`./map`)

- `SearchResultsMap` reads the page's search store; new `SearchMapPill`, `RentalMap` and
  `LocationMap`. `maplibre-gl` is loaded on demand. Every map takes `loadOn` (`"click"` default,
  `"near"`, `"consent"` with `consentCategory`); `CONSENT_EVENT`, `CONSENT_GRANTED_ATTRIBUTE` and
  `useConsent` connect a site's consent host.

### Props since the 1.0 review

- `Quote` `barLayout` (`"full"` default, `"floating"`: from md a centred card) and `barBelow`
  (`"md"`, `"lg"` default, `"xl"`): the bar is fixed to the viewport by the package and hides
  itself from `barBelow`, where the page shows the card.
- `RichText` `firstHeading` (`"section"` default, `"title"`: a leading heading renders as the page
  title, an h1) and `title` (drawn as that title when the document opens with text).
- A `{contact}` token in `deferredNotice` (`SearchBar`) and `bookableFromNotice` (`Quote`) places
  the not-bookable-yet contact link inline in the sentence; without the token the link sits on its
  own line. `BookableFrom.precision` (`"day"`, `"month"`, `"year"`) words the date ("ab 2027").
- `Showcase` `moreLabels`: per group id, the more tile's own text (`{count}`, `{label}`).
- `RentalFactList` `extraFacts` take `{ label, glyph? }` as well as strings, and an `"extra"` entry
  in `facts` places them (default: after the listed facts).
- `Booking` `policyCopy`, the same object as `Quote`'s, so the rate rows read the same on both.
- `RentalMap` `address="none"` leaves the address line to the page.

### Copy, parts, conventions

- Every component takes `voice` (`"neutral"` default, `"du"`, `"sie"`); copy tables are
  `CopyTable<T>` with German `du` / `sie` overlays, resolved by `resolveCopy` and `resolveShared`.
- Copy keys that take tokens are typed headless `Template<…>` with the tokens the component fills.
  Write a site's `copy` and `shared` overrides through headless `defineCopy`: a token the key does not
  take is then a compile error instead of a visible `{x}` on the page. `fillParts` and
  `FillPartsOptions` are generic over the tokens.
- A `data-part` vocabulary on every surface and block (`SEARCH_BAR_PARTS`, `RENTAL_JUMP_PARTS`,
  `SEARCH_RESULTS_PARTS`, `SHOWCASE_PARTS`, `RENTAL_CARD_PARTS`, `RENTAL_DETAIL_PARTS`,
  `QUOTE_PARTS`, `BOOKING_PARTS`, `CONTACT_PARTS`, `RICH_TEXT_PARTS`, `MAP_PARTS`, `FIELD_PARTS`,
  `PRIMITIVE_PARTS`); state is an attribute, never a class.
- One prop name per concept: `headingLevel` (`1`–`6`, `"none"`), `glyphs` (`"none"`, `"default"`,
  `"mapped"` with `glyphMap`), breakpoints `gridFrom`, `mosaicFrom`, `collapseBelow`,
  `overlayActions: { below }` (`"md"`, `"lg"`, `"xl"`), `whenEmpty`, `loadOn`.
- `useFavorites`, `useEnhance`, `useSdk`, `useLazySdk`, `GlyphIcon`, `fill`, `fillParts`,
  `dateFnsLocale`, `HeadingLevel`, `HeadingTag`.

### CSS

- `css/layers.css`: the layer order statement,
  `@layer properties, theme, base, voffice-tokens, voffice-components, components, utilities;`.
  Every package stylesheet starts with it.
- `css/motion.css` (the press dip, arrow hover, heart bursts and overlay transitions, opt-in) and
  `css/map.css` (MapLibre's own CSS, layered).
- Optional token axes, each read with its fallback: `--selection` / `--selection-foreground`,
  `--primary-hover`, `--offer` / `--offer-foreground`, `--mark` / `--mark-foreground`,
  `--accent-text`, `--radius-card`, `--radius-pill`, `--radius-control`, `--radius-label` (labels;
  falls back to `--radius-pill`), `--radius-badge`, `--shadow-card`, `--shadow-overlay` (floating
  layers; falls back to `--shadow-card`), `--text-caption`, `--card-image-aspect`,
  `--showcase-item-width`, `--results-card-min`, `--search-hero-label-weight`,
  `--search-hero-value-size`, `--search-panel-offset-top`, `--cal-months-gap`,
  `--cal-nav-duration`.

## Changed

- **Peer dependencies:** `@v-office/website-headless >=1.0.0 <2` (was `>=0.1.1 <0.3.0`),
  `@v-office/website-sdk >=2.25.0 <3` (was `>=2.16.0 <3`), `maplibre-gl >=5 <6` (optional; was
  `>=5`).
- **Class merging:** the package depends on `cn` instead of `clsx` and `tailwind-merge`. The merged
  class names are the same; a site's own `clsx` and `tailwind-merge` keep working.
- **The SDK prop:** every SDK-using component takes `sdk: SdkSetup` (`{ config, options? }`) from
  headless; surfaces with an equal setup share one SDK instance per page.
- **`SearchBar`:** `action` and `contract` (was `backend`) are required; `bookableFrom` became
  `dates.bookable` (`BookableFrom`, ISO days), `flexiblePeriods` became `dates.flexibleStays` (`[]`
  removes the Flexibel tab), `regions` are `RegionOption`s; `filterDefs` is gone (the bar carries
  every URL pair it does not own; `filters` is the compact filter trigger); new `fields`, `regionSelect`, `guests`, `preset`,
  `glyphs`, `panel`, `panelSide`, `panelAnchor`, `flow`, `mobile` (`"steps"`, `"scroll"`,
  `"inline"`), `collapseBelow` and `rentalJump`.
- **`SearchResults`:** `contract` and `rentalHref` (a route template) are required; `filters` is
  `ResolvedFilters` (was `filterDefs`), `facts` is `RentalFactsMap` (was `rentalFacts`), `card` is
  `RentalCardOptions`.
- **`Showcase`:** `groups` are headless `ShowcaseGroup`s of `CardSource`; new `layout`, `gridFrom`,
  `columns`, `arrows`, `loop`, `rotate`, `moreTile`, `card`, `favoritesKey`.
- **`Quote`:** `rental: QuoteRental` replaces `rentalId` and `petsAllowed`; `checkoutHref` (required,
  `null` for an enquiry-only page) replaces `checkoutPath`.
- **`Booking`:** `rental: BookingRental` replaces `rentalId`, `rentalName`, `rentalLocation`,
  `rentalHref`, `images` and `petsAllowed`; `legal` takes `{ terms, privacy }` links with an
  optional headless `LegalDocument` (was HTML); `returnPath` and `payment` are required.
- **`SearchResultsMap`:** `style` became `styleUrl`, `DEFAULT_CENTER` became `emptyView`; it needs
  `css/map.css`.
- **Copy:** tables are `CopyTable<T>` (was `Record<CopyLocale, T>`); `CheckoutFlowCopy` became
  `CheckoutCopy`, `PolicyChoiceCopy` became `PolicyCopy` (`DEFAULT_POLICY_COPY` reshaped);
  `SHARED_COPY` gains the `card` and `rental` groups and the voices.
- **Parts:** the `rental-card` parts are renamed to `RENTAL_CARD_PARTS`.
- **`components.css`** declares no Tailwind theme variable on `:root` and reads no `--color-*`;
  a site's own theme is untouched.

### Visible defaults that changed

- German copy is neutral and addresses nobody; 0.1.x said "Sie" in several strings. A `du` or `sie`
  site sets `voice`.
- Calendar day prices are on (`dayPrices="rounded"` on `Quote` and `Booking`); 0.1.x showed none
  for every site. `AvailabilityCalendar` shows none unless given `dayPrices`.
- No payment glyphs unless `payment.methods` lists them.
- Map tiles load on click (`loadOn="click"`), not on page load.
- No hover zoom, lift or press dip without `css/motion.css`.
- An eyebrow without a feed type prints the town only; `copy.townOnly` brings "Ferienwohnung in …"
  back.
- Floor plans are apart from the photo strip in `RentalGallery`.
- The favourites page's removal animation is the package's (`data-state="leaving"`, 280 ms, none
  under reduced motion).

## Removed

- `onRateConfigurationFault` on `Quote` and `Booking` (they dispatch `voffice:quote` and
  `voffice:checkout`).
- `SEARCH_RESULTS_EVENT`, `SEARCH_RESULTS_REQUEST_EVENT` and `SearchResultsEventDetail` (the map
  and the satellites read the store).
- `getCountryGroups` and `CountryOption` (headless `countryOptions`), `RentalFacts`,
  `RentalWater` and `DISTANCE_ADJACENT` (headless owns the card model), `ShowcaseRental` and
  `ShowcaseImage`, `CheckoutImage`, `RenderedLegalDoc`, the `SdkConfig` type.
- The default German routes: every route is a required prop.

## Unchanged

- Storage keys (`<namespace>-merkliste`, `voffice:checkout-context`, `voffice:booking-return`) and
  the `merkliste:changed` event.
- Every URL key and the German sort values (`empfohlen`, `preis-auf`, …).
- The kits' behaviour and gate markers on the same elements: `data-result-card`,
  `data-rental-stats`, `data-fav*`, `.card-images`, `data-img-*`, `data-skeleton-field`, the
  description and amenity markers.
- `book()` and `pay()` run only from a click; the § 7 VVG insurance document step cannot be hidden.
- The guest selectors of `Quote` and `Booking` follow 0.2.0's v9 children and pets rules: no
  children or babies on a rental that takes none, dogs capped at `maxPets`, and a handed-over
  count stays until the guest lowers it. `Booking` loads them when its guest editor first opens.
