# Handoff: Unger Reisen — Website-Redesign (One-Pager) ## Overview A modern, bold one-page marketing website for **Unger Reisen**, an omnibus (coach/bus) company from Niederbayern (Buch am Erlbach & Landshut, Germany). The page pitches their services (coach hire, corporate/club trips, transfers), shows the fleet, displays both locations on an interactive map, and drives visitors to call. Language: **German**. The signature element is a **scroll-driven hero**: a stylized bus drives left→right across the bottom of the hero as the user scrolls down. ## About the Design Files The file in this bundle (`Unger Reisen.dc.html`) is a **design reference created in HTML** — a working prototype showing the intended look, motion, and behavior. It is **not** production code to copy verbatim. The task is to **recreate this design in the target codebase's environment** (React/Next.js, Vue, Astro, plain Vite, etc.) using that project's established patterns, component library, and conventions. If no codebase exists yet, pick the most appropriate stack (a React/Next.js + Tailwind setup fits this well) and implement it there. > Note on the file format: the prototype is authored as a "Design Component" (`.dc.html`) > with a small custom template runtime (``, `{{ }}` holes, ``, a > `class Component extends DCLogic`). **Ignore that runtime.** It is only a prototyping > harness. Read it as: HTML structure + inline styles + a plain JS class whose `renderVals()` > returns the data arrays and event handlers. Reimplement with normal components and state. ## Fidelity **High-fidelity (hifi).** Final colors, typography, spacing, layout, motion, and copy are all intentional. Recreate pixel-closely, but re-express the styling in the target system (e.g. Tailwind classes / styled-components) rather than copying inline styles. --- ## Design Tokens ### Colors | Token | Value | Usage | |---|---|---| | `--red` (accent) | `#C8102E` | Primary accent. Marquee, stat band, buttons, pins, route, section eyebrows. (Prototype default is `#C8102E`; original palette also used `#E4002B`. Curated options: `#E4002B`, `#D21F1F`, `#C8102E`, `#EE3524`.) | | `--ink` / `--night` | `#0a0e18` | Page background (near-black navy) | | `--paper` | `#f4f0e8` | Light text on dark; light card backgrounds | | Card surface | `#111725` | Dark cards (services, fleet, contact) | | Card surface (hover) | `#151d30` | Service card hover | | Map panel bg | `#0d1420` | Map container background | | `--line` | `rgba(255,255,255,.14)` | Hairline borders/dividers on dark | | `--muted` | `#8b93a7` | Muted body text | | Body text on dark | `#c8cdda` | Hero paragraph, secondary text | | Sub-label text | `#9aa6c0` | Pin sublabels, small caps labels | | Footer legal text | `#5a6274` / `#40485a` | Footer links & disclaimer | | Input border (light card) | `#d3ccbe` | Form inputs (note: forms were later removed) | ### Typography - **Display font:** `Anton` (Google Fonts). Used for all big headlines, stat numbers, logo, pin labels. Always `text-transform: uppercase`, `letter-spacing: .5px`, `line-height: .9`. - **Body/UI font:** `Archivo` (Google Fonts), weights 400–900. Body, nav, labels, buttons. - Google Fonts import: `https://fonts.googleapis.com/css2?family=Anton&family=Archivo:wght@400;500;600;700;800;900&display=swap` - Type scale (fluid, `clamp`): - Hero H1: `clamp(64px, 13vw, 190px)` - Section H2 (Anton): `clamp(40px, 7vw, 90–96px)` - Stat numbers: `clamp(44px, 6vw, 72px)` - Fleet seat number: `40px` - Body: `16–19px`; nav/labels/buttons: `12–15px` uppercase, `letter-spacing 1–3px` ### Spacing / Layout - Section vertical padding: `clamp(70px, 10vw, 130px)`; horizontal: `clamp(20px, 5vw, 60px)` - Card grid gaps: `16px`; large column gaps: `clamp(30px, 5vw, 70px)` - Border radius: mostly **sharp** (0–2px). Buttons are rectangular (no pill). Only pins/dots are circular. ### Shadows - Bus body: `0 18px 30px -10px rgba(0,0,0,.6)` - Map pin dot: `0 0 0 5px 40, 0 2px 6px rgba(0,0,0,.55)` (red glow ring + drop) - Buttons lift on hover via `transform: translateY(-2px)` (transition `.2s ease`) --- ## Screens / Views Single continuous page. Sections top→bottom: ### 1. Top Marquee - Full-width red (`--red`) bar, white uppercase text scrolling right→left infinitely. - Content, `/`-separated: "Reisebusse mit Fahrer / Firmen & Vereine / Tagesfahrten / Transfers rund um die Uhr / Niederbayern". - Implementation: duplicate the track and animate `translateX(0 → -50%)` linear infinite (~24s). - `font-size:13px; font-weight:700; letter-spacing:2px`. ### 2. Nav (fixed/absolute over hero) - Left: logo — "UNGER" (Anton, 26px, white) + "REISEN" (Archivo, 11px, letter-spacing 5px, red). - Right: links (uppercase, 13.5px, weight 600) — Leistungen, Flotte, Karriere, Kontakt — plus a red CTA button **"Jetzt anrufen"** (`href="tel:+498762896"`). - Sits at `top:39px` (below marquee) when at page top; **on scroll >40px** it solidifies: background `rgba(10,14,24,.9)`, `backdrop-filter: blur(12px)`, moves to `top:0`, reduces padding, adds a hairline bottom shadow. Transition `.35s ease`. ### 3. Hero (`#top`, min-height:88vh) - Dark radial-gradient bg: `radial-gradient(120% 90% at 70% 10%, #182238 0%, #0a0e18 60%)`. - Eyebrow: red rule + "OMNIBUSUNTERNEHMEN SEIT GENERATIONEN". - H1 (Anton): "Wir bringen / Sie **weiter.**" — "weiter." in red. - Paragraph (max 520px, `#c8cdda`): "Moderne Reisebusse mit erfahrenen Fahrern — für Firmen, Vereine und Gruppen in ganz Bayern und Europa." - Buttons: red **"Jetzt anrufen →"** (`tel:`), outline **"Unsere Flotte"** (`#flotte`). - **Driving scene** (bottom of hero, `height: clamp(280px,42vh,420px)`, pinned bottom): - Layered parallax: far scenery hills, near hills, a dark road strip, red-dashed lane stripes. Each is a repeating radial/linear-gradient background animated via `background-position-x` at different speeds (far slow ~40s, near ~18s, stripes fast ~.5s) — evokes forward motion. - **The bus**: CSS-drawn side view — cream body with red mid-stripe, windshield, window strip, "UNGER REISEN" wordmark, door, two spinning wheels (`@keyframes wheel` rotate, .5s linear), a pulsing headlight glow. Bus width `clamp(380px,52vw,620px)`. - **Scroll-driven horizontal motion:** on scroll, compute `hp = clamp(scrollY / (heroHeight * 0.9), 0, 1)` and set the bus `transform: translate(x, bob)` where `x` interpolates from just off-left (`-busWidth*0.30`) to `sceneWidth - busWidth*0.70`, and `bob = sin(now/380)*4` (gentle vertical bob; 0 if reduced-motion). Driven by `requestAnimationFrame`. - Respect `prefers-reduced-motion`: disable marquee, hills, stripes, wheel spin, and bob. ### 4. Stat Band - Full-width red bg, white. Auto-fit grid of 4 stats (Anton big number + label): - **2** — Standorte in Bayern - **60+** — Sitzplätze pro Reisebus - **24/7** — Für Sie erreichbar - **∞** — Ziele in ganz Europa ### 5. Leistungen (`#leistungen`) - Header row: H2 "Das fahren wir für Sie" + intro paragraph. - Auto-fit grid (min 260px) of 4 dark cards (`#111725`, hairline border, min-height 260px). Each: big red Anton index (01–04), title (uppercase 22px/800), description. Hover: bg `#151d30` + `translateY(-4px)`. 1. **Busanmietung** — "Moderne Reisebusse mit Fahrer — flexibel für einzelne Fahrten oder mehrtägige Touren." 2. **Firmenreisen** — "Betriebsausflüge, Tagungen und Events. Ihr Team sicher und entspannt am Ziel." 3. **Vereinsfahrten** — "Ausflüge, Feste und Sportevents — komfortabel für die ganze Gruppe." 4. **Transfers** — "Flughafen-, Hotel- und Event-Transfers. Pünktlich und rund um die Uhr planbar." ### 6. Real Photo Band - Full-bleed band (`height: clamp(320px,48vw,520px)`) with a background bus photo, dark gradient overlay (`rgba(10,14,24,.55 → .75)`), centered Anton headline: "Komfort, auf den Sie sich verlassen können." - Prototype image URL: `https://www.unger-reisen.de/wp-content/uploads/startslider-bus-1024x366.png` (external; **replace with a licensed/owned photo** — see Assets). Has an `onerror` fallback to a gradient. ### 7. Flotte (`#flotte`) - Eyebrow "Unsere Flotte" + H2 "Für jede Gruppengröße". - Auto-fit grid (min 280px) of 3 cards. Card header row: name (Anton 30px) on the left, and a right-aligned inline seat unit: small "bis" + big red number (Anton 40px) + small "Sitze". Body: description + tag chips (hairline-bordered pills of text). - **Reisebus** — bis **60** — "Der Große für lange Strecken und große Gruppen — voll ausgestattet." Tags: Klimaanlage, WC, Bordküche, WLAN. - **Midibus** — bis **35** — "Wendig und komfortabel — ideal für mittlere Gruppen und Tagestouren." Tags: Klimaanlage, Komfortbestuhlung. - **Kleinbus** — bis **19** — "Persönlich und flexibel für kleine Gruppen, Transfers und Sonderfahrten." Tags: Flexibel, Wendig. ### 8. Kontakt + Karte (`#kontakt`) - Eyebrow "So erreichen Sie uns" + H2 "Zwei Standorte. / Ein Anruf." - Two-column grid (`1.35fr / .95fr`, stack on mobile): - **Left — interactive map** (panel `min-height:440px`, bg `#0d1420`, hairline border): - **MapLibre GL JS** map, dark Carto style `https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json`. - Two custom HTML markers (`anchor:'bottom'`): a label box (Anton title + Archivo sub) above a circular dot with a red glow ring. - **Landshut** — "Niederlassung" — coord `[12.1508, 48.5449]` — dot red, ring white. - **Buch a. Erlbach** — "Hauptsitz" — coord `[12.0517, 48.4703]` — dot white, ring red. - **Route line** between the two coords: a GeoJSON `LineString`, red, `width 3`, `line-dasharray [1.6,1.4]`, plus a wider low-opacity casing (`width 9, opacity .18`). - `NavigationControl` (zoom + compass) top-right. **`scrollZoom` disabled** so page scroll isn't hijacked. `fitBounds` to both points with padding `{top:96,bottom:70,left:70,right:70}`, `maxZoom:12`. Call `map.resize()` shortly after load. - Overlay chip (bottom-left, `pointer-events:none`): "**15 km** zwischen den Standorten". - Requires `maplibre-gl` (JS + CSS). In prototype loaded from `https://unpkg.com/maplibre-gl@4.7.1/...`; in a real app install the npm package. Map tiles load **online** — expected for a live site. - **Right — contact card** (`#111725`, hairline border): - **Hauptsitz** (white dot / red ring): "Eichenstr. 7+9, Vatersdorf · 84172 Buch am Erlbach" · Tel. +49 (0)8762 / 896 - divider - **Niederlassung** (red dot / white ring): "Jenaer Straße 4a · 84034 Landshut" · Tel. +49 (0)871 / 96 58 586-0 - CTAs pinned to bottom: red **"Jetzt anrufen"** (`tel:+498762896`) + outline **"info@unger-reisen.de"** (`mailto:`). ### 9. Karriere (`#karriere`) - Bordered band. Left: eyebrow "Karriere & Jobs", H2 "Fahren Sie mit uns", paragraph "Wir suchen Busfahrer:innen, Begleitpersonen und Sachbearbeiter:innen — steigen Sie ein." - Right: white button **"Offene Stellen →"** (`mailto:info@unger-reisen.de`). ### 10. Footer - 3-column grid on `--ink`, hairline top border: - Logo + blurb: "Günter Unger e.K. — Omnibus- & Verkehrsunternehmen. Reisen erster Klasse aus Niederbayern." - **Hauptsitz**: Eichenstr. 7+9, Vatersdorf · 84172 Buch am Erlbach · Tel. +49 (0)8762 / 896 - **Niederlassung**: Jenaer Straße 4a · 84034 Landshut · Tel. +49 (0)871 / 96 58 586-0 - Bottom bar: "© 2026 Unger Reisen · Alle Rechte vorbehalten" + Impressum / Datenschutz / AGB. - Small disclaimer: "Konzept-Entwurf für ein mögliches Website-Redesign · noch nicht offiziell." (**Remove this line** once it's the real site.) --- ## Interactions & Behavior - **Nav solidify on scroll** (>40px) — see §2. - **Scroll-driven bus** across hero — see §3. Core formula: `hp = clamp(scrollY/(heroHeight*0.9),0,1)`; `x = lerp(-busW*0.3, sceneW - busW*0.7, hp)`. - **Reveal on scroll**: elements marked for reveal start `opacity:0; translateY(28px)` and animate to `opacity:1; none` via IntersectionObserver (threshold ~0.12), transition `.7s cubic-bezier(.2,.7,.2,1)`. Provide a safety fallback that reveals everything after ~2.5s. - **Marquee / hills / stripes / wheels**: continuous CSS keyframe loops (see §1, §3). - **Buttons/links hover**: `translateY(-2px)` or border color → white. - **Map**: pan/zoom via drag + control buttons; scroll-zoom disabled; compass resets bearing. - **Smooth anchor scrolling** for nav links (`scroll-behavior: smooth`) to `#leistungen`, `#flotte`, `#karriere`, `#kontakt`, `#top`. - **Reduced motion**: disable all decorative animation; keep static end states. ## State Management Minimal — the page is largely presentational. In a component framework you need: - Nav-scrolled boolean (or do it with a scroll listener / IntersectionObserver on a sentinel). - The bus `x`/`bob` transform driven by a scroll + rAF loop (a ref + effect). - Reveal-on-scroll via IntersectionObserver (a small reusable hook/directive). - The MapLibre instance held in a ref; init in mount effect, `remove()` on unmount. - Data arrays for **stats**, **services**, **fleet** (see copy above) — render with `.map`. - (An earlier version had a controlled contact form; it was **removed** in favor of call/email CTAs. If you re-add a form, wire name/contact/dest/date/pax/message + a submitted state.) ## Configurable knobs (from the prototype's props) - **accentColor** — the red. Default `#C8102E`; options `#E4002B / #D21F1F / #C8102E / #EE3524`. Applied as a CSS variable `--red`; also recolors the map route on change. Expose as a theme token in the real app. ## Assets - **Fonts:** Anton + Archivo (Google Fonts) — see import above. - **Icons:** none required (all visuals are CSS/SVG-drawn or map markers). The original shadcn map component referenced `lucide-react` for map control icons — use those (Plus, Minus, Locate, Maximize, Compass/X) if you build custom controls; MapLibre's built-in `NavigationControl` needs no icon assets. - **Bus hero photo (§6):** placeholder points at unger-reisen.de. **Replace with an owned or licensed photo** of an Unger coach. If you need a temporary stand-in, use a royalty-free coach photo (e.g. an Unsplash coach/bus image) and swap later. - **Map:** MapLibre GL JS + CSS (npm `maplibre-gl`), Carto "dark-matter" style (free, attribution required — keep the attribution control). Tiles fetched at runtime. - **No logo file** — the "UNGER REISEN" logo is set in type (Anton + Archivo). ## Files - `Unger Reisen.dc.html` — the full design prototype (all sections, styles, and JS behavior). Read the `` body for structure/markup, the `