diff --git a/saas-app/app/Modules/Central/Controllers/LandingController.php b/saas-app/app/Modules/Central/Controllers/LandingController.php index 695122a..2b9b0af 100644 --- a/saas-app/app/Modules/Central/Controllers/LandingController.php +++ b/saas-app/app/Modules/Central/Controllers/LandingController.php @@ -4,25 +4,36 @@ declare(strict_types=1); namespace App\Modules\Central\Controllers; -use App\Modules\Identity\Services\AuthService; -use App\Modules\Tenants\Services\TenantService; - class LandingController { - public function __construct( - private readonly TenantService $tenantService, - private readonly AuthService $authService - ) { - } - public function index(): array { return [ 'view' => 'welcome', 'data' => [ - 'title' => 'Kaffeeliste SaaS', - 'tenantOverview' => $this->tenantService->adminOverview(), - 'centralLoginPreview' => $this->authService->centralLoginPreview(), + 'title' => 'Die Kaffeeliste', + 'landingColumns' => [ + [ + 'eyebrow' => 'Für Mitglieder', + 'title' => 'Schnell im Alltag', + 'copy' => 'Anmelden, Überblick sehen und direkt weitermachen.', + ], + [ + 'eyebrow' => 'Für Verantwortliche', + 'title' => 'Einfach verwalten', + 'copy' => 'Mitglieder, Bereiche und Abläufe an einem Ort.', + ], + [ + 'eyebrow' => 'Für Teams', + 'title' => 'Klar für alle', + 'copy' => 'Eine gemeinsame Kaffeeliste mit verständlicher Oberfläche.', + ], + ], + 'landingPreview' => [ + ['label' => 'Schneller Überblick', 'value' => 'Direkt sichtbar'], + ['label' => 'Für Mitglieder', 'value' => 'Einfach nutzbar'], + ['label' => 'Für Verantwortliche', 'value' => 'Klar verwaltet'], + ], ], ]; } diff --git a/saas-app/public/index.php b/saas-app/public/index.php index 4198ad4..1d3d227 100644 --- a/saas-app/public/index.php +++ b/saas-app/public/index.php @@ -71,7 +71,6 @@ if ($page === 'logout' && $requestMethod === 'POST') { app_redirect('/'); } -$marketing = app_marketing_messages(); $flash = app_flash(); $auth = app_auth_user(); $pdo = null; @@ -223,7 +222,31 @@ if ($auth !== null && isset($restrictedPages[$page]) && !$restrictedPages[$page] $canManageTenant = app_can_manage_tenant($auth); $tenantNavItems = app_tenant_navigation_items($auth, $tenantLicense); +$guestNavItems = [ + ['key' => 'home', 'href' => '/', 'label' => 'Start'], + ['key' => 'login', 'href' => '/login/', 'label' => 'Anmeldung'], + ['key' => 'tenants', 'href' => '/admin/login/', 'label' => 'Admin'], +]; +$primaryNavItems = $auth === null ? $guestNavItems : $tenantNavItems; +$currentNavLabel = 'Start'; +foreach ($primaryNavItems as $item) { + if ($page === (string) ($item['key'] ?? '')) { + $currentNavLabel = (string) ($item['label'] ?? $currentNavLabel); + break; + } +} $themeCss = app_tenant_theme_root_css($tenantSettings); +$isMarketingHome = $page === 'home' && $auth === null; +$landingColumns = [ + ['eyebrow' => 'Für Mitglieder', 'title' => 'Schnell starten', 'copy' => 'Einloggen und direkt weiter.'], + ['eyebrow' => 'Für Verantwortliche', 'title' => 'Alles im Blick', 'copy' => 'Bereiche, Hinweise und Verwaltung an einem Ort.'], + ['eyebrow' => 'Für Standorte', 'title' => 'Gemeinsam organisiert', 'copy' => 'Ein klarer Ablauf für Teams und Bereiche.'], +]; +$landingPreview = [ + ['label' => 'Start', 'value' => 'Klar'], + ['label' => 'Team', 'value' => 'Gemeinsam'], + ['label' => 'Zugang', 'value' => 'Direkt'], +]; ?> @@ -237,104 +260,248 @@ $themeCss = app_tenant_theme_root_css($tenantSettings); body{margin:0;min-height:100vh;font-family:"Aptos","Segoe UI",sans-serif;color:var(--ink);background:linear-gradient(180deg,#f9f6ef 0%,var(--bg) 100%)} a{color:inherit;text-decoration:none} h1,h2,h3{font-family:Georgia,serif;letter-spacing:-.02em} - .button,button{display:inline-flex;align-items:center;justify-content:center;padding:10px 14px;border-radius:999px;border:1px solid transparent;background:var(--brand);color:#fff;font:inherit;font-weight:700;cursor:pointer} + .button,button{display:inline-flex;align-items:center;justify-content:center;padding:10px 14px;border-radius:12px;border:1px solid transparent;background:var(--brand);color:#fff;font:inherit;font-weight:700;cursor:pointer} .button.secondary,.button--ghost{background:#fff;color:var(--brand);border-color:rgba(var(--brand-rgb),.18)} - .page-shell{width:min(1460px,calc(100vw - 32px));margin:20px auto 40px;display:grid;grid-template-columns:minmax(280px,300px) minmax(0,1fr);gap:20px;align-items:start} - .sidebar,.hero,.card,.alert{border:1px solid var(--line);border-radius:var(--radius);background:var(--card);box-shadow:var(--shadow)} - .sidebar{position:sticky;top:20px;display:grid;gap:16px;padding:18px;background:rgba(255,251,244,.96)} - .sidebar__brand{display:grid;gap:6px;padding-bottom:14px;border-bottom:1px solid rgba(37,24,15,.1)} + .page-shell{width:min(1320px,calc(100vw - 32px));margin:18px auto 34px;display:grid;gap:16px} + .site-header{position:sticky;top:18px;z-index:20} + .site-header__inner{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:16px 18px;border:1px solid var(--line);border-radius:24px;background:rgba(255,255,255,.94);box-shadow:var(--shadow)} + .site-brand{display:flex;align-items:center;gap:14px;min-width:0} + .site-brand__mark{width:44px;height:44px;border-radius:16px;display:grid;place-items:center;background:linear-gradient(135deg,var(--brand) 0%,var(--brand-strong) 100%);color:#fff;font-weight:800;box-shadow:0 14px 28px rgba(var(--brand-rgb),.18)} + .site-brand__title{margin:0;font-size:1.1rem;color:var(--ink)} + .site-brand__subtitle{margin:2px 0 0;color:var(--muted);font-size:.92rem} + .site-nav,.site-actions,.actions,.context{display:flex;flex-wrap:wrap;gap:10px;align-items:center} + .site-nav__link{display:inline-flex;align-items:center;justify-content:center;padding:10px 14px;border-radius:999px;border:1px solid transparent;background:transparent;color:var(--muted);font-weight:700} + .site-nav__link:hover{text-decoration:none;color:var(--brand);background:rgba(255,255,255,.82);border-color:rgba(var(--brand-rgb),.14)} + .site-nav__link.active{background:rgba(var(--brand-rgb),.10);color:var(--brand);border-color:rgba(var(--brand-rgb),.18)} + .site-mobile{display:none;position:relative} + .site-mobile[open]{z-index:20} + .site-toggle{display:flex;align-items:center;justify-content:space-between;gap:12px;cursor:pointer;list-style:none;padding:12px 14px;border-radius:16px;border:1px solid rgba(var(--brand-rgb),.12);background:#fff;color:var(--brand);font-weight:700} + .site-toggle::-webkit-details-marker{display:none} + .site-toggle::after{content:"";width:11px;height:11px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg);transition:transform .2s ease} + .site-mobile[open] .site-toggle::after{transform:rotate(225deg)} + .site-panel{position:absolute;right:0;top:calc(100% + 12px);width:min(320px,calc(100vw - 32px));padding:14px;border-radius:18px;border:1px solid var(--line);background:#fffdf9;box-shadow:var(--shadow)} + .site-stack{display:grid;gap:10px} + .site-stack .site-nav__link{justify-content:flex-start;background:rgba(255,255,255,.78);border-color:rgba(37,24,15,.08);color:var(--ink)} + .site-footer-actions{display:flex;justify-content:flex-end;margin-top:12px} + .hero,.card,.alert{border:1px solid var(--line);border-radius:var(--radius);background:var(--card);box-shadow:var(--shadow)} .sidebar__eyebrow,.eyebrow{display:inline-block;color:var(--accent);text-transform:uppercase;letter-spacing:.14em;font-size:.8rem;font-weight:800} .sidebar__eyebrow{margin:0} - .sidebar__title{margin:0;font-size:1.55rem;line-height:1.05} + .sidebar__title{margin:0;font-size:1.32rem;line-height:1.04} .sidebar__subtitle,.muted,p{color:var(--muted)} - .sidebar__meta,.actions,.context{display:flex;flex-wrap:wrap;gap:10px;align-items:center} - .sidebar__section{display:inline-block;color:var(--accent);text-transform:uppercase;letter-spacing:.14em;font-size:.76rem;font-weight:800} - .sidebar__nav,.sidebar__stack,.stack{display:grid;gap:10px} - .sidebar__link{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;border-radius:16px;border:1px solid rgba(var(--brand-rgb),.12);background:#fff;color:var(--brand);font-weight:700} - .sidebar__link.active{background:var(--brand);color:#fff} - .sidebar__footer{display:grid;gap:12px;padding-top:14px;border-top:1px solid rgba(37,24,15,.1)} - .sidebar__mobile{display:none} - .sidebar__mobile[open]{z-index:20} - .sidebar__toggle{display:flex;align-items:center;justify-content:space-between;gap:12px;cursor:pointer;list-style:none;padding:12px 14px;border-radius:16px;border:1px solid rgba(var(--brand-rgb),.12);background:#fff;color:var(--brand);font-weight:700} - .sidebar__toggle::-webkit-details-marker{display:none} - .sidebar__toggle::after{content:"";width:11px;height:11px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg);transition:transform .2s ease} - .sidebar__mobile[open] .sidebar__toggle::after{transform:rotate(225deg)} - .sidebar__panel{margin-top:12px;padding:14px;border-radius:18px;border:1px solid var(--line);background:#fffdf9;box-shadow:var(--shadow)} - .content{min-width:0;display:grid;gap:18px} - .hero,.card{padding:24px} - .hero{margin-bottom:0;background:linear-gradient(180deg,#fffdf8 0%,#f9f4ea 100%)} + .content{min-width:0;display:grid;gap:16px} + .hero,.card{padding:20px} + .hero{margin-bottom:0;background:rgba(255,255,255,.9)} .grid{display:grid;gap:18px}.grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-4{grid-template-columns:repeat(4,minmax(0,1fr))} - h1{font-size:clamp(2rem,4vw,3.2rem);margin:0 0 12px}h2{font-size:1.35rem;margin:0 0 12px}h3{font-size:1.05rem;margin:0 0 10px}p{margin:0;line-height:1.6} - .metric{padding:18px;border:1px solid var(--line);border-radius:16px;background:#fff}.metric strong{display:block;font-size:1.8rem;margin-bottom:8px} + h1{font-size:clamp(1.9rem,4vw,2.8rem);margin:0 0 10px}h2{font-size:1.2rem;margin:0 0 10px}h3{font-size:1rem;margin:0 0 8px}p{margin:0;line-height:1.55} + .metric{padding:18px;border:1px solid var(--line);border-radius:16px;background:#fff}.metric strong{display:block;font-size:1.55rem;margin-bottom:6px} .list{margin:14px 0 0;padding-left:18px;color:var(--muted);line-height:1.7} .alert{padding:16px 18px;margin-bottom:0}.alert-success{background:rgba(var(--brand-rgb),.08)}.alert-warning{background:rgba(var(--accent-rgb),.1)}.alert-error{background:rgba(154,31,31,.1)}.alert-info{background:rgba(var(--brand-rgb),.08)} .badge{display:inline-flex;align-items:center;padding:7px 12px;border-radius:999px;font-size:.86rem;font-weight:700} .badge-neutral{background:rgba(var(--brand-rgb),.08);color:var(--brand)}.badge-success{background:rgba(var(--brand-rgb),.12);color:var(--brand)}.badge-warning{background:rgba(var(--accent-rgb),.14);color:#8c6500} - .table{overflow-x:auto}.table table{width:100%;border-collapse:collapse;min-width:720px}.table th,.table td{padding:13px 10px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}.table th{font-size:.85rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)} + .table{overflow-x:auto}.table table{width:100%;border-collapse:collapse;min-width:720px}.table th,.table td{padding:12px 10px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}.table th{font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)} form.grid{grid-template-columns:repeat(2,minmax(0,1fr))}label{display:flex;flex-direction:column;gap:8px;font-weight:700}input,select,textarea{width:100%;padding:12px 14px;border-radius:14px;border:1px solid rgba(37,24,15,.15);font:inherit;background:#fff;color:var(--ink)}textarea{min-height:120px} .footer{margin-top:0;text-align:center;color:var(--muted);font-size:.92rem} - @media(max-width:960px){.page-shell{grid-template-columns:1fr;width:min(100vw - 20px,1460px)}.sidebar{position:static}.sidebar__desktop{display:none}.sidebar__mobile{display:block}.grid-2,.grid-3,.grid-4,form.grid{grid-template-columns:1fr}.table table{min-width:0}} - @media(min-width:961px){.sidebar__mobile{display:none}} + .section-mini{display:grid;gap:10px} + .section-mini__title{margin:0;font-size:1rem;color:var(--ink)} + .section-mini__copy{margin:0;color:var(--muted)} + body.landing-preview{background:radial-gradient(circle at top center,rgba(88,122,255,.22),transparent 28%),radial-gradient(circle at 20% 20%,rgba(42,72,170,.18),transparent 24%),linear-gradient(180deg,#05070d 0%,#0a0f1a 52%,#0d1320 100%);color:#f4f7ff} + body.landing-preview h1,body.landing-preview h2,body.landing-preview h3{font-family:"Inter Tight","Aptos","Segoe UI",sans-serif;letter-spacing:-.04em} + .marketing-shell{min-height:100vh;padding:0 0 92px;display:grid;gap:12px} + .marketing-main{width:min(1240px,calc(100vw - 48px));margin:0 auto} + .marketing-bar{position:sticky;top:0;z-index:20;display:flex;align-items:center;justify-content:space-between;gap:14px;height:88px;min-height:88px;width:100%;margin:0 0 20px;padding:0 18px;border:0;border-bottom:1px solid rgba(137,154,188,.18);border-radius:0;background:rgba(8,10,18,.82);box-shadow:none;backdrop-filter:blur(16px)} + .marketing-brand{display:flex;align-items:center;gap:8px;flex:0 0 auto} + .marketing-brand__mark{width:40px;height:40px;border-radius:10px;display:grid;place-items:center;background:linear-gradient(135deg,#587aff 0%,#243a91 100%);color:#fff;font-size:1rem;font-weight:800;box-shadow:none} + .marketing-brand__title{margin:0;font-size:1.08rem;line-height:1;color:#f4f7ff} + .marketing-brand__copy{display:none} + .marketing-nav,.marketing-actions,.landing-actions{display:flex;flex-wrap:wrap;gap:12px;align-items:center} + .marketing-nav{gap:6px} + .marketing-nav a{display:inline-flex;align-items:center;justify-content:center;min-height:36px;padding:0 .3rem;border-radius:6px;border:1px solid transparent;font-size:1rem;font-weight:600;color:rgba(231,238,255,.8)} + .marketing-nav a:hover{text-decoration:none;color:#f4f7ff;background:rgba(255,255,255,.06);border-color:rgba(201,214,255,.12)} + .marketing-actions .button{min-height:38px;padding:.42rem .8rem;border-radius:8px;font-size:.94rem} + .marketing-actions .button.secondary,.marketing-mobile__footer .button.secondary{background:transparent;color:#f4f7ff;border-color:rgba(201,214,255,.16);box-shadow:none} + .marketing-mobile{display:none;position:relative} + .marketing-mobile[open]{z-index:40} + .marketing-mobile__toggle{display:inline-flex;align-items:center;justify-content:center;gap:10px;list-style:none;cursor:pointer;min-width:38px;min-height:38px;padding:.24rem .46rem;border-radius:8px;border:1px solid rgba(201,214,255,.14);background:rgba(255,255,255,.04);color:#f4f7ff} + .marketing-mobile__toggle::-webkit-details-marker{display:none} + .marketing-mobile__toggle::before{content:"";width:16px;height:10px;border-top:2px solid currentColor;border-bottom:2px solid currentColor;box-shadow:inset 0 -4px 0 0 currentColor} + .marketing-mobile__panel{position:absolute;right:0;top:calc(100% + 10px);width:min(280px,calc(100vw - 24px));padding:14px;border-radius:16px;border:1px solid rgba(163,183,255,.14);background:rgba(8,10,18,.96);box-shadow:0 18px 36px rgba(1,5,13,.45)} + .marketing-mobile__stack{display:grid;gap:8px} + .marketing-mobile__stack .marketing-nav__link{justify-content:flex-start;padding:.55rem .7rem;background:rgba(255,255,255,.04);border-color:rgba(201,214,255,.1)} + .marketing-mobile__footer{margin-top:12px;display:flex;justify-content:flex-end} + .landing-hero{width:min(1240px,calc(100vw - 48px));margin:0 auto;padding-top:12px;display:grid;grid-template-columns:minmax(0,1.08fr) minmax(280px,.92fr);gap:40px;align-items:start} + .landing-copy__eyebrow{margin:0 0 10px;text-transform:uppercase;letter-spacing:.16em;font-size:.78rem;font-weight:700;color:#8aa0d0} + .landing-copy h1{margin:0;font-size:clamp(3.2rem,7vw,6.4rem);line-height:.9;letter-spacing:-.06em;color:#f4f7ff} + .landing-copy p{margin:14px 0 0;color:rgba(219,228,248,.72);font-size:1.05rem;max-width:30rem;line-height:1.65} + .landing-actions{margin-top:24px} + .landing-visual,.landing-callout{border:1px solid rgba(163,183,255,.12);border-radius:20px;background:rgba(14,20,34,.86);box-shadow:0 16px 40px rgba(2,5,12,.34)} + .landing-visual{padding:20px;display:grid;gap:12px} + .landing-visual__top{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:12px;border-bottom:1px solid rgba(163,183,255,.12)} + .landing-visual__title{margin:0;font-size:1.1rem;color:#f4f7ff} + .landing-visual__stack{display:grid;gap:12px} + .landing-visual__row{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:12px 14px;border-radius:16px;background:rgba(255,255,255,.04);color:rgba(216,225,246,.72);font-weight:600} + .landing-visual__row strong{color:#f4f7ff} + .landing-columns{width:min(1240px,calc(100vw - 48px));margin:0 auto;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0;border-top:1px solid rgba(163,183,255,.12);border-bottom:1px solid rgba(163,183,255,.12)} + .landing-column{padding:24px 18px} + .landing-column + .landing-column{border-left:1px solid rgba(163,183,255,.12)} + .landing-column__eyebrow{margin:0 0 10px;color:#8aa0d0;font-size:.78rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase} + .landing-column h2{margin:0 0 10px;font-size:1.45rem;color:#f4f7ff} + .landing-column p{margin:0;max-width:22rem;color:rgba(219,228,248,.72)} + .landing-callout{width:min(1240px,calc(100vw - 48px));margin:0 auto;padding:24px 26px} + .landing-callout__eyebrow{margin:0 0 8px;color:#8aa0d0;font-size:.78rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase} + .landing-callout h2{margin:0 0 10px;font-size:2rem;color:#f4f7ff} + .landing-callout p{margin:0;max-width:36rem;color:rgba(217,226,246,.8)} + .landing-cta{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:16px;padding-top:20px;margin-top:22px;border-top:1px solid rgba(163,183,255,.12)} + .landing-cta__copy{display:grid;gap:6px} + .landing-cta__copy strong{font-size:1.05rem;color:#f4f7ff} + .landing-cta__copy span{color:rgba(217,226,246,.72)} + .marketing-footer{position:fixed;left:0;right:0;bottom:0;z-index:25;margin-top:0;padding:10px 24px;border-top:1px solid rgba(137,154,188,.14);background:rgba(8,10,18,.88);backdrop-filter:blur(18px);color:rgba(209,217,235,.68);font-size:.92rem} + .marketing-footer__inner{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;width:min(1240px,calc(100% - 48px));margin:0 auto} + @media(max-width:960px){.marketing-main,.landing-hero,.landing-columns,.landing-callout{width:calc(100vw - 24px)}.marketing-bar{height:72px;min-height:72px;margin:0 0 16px;padding:0 12px}.marketing-nav,.marketing-actions{display:none}.marketing-mobile{display:block}.landing-hero,.landing-columns{grid-template-columns:1fr}.landing-hero{gap:24px;padding-top:0}.landing-column{padding:20px 0}.landing-column + .landing-column{border-left:0;border-top:1px solid rgba(163,183,255,.12)}.landing-callout{padding:20px}.marketing-shell{padding:0 0 88px}.marketing-footer{padding:10px 12px}.marketing-footer__inner{width:100%}} + @media(max-width:960px){.page-shell{width:min(100vw - 20px,1460px)}.site-header__inner{align-items:flex-start;padding:14px 16px}.site-nav{display:none}.site-mobile{display:block}.grid-2,.grid-3,.grid-4,form.grid{grid-template-columns:1fr}.table table{min-width:0}} + @media(min-width:961px){.site-mobile{display:none}} -
-