SEO/AEO, Farb schema, breadcrumbs
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
<header class="w-full flex justify-between items-center p-4 bg-white top-0 z-10 h-16 md:h-20">
|
||||
<img src="assets/images/header-logo.png" alt="Logo" class="h-8 md:h-10" />
|
||||
<img src="assets/images/header-logo.png" alt="Logo" class="h-8 md:h-10" width="150" height="40" />
|
||||
<div class="hidden md:flex items-center space-x-4">
|
||||
@if(user){
|
||||
<a routerLink="/account" class="text-blue-600 border border-blue-600 px-3 py-2 rounded">Account</a>
|
||||
<a routerLink="/account" class="text-primary-600 border border-primary-600 px-3 py-2 rounded">Account</a>
|
||||
} @else {
|
||||
<!-- <a routerLink="/pricing" class="text-gray-800">Pricing</a> -->
|
||||
<a routerLink="/login" [queryParams]="{ mode: 'login' }" class="text-blue-600 border border-blue-600 px-3 py-2 rounded">Log In</a>
|
||||
<a routerLink="/login" [queryParams]="{ mode: 'register' }" class="text-white bg-blue-600 px-4 py-2 rounded">Register</a>
|
||||
<!-- <a routerLink="/login" class="text-blue-500 hover:underline">Login/Register</a> -->
|
||||
<!-- <a routerLink="/pricing" class="text-neutral-800">Pricing</a> -->
|
||||
<a routerLink="/login" [queryParams]="{ mode: 'login' }" class="text-primary-600 border border-primary-600 px-3 py-2 rounded">Log In</a>
|
||||
<a routerLink="/login" [queryParams]="{ mode: 'register' }" class="text-white bg-primary-600 px-4 py-2 rounded">Register</a>
|
||||
<!-- <a routerLink="/login" class="text-primary-500 hover:underline">Login/Register</a> -->
|
||||
}
|
||||
</div>
|
||||
<button (click)="toggleMenu()" class="md:hidden text-gray-600">
|
||||
<button (click)="toggleMenu()" class="md:hidden text-neutral-600">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h16m-7 6h7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<div *ngIf="isMenuOpen" class="fixed inset-0 bg-gray-800 bg-opacity-75 z-20">
|
||||
<div *ngIf="isMenuOpen" class="fixed inset-0 bg-neutral-800 bg-opacity-75 z-20">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<!-- <a href="#" class="text-white text-xl py-2">Pricing</a> -->
|
||||
@if(user){
|
||||
@@ -38,7 +38,7 @@
|
||||
<!-- 1. px-4 für <main> (vorher px-2 sm:px-4) -->
|
||||
<main class="flex flex-col items-center justify-center px-4 w-full flex-grow">
|
||||
<div
|
||||
class="bg-cover-custom pb-12 md:py-20 flex flex-col w-full rounded-xl lg:rounded-2xl md:drop-shadow-custom-md lg:drop-shadow-custom-lg min-h-[calc(100vh_-_20rem)] lg:min-h-[calc(100vh_-_10rem)] max-sm:bg-contain max-sm:bg-bottom max-sm:bg-no-repeat max-sm:min-h-[calc(100vh_-_7rem)] max-sm:bg-blue-600"
|
||||
class="bg-cover-custom pb-12 md:py-20 flex flex-col w-full rounded-xl lg:rounded-2xl md:drop-shadow-custom-md lg:drop-shadow-custom-lg min-h-[calc(100vh_-_20rem)] lg:min-h-[calc(100vh_-_10rem)] max-sm:bg-contain max-sm:bg-bottom max-sm:bg-no-repeat max-sm:min-h-[60vh] max-sm:bg-primary-600"
|
||||
>
|
||||
<div class="flex justify-center w-full">
|
||||
<!-- 3. Für Mobile: m-2 statt max-w-xs; ab sm: wieder max-width und kein Margin -->
|
||||
@@ -52,27 +52,29 @@
|
||||
|
||||
<!-- 2) Textblock -->
|
||||
<div class="relative z-10 mx-auto max-w-4xl px-6 sm:px-6 py-4 sm:py-16 text-center text-white">
|
||||
<h1 class="text-[1.55rem] sm:text-4xl md:text-5xl lg:text-6xl font-extrabold tracking-tight leading-tight drop-shadow-[0_2px_6px_rgba(0,0,0,0.55)]">Find businesses for Sale</h1>
|
||||
<h1 class="text-[1.55rem] sm:text-4xl md:text-5xl lg:text-6xl font-extrabold tracking-tight leading-tight drop-shadow-[0_2px_6px_rgba(0,0,0,0.55)]">Buy & Sell Businesses and Commercial Properties</h1>
|
||||
|
||||
<p class="mt-3 sm:mt-4 text-base sm:text-lg md:text-xl lg:text-2xl font-medium text-white/90 drop-shadow-[0_1.5px_4px_rgba(0,0,0,0.6)]">Unlocking Opportunities - Empowering Entrepreneurial Dreams</p>
|
||||
<p class="mt-3 sm:mt-4 text-base sm:text-lg md:text-xl lg:text-2xl font-medium text-white/90 drop-shadow-[0_1.5px_4px_rgba(0,0,0,0.6)]">Find profitable businesses for sale, commercial real estate, and franchise opportunities across the United States</p>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Restliche Anpassungen (Innenabstände, Button-Paddings etc.) bleiben wie im vorherigen Schritt -->
|
||||
<div class="bg-white bg-opacity-80 pb-4 md:pb-6 pt-2 px-3 sm:px-4 md:px-6 rounded-lg shadow-lg w-full" [ngClass]="{ 'pt-6': aiSearch }">
|
||||
<div class="search-form-container bg-white bg-opacity-80 pb-4 md:pb-6 pt-2 px-3 sm:px-4 md:px-6 rounded-lg shadow-lg w-full" [ngClass]="{ 'pt-6': aiSearch }">
|
||||
@if(!aiSearch){
|
||||
<div class="text-sm lg:text-base mb-1 text-center text-gray-500 border-gray-200 dark:text-gray-400 dark:border-gray-700 flex justify-between">
|
||||
<div class="text-sm lg:text-base mb-1 text-center text-neutral-500 border-neutral-200 dark:text-neutral-400 dark:border-neutral-700 flex justify-between">
|
||||
<ul class="flex flex-wrap -mb-px w-full">
|
||||
<li class="w-[33%]">
|
||||
<a
|
||||
(click)="changeTab('business')"
|
||||
[ngClass]="
|
||||
activeTabAction === 'business'
|
||||
? ['text-blue-600', 'border-blue-600', 'active', 'dark:text-blue-500', 'dark:border-blue-500']
|
||||
: ['border-transparent', 'hover:text-gray-600', 'hover:border-gray-300', 'dark:hover:text-gray-300']
|
||||
? ['text-primary-600', 'border-primary-600', 'active', 'dark:text-primary-500', 'dark:border-primary-500']
|
||||
: ['border-transparent', 'hover:text-neutral-600', 'hover:border-neutral-300', 'dark:hover:text-neutral-300']
|
||||
"
|
||||
class="hover:cursor-pointer inline-block px-1 py-2 md:p-4 border-b-2 rounded-t-lg"
|
||||
>Businesses</a
|
||||
class="tab-link hover:cursor-pointer inline-flex items-center justify-center px-1 py-2 md:p-4 border-b-2 rounded-t-lg"
|
||||
>
|
||||
<img src="assets/images/business_logo.png" alt="Search businesses for sale" class="tab-icon w-6 h-6 md:w-7 md:h-7 mr-1 md:mr-2 object-contain" />
|
||||
<span>Businesses</span>
|
||||
</a>
|
||||
</li>
|
||||
@if ((numberOfCommercial$ | async) > 0) {
|
||||
<li class="w-[33%]">
|
||||
@@ -80,35 +82,38 @@
|
||||
(click)="changeTab('commercialProperty')"
|
||||
[ngClass]="
|
||||
activeTabAction === 'commercialProperty'
|
||||
? ['text-blue-600', 'border-blue-600', 'active', 'dark:text-blue-500', 'dark:border-blue-500']
|
||||
: ['border-transparent', 'hover:text-gray-600', 'hover:border-gray-300', 'dark:hover:text-gray-300']
|
||||
? ['text-primary-600', 'border-primary-600', 'active', 'dark:text-primary-500', 'dark:border-primary-500']
|
||||
: ['border-transparent', 'hover:text-neutral-600', 'hover:border-neutral-300', 'dark:hover:text-neutral-300']
|
||||
"
|
||||
class="hover:cursor-pointer inline-block px-1 py-2 md:p-4 border-b-2 rounded-t-lg"
|
||||
>Properties</a
|
||||
class="tab-link hover:cursor-pointer inline-flex items-center justify-center px-1 py-2 md:p-4 border-b-2 rounded-t-lg"
|
||||
>
|
||||
<img src="assets/images/properties_logo.png" alt="Search commercial properties for sale" class="tab-icon w-6 h-6 md:w-7 md:h-7 mr-1 md:mr-2 object-contain" />
|
||||
<span>Properties</span>
|
||||
</a>
|
||||
</li>
|
||||
} @if ((numberOfBroker$ | async) > 0) {
|
||||
}
|
||||
<li class="w-[33%]">
|
||||
<a
|
||||
(click)="changeTab('broker')"
|
||||
[ngClass]="
|
||||
activeTabAction === 'broker'
|
||||
? ['text-blue-600', 'border-blue-600', 'active', 'dark:text-blue-500', 'dark:border-blue-500']
|
||||
: ['border-transparent', 'hover:text-gray-600', 'hover:border-gray-300', 'dark:hover:text-gray-300']
|
||||
? ['text-primary-600', 'border-primary-600', 'active', 'dark:text-primary-500', 'dark:border-primary-500']
|
||||
: ['border-transparent', 'hover:text-neutral-600', 'hover:border-neutral-300', 'dark:hover:text-neutral-300']
|
||||
"
|
||||
class="hover:cursor-pointer inline-block px-1 py-2 md:p-4 border-b-2 rounded-t-lg"
|
||||
>Professionals</a
|
||||
class="tab-link hover:cursor-pointer inline-flex items-center justify-center px-1 py-2 md:p-4 border-b-2 rounded-t-lg"
|
||||
>
|
||||
<img src="assets/images/icon_professionals.png" alt="Search business professionals and brokers" class="tab-icon w-6 h-6 md:w-7 md:h-7 mr-1 md:mr-2 object-contain bg-transparent" style="mix-blend-mode: darken;" />
|
||||
<span>Professionals</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
} @if(criteria && !aiSearch){
|
||||
<div class="w-full max-w-3xl mx-auto bg-white rounded-lg flex flex-col md:flex-row md:border md:border-gray-300">
|
||||
<div class="md:flex-none md:w-48 flex-1 md:border-r border-gray-300 overflow-hidden mb-2 md:mb-0">
|
||||
<div class="relative max-sm:border border-gray-300 rounded-md">
|
||||
<div class="w-full max-w-3xl mx-auto bg-white rounded-lg flex flex-col md:flex-row md:border md:border-neutral-300">
|
||||
<div class="md:flex-none md:w-48 flex-1 md:border-r border-neutral-300 overflow-hidden mb-2 md:mb-0">
|
||||
<div class="relative max-sm:border border-neutral-300 rounded-md">
|
||||
<select
|
||||
class="appearance-none bg-transparent w-full py-3 px-4 pr-8 focus:outline-none md:border-none rounded-md md:rounded-none"
|
||||
class="appearance-none bg-transparent w-full py-4 px-4 pr-8 focus:outline-none md:border-none rounded-md md:rounded-none min-h-[52px]"
|
||||
[ngModel]="criteria.types"
|
||||
(ngModelChange)="onTypesChange($event)"
|
||||
[ngClass]="{ 'placeholder-selected': criteria.types.length === 0 }"
|
||||
@@ -118,14 +123,14 @@
|
||||
<option [value]="type.value">{{ type.name }}</option>
|
||||
}
|
||||
</select>
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-neutral-700">
|
||||
<i class="fas fa-chevron-down text-xs"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md:flex-auto md:w-36 flex-grow md:border-r border-gray-300 mb-2 md:mb-0">
|
||||
<div class="relative max-sm:border border-gray-300 rounded-md">
|
||||
<div class="md:flex-auto md:w-36 flex-grow md:border-r border-neutral-300 mb-2 md:mb-0">
|
||||
<div class="relative max-sm:border border-neutral-300 rounded-md">
|
||||
<ng-select
|
||||
class="custom md:border-none rounded-md md:rounded-none"
|
||||
[multiple]="false"
|
||||
@@ -147,10 +152,10 @@
|
||||
</div>
|
||||
</div>
|
||||
@if (criteria.radius && !aiSearch){
|
||||
<div class="md:flex-none md:w-36 flex-1 md:border-r border-gray-300 mb-2 md:mb-0">
|
||||
<div class="relative max-sm:border border-gray-300 rounded-md">
|
||||
<div class="md:flex-none md:w-36 flex-1 md:border-r border-neutral-300 mb-2 md:mb-0">
|
||||
<div class="relative max-sm:border border-neutral-300 rounded-md">
|
||||
<select
|
||||
class="appearance-none bg-transparent w-full py-3 px-4 pr-8 focus:outline-none md:border-none rounded-md md:rounded-none"
|
||||
class="appearance-none bg-transparent w-full py-4 px-4 pr-8 focus:outline-none md:border-none rounded-md md:rounded-none min-h-[52px]"
|
||||
(ngModelChange)="onRadiusChange($event)"
|
||||
[ngModel]="criteria.radius"
|
||||
[ngClass]="{ 'placeholder-selected': !criteria.radius }"
|
||||
@@ -160,19 +165,23 @@
|
||||
<option [value]="dist.value">{{ dist.name }}</option>
|
||||
}
|
||||
</select>
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-neutral-700">
|
||||
<i class="fas fa-chevron-down text-xs"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="bg-blue-600 hover:bg-blue-500 transition-colors duration-200 max-sm:rounded-md">
|
||||
<div class="bg-primary-500 hover:bg-primary-600 max-sm:rounded-md search-button">
|
||||
@if( numberOfResults$){
|
||||
<button class="w-full h-full text-white font-semibold py-2 px-4 md:py-3 md:px-6 focus:outline-none rounded-md md:rounded-none min-h-[48px]" (click)="search()">
|
||||
Search ({{ numberOfResults$ | async }})
|
||||
<button class="w-full h-full text-white font-bold py-2 px-4 md:py-3 md:px-6 focus:outline-none rounded-md md:rounded-none min-h-[52px] flex items-center justify-center gap-2" (click)="search()">
|
||||
<i class="fas fa-search"></i>
|
||||
<span>Search {{ numberOfResults$ | async }}</span>
|
||||
</button>
|
||||
}@else {
|
||||
<button class="w-full h-full text-white font-semibold py-2 px-4 md:py-3 md:px-6 focus:outline-none rounded-md md:rounded-none min-h-[48px]" (click)="search()">Search</button>
|
||||
<button class="w-full h-full text-white font-bold py-2 px-4 md:py-3 md:px-6 focus:outline-none rounded-md md:rounded-none min-h-[52px] flex items-center justify-center gap-2" (click)="search()">
|
||||
<i class="fas fa-search"></i>
|
||||
<span>Search</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -181,5 +190,69 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Trust & Social Proof Section -->
|
||||
<div class="w-full px-4 mt-8">
|
||||
<div class="trust-section-container bg-white rounded-xl py-10 px-6 md:px-10 border border-neutral-200">
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<h2 class="text-2xl md:text-3xl font-semibold text-center text-neutral-800 mb-2">Trusted by Thousands</h2>
|
||||
<p class="text-center text-neutral-500 mb-10 text-base">Join thousands of successful buyers and sellers on BizMatch</p>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 md:gap-8">
|
||||
<!-- Trust Badge 1 -->
|
||||
<div class="trust-badge text-center">
|
||||
<div class="trust-icon inline-flex items-center justify-center w-12 h-12 bg-neutral-100 text-neutral-600 rounded-full mb-3">
|
||||
<i class="fas fa-shield-alt text-lg"></i>
|
||||
</div>
|
||||
<h3 class="text-base font-semibold text-neutral-800 mb-1">Verified Listings</h3>
|
||||
<p class="text-sm text-neutral-500">All business listings are verified and reviewed by our team</p>
|
||||
</div>
|
||||
|
||||
<!-- Trust Badge 2 -->
|
||||
<div class="trust-badge text-center">
|
||||
<div class="trust-icon inline-flex items-center justify-center w-12 h-12 bg-neutral-100 text-neutral-600 rounded-full mb-3">
|
||||
<i class="fas fa-users text-lg"></i>
|
||||
</div>
|
||||
<h3 class="text-base font-semibold text-neutral-800 mb-1">Expert Support</h3>
|
||||
<p class="text-sm text-neutral-500">Connect with licensed business brokers and advisors</p>
|
||||
</div>
|
||||
|
||||
<!-- Trust Badge 3 -->
|
||||
<div class="trust-badge text-center">
|
||||
<div class="trust-icon inline-flex items-center justify-center w-12 h-12 bg-neutral-100 text-neutral-600 rounded-full mb-3">
|
||||
<i class="fas fa-lock text-lg"></i>
|
||||
</div>
|
||||
<h3 class="text-base font-semibold text-neutral-800 mb-1">Secure Platform</h3>
|
||||
<p class="text-sm text-neutral-500">Your information is protected with enterprise-grade security</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats Row -->
|
||||
<div class="stats-section grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6 mt-10 pt-6 border-t border-neutral-100">
|
||||
<div class="text-center">
|
||||
<div class="stat-number text-2xl md:text-3xl font-semibold text-neutral-700 mb-1">{{ activeListingsCount | number:'1.0-0' }}+</div>
|
||||
<div class="text-xs md:text-sm text-neutral-500">Active Listings</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="stat-number text-2xl md:text-3xl font-semibold text-neutral-700 mb-1">{{ successfulSalesCount | number:'1.0-0' }}+</div>
|
||||
<div class="text-xs md:text-sm text-neutral-500">Successful Sales</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="stat-number text-2xl md:text-3xl font-semibold text-neutral-700 mb-1">{{ brokersCount | number:'1.0-0' }}+</div>
|
||||
<div class="text-xs md:text-sm text-neutral-500">Business Brokers</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="stat-number text-2xl md:text-3xl font-semibold text-neutral-700 mb-1">24/7</div>
|
||||
<div class="text-xs md:text-sm text-neutral-500">Platform Access</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FAQ Section for SEO/AEO -->
|
||||
<div class="w-full px-4 mt-12 max-w-4xl mx-auto">
|
||||
<app-faq [faqItems]="faqItems"></app-faq>
|
||||
</div>
|
||||
</main>
|
||||
<!-- ==== ANPASSUNGEN ENDE ==== -->
|
||||
|
||||
@@ -1,8 +1,41 @@
|
||||
.bg-cover-custom {
|
||||
position: relative;
|
||||
// Prioritize AVIF format (69KB) over JPG (26MB)
|
||||
background-image: url('/assets/images/flags_bg.avif');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
border-radius: 20px;
|
||||
|
||||
// Fallback for browsers that don't support AVIF
|
||||
@supports not (background-image: url('/assets/images/flags_bg.avif')) {
|
||||
background-image: url('/assets/images/flags_bg.jpg');
|
||||
}
|
||||
|
||||
// Add gradient overlay for better text contrast
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(0, 0, 0, 0.35) 0%,
|
||||
rgba(0, 0, 0, 0.15) 40%,
|
||||
rgba(0, 0, 0, 0.05) 70%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
border-radius: 20px;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// Ensure content stays above overlay
|
||||
> * {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
select:not([size]) {
|
||||
background-image: unset;
|
||||
@@ -32,11 +65,11 @@ select {
|
||||
background-color: rgb(125 211 252);
|
||||
}
|
||||
:host ::ng-deep .ng-select.ng-select-single .ng-select-container {
|
||||
height: 48px;
|
||||
min-height: 52px;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
.ng-value-container .ng-input {
|
||||
top: 10px;
|
||||
top: 12px;
|
||||
}
|
||||
span.ng-arrow-wrapper {
|
||||
display: none;
|
||||
@@ -70,3 +103,164 @@ input[type='text'][name='aiSearchText'] {
|
||||
box-sizing: border-box; /* Padding und Border in die Höhe und Breite einrechnen */
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
// Enhanced Search Button Styling
|
||||
.search-button {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4);
|
||||
filter: brightness(1.05);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
// Ripple effect
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
transform: translate(-50%, -50%);
|
||||
transition: width 0.6s, height 0.6s;
|
||||
}
|
||||
|
||||
&:active::after {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
// Tab Icon Styling
|
||||
.tab-icon {
|
||||
font-size: 1rem;
|
||||
margin-right: 0.5rem;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.tab-link {
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
&:hover .tab-icon {
|
||||
transform: scale(1.15);
|
||||
}
|
||||
}
|
||||
|
||||
// Input Field Hover Effects
|
||||
select,
|
||||
.ng-select {
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(243, 244, 246, 0.8);
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
background-color: white;
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
// Smooth tab transitions
|
||||
.tab-content {
|
||||
animation: fadeInUp 0.3s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Trust section container - more prominent
|
||||
.trust-section-container {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
transition: box-shadow 0.3s ease, transform 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
}
|
||||
|
||||
// Trust badge animations - subtle lowkey style
|
||||
.trust-badge {
|
||||
transition: opacity 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.trust-icon {
|
||||
transition: background-color 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
.trust-badge:hover .trust-icon {
|
||||
background-color: rgb(229, 231, 235); // gray-200
|
||||
color: rgb(75, 85, 99); // gray-600
|
||||
}
|
||||
|
||||
// Stat counter animation - minimal
|
||||
.stat-number {
|
||||
transition: color 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
color: rgb(55, 65, 81); // gray-700 darker
|
||||
}
|
||||
}
|
||||
|
||||
// Search form container enhancement
|
||||
.search-form-container {
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(10px);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
// Header button improvements
|
||||
header {
|
||||
a {
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
&.text-blue-600.border.border-blue-600 {
|
||||
// Log In button
|
||||
&:hover {
|
||||
background-color: rgba(37, 99, 235, 0.05);
|
||||
box-shadow: 0 2px 8px rgba(37, 99, 235, 0.15);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
&.bg-blue-600 {
|
||||
// Register button
|
||||
&:hover {
|
||||
background-color: rgb(29, 78, 216);
|
||||
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);
|
||||
filter: brightness(1.05);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { initFlowbite } from 'flowbite';
|
||||
import { catchError, concat, distinctUntilChanged, Observable, of, Subject, switchMap, tap } from 'rxjs';
|
||||
import { BusinessListingCriteria, CityAndStateResult, CommercialPropertyListingCriteria, GeoResult, KeycloakUser, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
|
||||
import { FaqComponent, FAQItem } from '../../components/faq/faq.component';
|
||||
import { ModalService } from '../../components/search-modal/modal.service';
|
||||
import { TooltipComponent } from '../../components/tooltip/tooltip.component';
|
||||
import { AiService } from '../../services/ai.service';
|
||||
@@ -16,6 +17,7 @@ import { GeoService } from '../../services/geo.service';
|
||||
import { ListingsService } from '../../services/listings.service';
|
||||
import { SearchService } from '../../services/search.service';
|
||||
import { SelectOptionsService } from '../../services/select-options.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { UserService } from '../../services/user.service';
|
||||
import { map2User } from '../../utils/utils';
|
||||
|
||||
@@ -23,7 +25,7 @@ import { map2User } from '../../utils/utils';
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule, RouterModule, NgSelectModule, TooltipComponent],
|
||||
imports: [CommonModule, FormsModule, RouterModule, NgSelectModule, TooltipComponent, FaqComponent],
|
||||
templateUrl: './home.component.html',
|
||||
styleUrl: './home.component.scss',
|
||||
})
|
||||
@@ -58,6 +60,56 @@ export class HomeComponent {
|
||||
showInput: boolean = true;
|
||||
tooltipTargetBeta = 'tooltipTargetBeta';
|
||||
|
||||
// Counter animation
|
||||
activeListingsCount = 0;
|
||||
successfulSalesCount = 0;
|
||||
brokersCount = 0;
|
||||
hasAnimated = false;
|
||||
|
||||
// FAQ data optimized for AEO (Answer Engine Optimization) and Featured Snippets
|
||||
faqItems: FAQItem[] = [
|
||||
{
|
||||
question: 'How do I buy a business on BizMatch?',
|
||||
answer: '<p><strong>Buying a business on BizMatch involves 6 simple steps:</strong></p><ol><li><strong>Browse Listings:</strong> Search our marketplace using filters for industry, location, and price range</li><li><strong>Review Details:</strong> Examine financial information, business operations, and growth potential</li><li><strong>Contact Seller:</strong> Reach out directly through our secure messaging platform</li><li><strong>Due Diligence:</strong> Review financial statements, contracts, and legal documents</li><li><strong>Negotiate Terms:</strong> Work with the seller to agree on price and transition details</li><li><strong>Close Deal:</strong> Complete the purchase with legal and financial advisors</li></ol><p>We recommend working with experienced business brokers and conducting thorough due diligence before making any purchase.</p>'
|
||||
},
|
||||
{
|
||||
question: 'How much does it cost to list a business for sale?',
|
||||
answer: '<p><strong>BizMatch offers flexible pricing options:</strong></p><ul><li><strong>Free Basic Listing:</strong> Post your business with essential details at no cost</li><li><strong>Premium Listing:</strong> Enhanced visibility with featured placement and priority support</li><li><strong>Broker Packages:</strong> Professional tools for business brokers and agencies</li></ul><p>Contact our team for detailed pricing information tailored to your specific needs.</p>'
|
||||
},
|
||||
{
|
||||
question: 'What types of businesses can I find on BizMatch?',
|
||||
answer: '<p><strong>BizMatch features businesses across all major industries:</strong></p><ul><li><strong>Food & Hospitality:</strong> Restaurants, cafes, bars, hotels, catering services</li><li><strong>Retail:</strong> Stores, boutiques, online shops, franchises</li><li><strong>Service Businesses:</strong> Consulting firms, cleaning services, healthcare practices</li><li><strong>Manufacturing:</strong> Production facilities, distribution centers, warehouses</li><li><strong>E-commerce:</strong> Online businesses, digital products, subscription services</li><li><strong>Commercial Real Estate:</strong> Office buildings, retail spaces, industrial properties</li></ul><p>Our marketplace serves all business sizes from small local operations to large enterprises across the United States.</p>'
|
||||
},
|
||||
{
|
||||
question: 'How do I know if a business listing is legitimate?',
|
||||
answer: '<p><strong>Yes, BizMatch verifies all listings.</strong> Here\'s how we ensure legitimacy:</p><ol><li><strong>Seller Verification:</strong> All users must verify their identity and contact information</li><li><strong>Listing Review:</strong> Our team reviews each listing for completeness and accuracy</li><li><strong>Documentation Check:</strong> We verify business registration and ownership documents</li><li><strong>Transparent Communication:</strong> All conversations are logged through our secure platform</li></ol><p><strong>Additional steps you should take:</strong></p><ul><li>Review financial statements and tax returns</li><li>Visit the business location in person</li><li>Consult with legal and financial advisors</li><li>Work with licensed business brokers when appropriate</li><li>Conduct background checks on sellers</li></ul>'
|
||||
},
|
||||
{
|
||||
question: 'Can I sell commercial property on BizMatch?',
|
||||
answer: '<p><strong>Yes!</strong> BizMatch is a full-service marketplace for both businesses and commercial real estate.</p><p><strong>Property types you can list:</strong></p><ul><li>Office buildings and professional spaces</li><li>Retail locations and shopping centers</li><li>Warehouses and distribution facilities</li><li>Industrial properties and manufacturing plants</li><li>Mixed-use developments</li><li>Land for commercial development</li></ul><p>Our platform connects you with qualified buyers, investors, and commercial real estate professionals actively searching for investment opportunities.</p>'
|
||||
},
|
||||
{
|
||||
question: 'What information should I include when listing my business?',
|
||||
answer: '<p><strong>A complete listing should include these essential details:</strong></p><ol><li><strong>Financial Information:</strong> Asking price, annual revenue, cash flow, profit margins</li><li><strong>Business Operations:</strong> Years established, number of employees, hours of operation</li><li><strong>Description:</strong> Detailed overview of products/services, customer base, competitive advantages</li><li><strong>Industry Category:</strong> Specific business type and market segment</li><li><strong>Location Details:</strong> City, state, demographic information</li><li><strong>Assets Included:</strong> Equipment, inventory, real estate, intellectual property</li><li><strong>Visual Content:</strong> High-quality photos of business premises and operations</li><li><strong>Growth Potential:</strong> Expansion opportunities and market trends</li></ol><p><strong>Pro tip:</strong> The more detailed and transparent your listing, the more interest it will generate from serious, qualified buyers.</p>'
|
||||
},
|
||||
{
|
||||
question: 'How long does it take to sell a business?',
|
||||
answer: '<p><strong>Most businesses sell within 6 to 12 months.</strong> The timeline varies based on several factors:</p><p><strong>Factors that speed up sales:</strong></p><ul><li>Realistic pricing based on professional valuation</li><li>Complete and organized financial documentation</li><li>Strong business performance and growth trends</li><li>Attractive location and market conditions</li><li>Experienced business broker representation</li><li>Flexible seller terms and financing options</li></ul><p><strong>Timeline breakdown:</strong></p><ol><li><strong>Months 1-2:</strong> Preparation and listing creation</li><li><strong>Months 3-6:</strong> Marketing and buyer qualification</li><li><strong>Months 7-10:</strong> Negotiations and due diligence</li><li><strong>Months 11-12:</strong> Closing and transition</li></ol>'
|
||||
},
|
||||
{
|
||||
question: 'What is business valuation and why is it important?',
|
||||
answer: '<p><strong>Business valuation is the process of determining the economic worth of a company.</strong> It calculates the fair market value based on financial performance, assets, and market conditions.</p><p><strong>Why valuation matters:</strong></p><ul><li><strong>Realistic Pricing:</strong> Attracts serious buyers and prevents extended time on market</li><li><strong>Negotiation Power:</strong> Provides data-driven justification for asking price</li><li><strong>Buyer Confidence:</strong> Professional valuations increase trust and credibility</li><li><strong>Financing Approval:</strong> Banks require valuations for business acquisition loans</li></ul><p><strong>Valuation methods include:</strong></p><ol><li><strong>Asset-Based:</strong> Total value of business assets minus liabilities</li><li><strong>Income-Based:</strong> Projected future earnings and cash flow</li><li><strong>Market-Based:</strong> Comparison to similar business sales</li><li><strong>Multiple of Earnings:</strong> Revenue or profit multiplied by industry-standard factor</li></ol>'
|
||||
},
|
||||
{
|
||||
question: 'Do I need a business broker to buy or sell a business?',
|
||||
answer: '<p><strong>No, but brokers are highly recommended.</strong> You can conduct transactions directly through BizMatch, but professional brokers provide significant advantages:</p><p><strong>Benefits of using a business broker:</strong></p><ul><li><strong>Expert Valuation:</strong> Accurate pricing based on market data and analysis</li><li><strong>Marketing Expertise:</strong> Professional listing creation and buyer outreach</li><li><strong>Qualified Buyers:</strong> Pre-screening to ensure financial capability and serious interest</li><li><strong>Negotiation Skills:</strong> Experience handling complex deal structures and terms</li><li><strong>Confidentiality:</strong> Protect sensitive information during the sales process</li><li><strong>Legal Compliance:</strong> Navigate regulations, contracts, and disclosures</li><li><strong>Time Savings:</strong> Handle paperwork, communications, and coordination</li></ul><p>BizMatch connects you with licensed brokers in your area, or you can manage the transaction yourself using our secure platform and resources.</p>'
|
||||
},
|
||||
{
|
||||
question: 'What financing options are available for buying a business?',
|
||||
answer: '<p><strong>Business buyers have multiple financing options:</strong></p><ol><li><strong>SBA 7(a) Loans:</strong> Government-backed loans with favorable terms<ul><li>Down payment as low as 10%</li><li>Loan amounts up to $5 million</li><li>Competitive interest rates</li><li>Terms up to 10-25 years</li></ul></li><li><strong>Conventional Bank Financing:</strong> Traditional business acquisition loans<ul><li>Typically require 20-30% down payment</li><li>Based on creditworthiness and business performance</li></ul></li><li><strong>Seller Financing:</strong> Owner provides loan to buyer<ul><li>More flexible terms and requirements</li><li>Often combined with other financing</li><li>Typically 10-30% of purchase price</li></ul></li><li><strong>Investor Partnerships:</strong> Equity financing from partners<ul><li>Shared ownership and profits</li><li>No personal debt obligation</li></ul></li><li><strong>Personal Savings:</strong> Self-funded purchase<ul><li>No interest or loan payments</li><li>Full ownership from day one</li></ul></li></ol><p><strong>Most buyers use a combination of these options</strong> to structure the optimal deal for their situation.</p>'
|
||||
}
|
||||
];
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private modalService: ModalService,
|
||||
@@ -71,6 +123,7 @@ export class HomeComponent {
|
||||
private aiService: AiService,
|
||||
private authService: AuthService,
|
||||
private filterStateService: FilterStateService,
|
||||
private seoService: SeoService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
@@ -78,6 +131,61 @@ export class HomeComponent {
|
||||
initFlowbite();
|
||||
}, 0);
|
||||
|
||||
// Set SEO meta tags for home page
|
||||
this.seoService.updateMetaTags({
|
||||
title: 'BizMatch - Buy & Sell Businesses and Commercial Properties',
|
||||
description: 'Find profitable businesses for sale, commercial real estate, and franchise opportunities across the United States. Browse thousands of listings from verified sellers and brokers.',
|
||||
keywords: 'business for sale, businesses for sale, buy business, sell business, commercial property, commercial real estate, franchise opportunities, business broker, business marketplace',
|
||||
type: 'website'
|
||||
});
|
||||
|
||||
// Add Organization schema for brand identity and FAQ schema for AEO
|
||||
const organizationSchema = this.seoService.generateOrganizationSchema();
|
||||
const faqSchema = this.seoService.generateFAQPageSchema(
|
||||
this.faqItems.map(item => ({
|
||||
question: item.question,
|
||||
answer: item.answer
|
||||
}))
|
||||
);
|
||||
|
||||
// Add HowTo schema for buying a business
|
||||
const howToSchema = this.seoService.generateHowToSchema({
|
||||
name: 'How to Buy a Business on BizMatch',
|
||||
description: 'Step-by-step guide to finding and purchasing your ideal business through BizMatch marketplace',
|
||||
totalTime: 'PT45M',
|
||||
steps: [
|
||||
{
|
||||
name: 'Browse Business Listings',
|
||||
text: 'Search through thousands of verified business listings using our advanced filters. Filter by industry, location, price range, revenue, and more to find businesses that match your criteria.'
|
||||
},
|
||||
{
|
||||
name: 'Review Business Details',
|
||||
text: 'Examine the business financials, including annual revenue, cash flow, asking price, and years established. Read the detailed business description and view photos of the operation.'
|
||||
},
|
||||
{
|
||||
name: 'Contact the Seller',
|
||||
text: 'Use our secure messaging system to contact the seller or business broker directly. Request additional information, financial documents, or schedule a site visit to see the business in person.'
|
||||
},
|
||||
{
|
||||
name: 'Conduct Due Diligence',
|
||||
text: 'Review all financial statements, tax returns, lease agreements, and legal documents. Verify the business information, inspect the physical location, and consult with legal and financial advisors.'
|
||||
},
|
||||
{
|
||||
name: 'Make an Offer',
|
||||
text: 'Submit a formal offer based on your valuation and due diligence findings. Negotiate terms including purchase price, payment structure, transition period, and any contingencies.'
|
||||
},
|
||||
{
|
||||
name: 'Close the Transaction',
|
||||
text: 'Work with attorneys and escrow services to finalize all legal documents, transfer ownership, and complete the purchase. The seller will transfer assets, train you on operations, and help with the transition.'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Add SearchBox schema for Sitelinks Search
|
||||
const searchBoxSchema = this.seoService.generateSearchBoxSchema();
|
||||
|
||||
this.seoService.injectMultipleSchemas([organizationSchema, faqSchema, howToSchema, searchBoxSchema]);
|
||||
|
||||
// Clear all filters and sort options on initial load
|
||||
this.filterStateService.resetCriteria('businessListings');
|
||||
this.filterStateService.resetCriteria('commercialPropertyListings');
|
||||
@@ -95,6 +203,47 @@ export class HomeComponent {
|
||||
this.user = map2User(token);
|
||||
this.loadCities();
|
||||
this.setTotalNumberOfResults();
|
||||
|
||||
// Setup intersection observer for counter animation
|
||||
this.setupCounterAnimation();
|
||||
}
|
||||
|
||||
setupCounterAnimation() {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting && !this.hasAnimated) {
|
||||
this.hasAnimated = true;
|
||||
this.animateCounter('activeListingsCount', 1000, 2000);
|
||||
this.animateCounter('successfulSalesCount', 500, 2000);
|
||||
this.animateCounter('brokersCount', 50, 2000);
|
||||
}
|
||||
});
|
||||
},
|
||||
{ threshold: 0.3 }
|
||||
);
|
||||
|
||||
// Wait for the element to be available
|
||||
setTimeout(() => {
|
||||
const statsElement = document.querySelector('.stats-section');
|
||||
if (statsElement) {
|
||||
observer.observe(statsElement);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
animateCounter(property: 'activeListingsCount' | 'successfulSalesCount' | 'brokersCount', target: number, duration: number) {
|
||||
const start = 0;
|
||||
const increment = target / (duration / 16); // 60fps
|
||||
const step = () => {
|
||||
this[property] += increment;
|
||||
if (this[property] < target) {
|
||||
requestAnimationFrame(step);
|
||||
} else {
|
||||
this[property] = target;
|
||||
}
|
||||
};
|
||||
requestAnimationFrame(step);
|
||||
}
|
||||
|
||||
changeTab(tabname: 'business' | 'commercialProperty' | 'broker') {
|
||||
|
||||
Reference in New Issue
Block a user