- Hide img overlay on .playing so video is visible when playing
- Add controls on play click
- When no poster: show video directly with preload=metadata (native first frame)
- why-grid left col 704px → minmax(0,500px) so video column gets more space
- video-card: flex fills available width, absolute positioning for img/video stack
- aspect-ratio 9:16 for portrait video
- Strip absolute origin from video/poster src (fixes cert error from shumi.ai-impress.com)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Background-image on the element is always behind content — no overlay div
needed. card-pattern-arcs.svg (360×360 arc circles, #70b030 strokes)
is visible on dark green without opacity tricks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PageHero: swap opaque green fill for subtle black gradient so hero photo shows through
- Locations cards: add card-wave-green.svg pattern on top of solid green bg
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move hero title plate to the bottom of the photo so faces stay visible
- Admin can now set hero title/subtitle size (px) and font
(Montserrat/Poppins/Inter); mobile scales via clamp()
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PNG sources re-encoded losslessly, oversized JPGs at q92:
22 files, 13.6MB -> 4.5MB. JPGs that would grow after
re-encoding are kept as-is. References updated; originals
kept on disk since CMS rows may still point at them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add checkbox field to control whether a location card appears on /lokatsii.
Default true so existing entries remain visible. Filter added to getLocations query.
Migration 20260610_140000 adds show_on_lokatsii boolean column with DEFAULT true.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- beforeChange hook: when ezy_id changes, fetch tariff from ezy API,
populate last_synced_name/price/at; throw if ezy_id not found
- POST /api/tariffs/[id]/sync-ezy: re-sync a specific tariff on demand
- SyncEzyButton: custom Payload UI field component with loading/ok/error states
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
buildComboCards now uses ezy tariffs as primary source when available.
Static cards are only used for descriptions and as fallback when ezy is down.
This removes test/placeholder cards and fixes mismatched prices from CMS.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- revalidatePath + kvytky page: use http://localhost:3000 for server-to-self
fetches (was using NEXT_PUBLIC_SITE_URL with self-signed HTTPS → Node rejected cert)
- Footer: strip hostname from Payload media URL (same fix as Header)
- DyvoLisTickets: show zone ticket named 'Диво' for individual dyvolis tickets
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add googleReviewUrl text field to HomePage.sectionTitles group so editors
can update the Google review link without a deploy. Falls back to the
hardcoded URL when the field is empty.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Copy original lossless PNG to public/images/locations/ as hero bg fallback
(bypasses Payload WebP compression entirely when CMS has no image)
- Fallback heroBgUrl to static PNG so the banner always renders
- Raise Media collection WebP quality: 82→88 (mobile/tablet), 85→92 (original+desktop)
Future re-uploads will have noticeably better quality
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
extraItems was simplified to always use FALLBACK_EXTRA_ITEMS in the
previous refactor, breaking CMS editability for Костюмованих ведучих,
Аквагрим, Затишну альтанку. Restore CMS-first logic: use
cmsPackageItems[3+] when available, fallback otherwise.
Replace wrong gallery-shumi-6.webp (DyvoLis topiary arch) with null
so the placeholder SVG shows until a real photo is uploaded via CMS.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
heroBgUrl was never populated — page.tsx queried only the dinosaur-page
global and didn't read the Location's heroBackground upload field.
Now fetches the locations collection in parallel and passes heroBgUrl to
DinoPageContent, which already handles the conditional hero-bg render.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove 10 CMS global fields that had data+fallbacks but were never rendered:
workingHours, pricingPackages, entrancePrices, freeInclusions, entertainmentPackages
plus heroCta, packageSectionSubtitle, and their title fields.
In page.tsx: remove TicketCard component, TicketCardData interface, and all
corresponding variable declarations (~80 lines). Simplify extraItems to always
use FALLBACK_EXTRA_ITEMS (removes fragile cmsHasPhotos && length>3 condition).
Fix typo in packageItems defaultValue: 'ДинопаркArk' → 'ДиноПарк'
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DinoPageContent: add isolation:isolate to .hero so z-index:-1 hero-bg
is visible (was painted behind the page background color)
- Gallery: pad CMS images with static fallbacks when fewer than 9 entries,
so the slider always shows a full set even if CMS only has 2 photos
- Birthday page: replace null altanka image with gallery-shumi-6.webp placeholder
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Payload 3 + PostgreSQL rejects string IDs for upload field relationships;
helpers were returning String(doc.id) which caused ValidationError on
every location/post create that referenced an already-existing media record.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace text src/poster in whyVideos with media upload pickers so
admins can upload video files directly from the CMS instead of
entering raw URLs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
extraItems now uses slice(3) without end limit — items 4-N all appear
in the "Також можна додатково замовити" grid instead of being silently dropped.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Admins can now upload custom pattern images for green and orange
pricing cards via Home Page → День народження → Паттерн зелених/оранжевої карток.
Falls back to static /images/figma/card-pattern-*.png if not set.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove DyvoLisPage global from Payload config (was not connected to website,
website reads from locations collection instead)
- Fix docker-compose.prod.yml migrate service volume path:
/app/migrations -> /migrations to match Dockerfile.migrator WORKDIR
- Wrap seed route in try/catch to return proper error instead of silent 500
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add FAQ accordion section (FAQ.tsx) after Reviews on home page
- Add faq group field to HomePage global (title + items array)
- Add HomePageFaq types to types/globals.ts
- Seed whyParents.items with 6 items from static fallback texts
- Seed faq with 6 Q&A items about the park
- Migration 0012: create home_page_faq_items table for Payload array field
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CookieBanner: bottom-fixed, stores consent in localStorage,
links to privacy policy, green brand colors
- Privacy policy + Data processing: replace GDPR as primary
reference with ЗУ «Про захист персональних даних» № 2297-VI,
correct article references (ст. 6, 8, 16, 24 Закону),
supervisory authority: Уповноважений ВРУ з прав людини
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CheckoutPage: pass instructions and terms from CMS global to frontend;
instructions shown above form, terms below button
- ThankYouPage: fetch title/message/contactPhone/contactEmail from CMS;
contact info shown if set, falls back to hardcoded defaults
- Hero: use backgroundImageUrl text field as fallback for media upload
- Add lexicalToText util for plain-text extraction from Payload Lexical JSON
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove early-return guard that skipped global linking when both forms already existed. Per-form idempotency is handled by the '?? await payload.create()' pattern, so we can safely always run updateGlobal to ensure forms are linked to their globals even after re-runs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Payload forms plugin requires a Lexical rich-text confirmationMessage
when confirmationType is 'message'; omitting it caused a 500 on seed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix auth bypass when SYNC_SECRET env var is unset: now defaults to empty string
- Change idempotency check from totalDocs >= 2 to per-form existence checks
- Allow reuse of existing forms instead of creating duplicates if one creation fails
- Handles partial seed state gracefully (e.g., birthday form exists but group form missing)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DinoPageContent: wheel shows exactly 5 dinos in the bottom bowl (fixed 30°
slot, decoupled from CMS dino count; far nodes parked off-screen)
- non-active dinos darkened to silhouettes, active stays full color
- hero banner swapped to blue T-Rex, height 1096px, 12px gap below header
- optimize heavy CMS images (61MB -> 9MB) and commit media + public assets
so git holds everything needed for deploy
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Wheel size increased: 1500px at 1440vw, overflows and clips correctly
- Fixed initial wheelAngle from 270 → -(180/n) so item[0] is at top on load
- Segment colors: unified warm orange, only active+adjacent highlighted
- Removed pagination dots/arrows (not in Figma)
- Gallery: 4 photos in grid, no border, rounded corners
- page.tsx: use FALLBACK when CMS has < 20 dinos (maps epoch→latinName, weight→height)
- DinoGallery: add real park photos as static fallback (T-Rex, aerial, arch)
- DinoHero: use T-Rex PNG as fallback when no CMS heroImage uploaded
- Locations/lokatsii: add DB slug aliases (dzerkalnyi-labiryt→maze, tyr→tir,
maiydanchyk→playground) so all 5 locations get correct images
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>