feat(website): book-a-demo & status pages, expand roadmap/contact

- /demo: book-a-demo page with a what-to-expect column + a form that
  composes a prefilled email to info@dezky.eu (interim, no backend); built
  to swap for a self-hosted scheduler later. Wire every "Book a demo" CTA
  (nav, hero, pricing, the previously-dead final-CTA button, and the
  contact/partners/migration/coming-soon CTAs) to /demo.
- /status: manually-maintained system-status page (overall banner,
  per-service rows, incident history). Live modules operational; Video/Chat
  marked coming soon.
- Roadmap: expand the board (5 items/column) + a "the bigger picture"
  themes grid + a "suggest a feature" CTA + a directional-timelines note.
- Contact: purpose-specific channels (info@ / legal@ / privacy@), a
  response-time note, and a company + "see it live" demo block.
- Drop /status from the [slug].vue stub map; tidy now-unused imports.
This commit is contained in:
Ronni Baslund
2026-06-06 19:19:19 +02:00
parent 3347fa9265
commit d2096eb847
13 changed files with 427 additions and 48 deletions
@@ -2,18 +2,16 @@
// Placeholder body for not-yet-built sub-pages. Shows the page title under a
// "coming soon" eyebrow, an explanatory line, and a demo CTA. Legal pages pass
// the legal-specific body instead of the generic one.
import { useRoute } from 'vue-router'
import { useCopy, goToSection } from '~/composables/useLanding'
import { useCopy } from '~/composables/useLanding'
defineProps<{ title: string, body: string }>()
const copy = useCopy()
const route = useRoute()
</script>
<template>
<LandingPageHeader :label="copy.pages.comingSoonKicker" :title="title" :intro="body" />
<LandingContainer pad="clamp(32px, 5vw, 48px) clamp(20px, 5vw, 64px) clamp(56px, 8vw, 160px)">
<LandingBtn variant="primary" size="lg" @click="goToSection('#final-cta', route.path)">{{ copy.pages.ctaDemo }} </LandingBtn>
<LandingBtn variant="primary" size="lg" @click="navigateTo('/demo')">{{ copy.pages.ctaDemo }} </LandingBtn>
</LandingContainer>
</template>
+2 -2
View File
@@ -14,13 +14,13 @@ const copy = useCopy()
<LandingContainer pad="clamp(56px, 8vw, 140px) clamp(20px, 5vw, 64px)">
<h2 :style="{ fontFamily: '\'Inter Tight\', sans-serif', fontWeight: 600, fontSize: 'clamp(32px, 6vw, 96px)', letterSpacing: '-0.04em', lineHeight: 0.98, margin: 0, color: C.bone, textWrap: 'balance', maxWidth: '900px' }">
<template v-for="(part, i) in copy.finalCta.heading" :key="i">
<template v-if="typeof part === 'string'">{{ part }} </template>
<template v-if="typeof part === 'string'">{{ part }} </template>
<span v-else :style="{ color: C.signal }">{{ part.hl }}</span>
</template>
</h2>
<div :style="{ marginTop: '28px', maxWidth: 'min(100%, 520px)', fontFamily: '\'Inter\', sans-serif', fontSize: '19px', color: 'rgba(244,243,238,0.7)' }">{{ copy.finalCta.sub }}</div>
<div :style="{ marginTop: '40px' }">
<button :style="{
<button @click="navigateTo('/demo')" :style="{
background: C.signal, color: C.carbon, border: 'none',
padding: '20px 32px', fontFamily: '\'Inter\', sans-serif',
fontSize: '16px', fontWeight: 600, borderRadius: '4px', cursor: 'pointer',
+1 -1
View File
@@ -46,7 +46,7 @@ const brush = {
</div>
<div :style="{ display: 'flex', gap: '12px', marginTop: '40px', flexWrap: 'wrap' }">
<LandingBtn variant="primary" size="lg">{{ copy.hero.cta }} </LandingBtn>
<LandingBtn variant="primary" size="lg" @click="navigateTo('/demo')">{{ copy.hero.cta }} </LandingBtn>
<LandingBtn variant="secondary" size="lg">{{ copy.hero.sub_cta }}</LandingBtn>
</div>
+3 -3
View File
@@ -4,7 +4,7 @@
import { computed, ref } from 'vue'
import { useRoute } from 'vue-router'
import { APP_URL } from '~/utils/landingTokens'
import { useTheme, useCopy, useLang, toggleLang, scrollToAnchor, goToSection } from '~/composables/useLanding'
import { useTheme, useCopy, useLang, toggleLang, scrollToAnchor } from '~/composables/useLanding'
const t = useTheme()
const copy = useCopy()
@@ -81,7 +81,7 @@ function onMobileLink(e: MouseEvent, href: string) {
@click="toggleLang()"
>{{ lang === 'da' ? 'da · en' : 'en · da' }}</button>
<a :href="APP_URL" :style="{ fontFamily: '\'Inter\', sans-serif', fontSize: '14px', color: t.fgMuted }">{{ copy.nav.login }}</a>
<LandingBtn variant="primary" @click="goToSection('#final-cta', route.path)">{{ copy.nav.cta }} </LandingBtn>
<LandingBtn variant="primary" @click="navigateTo('/demo')">{{ copy.nav.cta }} </LandingBtn>
</div>
<!-- Hamburger visible only on mobile via scoped CSS -->
@@ -155,7 +155,7 @@ function onMobileLink(e: MouseEvent, href: string) {
:style="{ fontFamily: '\'Inter\', sans-serif', fontSize: '14px', color: t.fgMuted }"
@click="mobileOpen = false"
>{{ copy.nav.login }}</a>
<LandingBtn variant="primary" @click="() => { goToSection('#final-cta', route.path); mobileOpen = false }">{{ copy.nav.cta }} </LandingBtn>
<LandingBtn variant="primary" @click="() => { navigateTo('/demo'); mobileOpen = false }">{{ copy.nav.cta }} </LandingBtn>
</div>
</div>
</header>
+1 -1
View File
@@ -17,7 +17,7 @@ const copy = useCopy()
<p :style="{ fontFamily: '\'Inter\', sans-serif', fontSize: '20px', lineHeight: 1.5, maxWidth: '640px', color: t.fgMuted, margin: 0, textWrap: 'pretty' }">{{ copy.pricing.lede }}</p>
</div>
<div :style="{ marginTop: '36px', display: 'flex', alignItems: 'center', gap: '16px' }">
<LandingBtn variant="primary" size="lg">{{ copy.pricing.cta }} </LandingBtn>
<LandingBtn variant="primary" size="lg" @click="navigateTo('/demo')">{{ copy.pricing.cta }} </LandingBtn>
</div>
</div>
<div :style="{ background: t.surface, border: `1px solid ${t.border}`, borderRadius: '6px', padding: '36px 36px' }">