Skip to main content
Back to ScopeForged

ScopeForged Documentation

Technical documentation, guides, and feature references for the ScopeForged client portal.

Integrations & Marketing/Marketing Site

Marketing Site Guide

Last Updated: 2026-02-16 Status: Implemented (Phase 1 + SEO + Contact Management + Multi-Domain + Case Studies + Team/Founder) Plan Reference: 113-multi-domain-architecture.md, 114-marketing-site.md, 126-contact-form-submissions.md, 127-import-contact-submissions-from-logs.md, 128-seo-optimization.md, 152-team-founder-page.md


Overview

The marketing site at scopeforged.com serves as the public-facing brand presence, lead generation funnel, and centralized authentication entry point. All users (clients and admins) log in through the marketing site and are redirected to their appropriate subdomain based on role.


Table of Contents

  1. Domain Architecture
  2. Pages
  3. Authentication Flow
  4. Technical Architecture
  5. Content Structure
  6. Related Features

Domain Architecture

DomainPurposeAuth Required
scopeforged.comMarketing site + LoginNo (public) / Yes (auth routes)
portal.scopeforged.comClient portalYes (role: client)
admin.scopeforged.comAdmin panelYes (role: admin)

Session Sharing

Sessions are shared across all subdomains via SESSION_DOMAIN=.scopeforged.com. This enables:

  • Single login for all domains
  • Seamless navigation between subdomains
  • Centralized logout

Pages

Public Pages

PageRouteRoute NamePurpose
Homepage/marketing.homeHero, value proposition, process overview, CTAs
Process/processmarketing.process5-phase development process detail
Services/servicesmarketing.servicesOverview of all services
Service Detail/services/{slug}marketing.services.showIndividual service pages
Audits/auditsmarketing.auditsAudit catalog (19 audits, 7 categories)
About/aboutmarketing.aboutCompany story, founder profile, values
Contact/contactmarketing.contactContact form
Case Studies/case-studiesmarketing.case-studies.indexPortfolio of completed work
Case Study Detail/case-studies/{slug}marketing.case-studies.showIndividual case study
Privacy/privacymarketing.privacyPrivacy policy
Terms/termsmarketing.termsTerms of service

Authentication Pages

PageRouteRoute NameAccess
Login/loginloginGuest only
Signup/signupmarketing.signupGuest only
Forgot Password/forgot-passwordpassword.requestGuest only
Reset Password/reset-password/{token}password.resetGuest only
Logout/logout (POST)logoutAuthenticated

Service Detail Pages

ServiceURL
Technical Audits & Discovery/services/technical-audits
Custom Application Development/services/custom-development
System Modernization & Migration/services/modernization
Production Infrastructure/services/infrastructure
Ongoing Support & Evolution/services/support

Authentication Flow

Login Flow

  1. User visits scopeforged.com/login
  2. Enters email and password
  3. On successful authentication:
    • Admin users → Redirect to admin.scopeforged.com
    • Client users → Redirect to portal.scopeforged.com
  4. Session cookie is set for .scopeforged.com domain

Signup Flow

  1. User visits scopeforged.com/signup
  2. Fills form: name, email, company name, password
  3. On submission, system creates:
    • User record (role: client)
    • Client record (company)
    • User-Client relationship
    • Project record (name: "Discovery", status: draft, stage: questionnaire)
  4. User is logged in automatically
  5. Redirect to portal.scopeforged.com/projects/{id}/questionnaire

Unauthenticated Access Handling

When an unauthenticated user attempts to access protected routes:

  • Portal routes → Redirect to scopeforged.com/login
  • Admin routes → Redirect to scopeforged.com/login

Configured in bootstrap/app.php:

$middleware->redirectGuestsTo(fn () => marketing_url('/login'));

Password Reset Flow

  1. User clicks "Forgot Password" on login page
  2. Enters email on /forgot-password
  3. Receives email with reset link
  4. Clicks link → /reset-password/{token}
  5. Sets new password
  6. Redirected to login page

Technical Architecture

Controllers

ControllerPurpose
Marketing\AuthControllerLogin, signup, logout, password reset
Marketing\HomeControllerHomepage (inherited from layout)
Marketing\ProcessControllerProcess page
Marketing\ServicesControllerServices index and detail
Marketing\AuditsControllerAudit catalog
Marketing\AboutControllerAbout page
Marketing\ContactControllerContact form handling
Marketing\CaseStudyControllerCase studies listing and detail

Views Structure

resources/views/marketing/
├── layouts/
│   └── app.blade.php           # Main marketing layout
├── partials/
│   ├── header.blade.php        # Navigation header
│   └── footer.blade.php        # Site footer
├── auth/
│   ├── login.blade.php
│   ├── signup.blade.php
│   ├── forgot-password.blade.php
│   └── reset-password.blade.php
├── services/
│   ├── index.blade.php         # Services overview
│   ├── show.blade.php          # Service detail wrapper
│   └── partials/               # Service-specific content
│       ├── technical-audits.blade.php
│       ├── custom-development.blade.php
│       ├── modernization.blade.php
│       ├── infrastructure.blade.php
│       └── support.blade.php
├── home.blade.php
├── process.blade.php
├── audits.blade.php
├── about.blade.php
├── contact.blade.php
├── privacy.blade.php
└── terms.blade.php

resources/views/components/marketing/
├── founder-profile.blade.php    # Founder profile card with photo, bio, credentials
├── team-member-card.blade.php   # Compact team member card for future expansion
├── testimonial-card.blade.php   # Client testimonial display
├── testimonial-carousel.blade.php # Testimonial carousel component
├── trust-badges.blade.php       # Trust signals and badges
├── faq-item.blade.php           # FAQ accordion item
├── chatbot-widget.blade.php     # AI chatbot widget
├── chat-widget.blade.php        # Live chat widget
└── cookie-consent.blade.php     # GDPR cookie consent banner

Routes

Routes are defined in routes/marketing.php and loaded via domain-based routing in bootstrap/app.php:

Route::domain(config('domains.marketing'))
    ->middleware('web')
    ->group(base_path('routes/marketing.php'));

Helper Functions

Located in app/Helpers/domain_helpers.php:

HelperPurpose
marketing_url($path)Generate URL for marketing domain
portal_url($path)Generate URL for portal domain
admin_url($path)Generate URL for admin domain
current_domain_context()Get current domain context

Content Structure

Homepage Sections

  1. Hero - Primary value proposition with CTAs
  2. The Problem - Why software projects fail
  3. The Process - Visual overview of 5 phases
  4. What Makes Us Different - Key differentiators
  5. Services Overview - Cards for each service
  6. Audits Highlight - 19-audit catalog emphasis
  7. What This Means For You - Client benefits
  8. Final CTA - "Start Your Discovery"

About Page Sections

  1. Hero - Page title and introduction
  2. Our Story (Why We Exist) - Company founding story and mission
  3. Meet the Founder - Profile card with photo, bio, credentials, and social links
  4. Our Values (What We Stand For) - Transparency, Accountability, Quality
  5. The Problem We Solve - Why software projects fail
  6. How We're Different - Key differentiators (portal, audits, milestones, discovery)
  7. Final CTA - "Start Your Discovery" and contact links

The About page includes Person schema.org markup for the founder to improve SEO.

Process Page Phases

  1. Discovery - Clarity before commitment
  2. Build - Implement with discipline
  3. Audit - Verify quality
  4. Launch - Controlled release
  5. Iterate - Long-term success

Audit Categories

CategoryAudits Count
Code & Architecture2
Security3
Performance3
Quality3
Operations3
User Experience4
Integrations1
Total19

Animation System

All marketing pages use a consistent animation toolkit defined in resources/css/animations.css. No custom JavaScript is needed - animations are triggered by Alpine.js directives.

Animation Classes

ClassEffect
reveal reveal-upFade in + slide up
reveal reveal-leftFade in + slide from left
reveal reveal-rightFade in + slide from right
reveal reveal-scaleFade in + scale up
reveal-staggerAuto-delays children 100ms apart
hero-staggerAuto-delays children 150ms apart
hover-liftTranslateY + shadow on hover
btn-shimmerShimmer effect on buttons
btn-arrow-slideArrow slides right on hover
press-effectScale down on click
section-dividerDecorative section separator

Patterns

Hero (immediate on load):

<div class="hero-stagger" x-data="{ shown: false }" x-init="$nextTick(() => shown = true)">
    <h1 class="reveal reveal-up" :class="shown && 'revealed'">...</h1>
</div>

Section (reveal on scroll):

<div class="reveal reveal-up" x-data x-intersect.once="$el.classList.add('revealed')">...</div>

Card grid (staggered):

<div class="reveal-stagger" x-data x-intersect.once="$el.querySelectorAll('.reveal').forEach(el => el.classList.add('revealed'))">
    <div class="reveal reveal-up hover-lift">Card</div>
</div>

Accessibility

Animations are automatically disabled when prefers-reduced-motion: reduce is set, handled by @media query in animations.css.

Pages with Animations

All marketing pages: Home, Process, Services, About, Contact, Blog, FAQ, Audits, and all service detail pages.



Contact Form Submissions

Contact form submissions are stored in the database for admin management and follow-up.

Contact Form Submission Flow

  1. User visits scopeforged.com/contact
  2. Fills form: name, email, company (optional), message
  3. Submission stored in contact_submissions table
  4. Admin notification sent (database + broadcast)
  5. Admin can manage submissions via admin panel

Admin Management

Location: Admin → CRM → Contact Submissions or /admin/contact-submissions

Features:

  • List all submissions with filtering (status, date range, search)
  • View individual submission details
  • Update status (new → reviewed → responded → archived)
  • Add admin notes
  • Delete submissions

Status Flow

[New] → [Reviewed] → [Responded] → [Archived]
                 ↘      ↗
                [Archived]
StatusDescription
newJust submitted, needs attention
reviewedAdmin has seen it
respondedAdmin has replied via email or other means
archivedNo longer active, kept for records

Contact Submission Model

Location: app/Models/ContactSubmission.php

FieldTypeDescription
namestringSubmitter name
emailstringSubmitter email
companystringCompany name (optional)
messagetextMessage content
statusstringnew, reviewed, responded, archived
admin_notestextInternal notes
reviewed_bybigintAdmin who reviewed
reviewed_attimestampReview timestamp
sourcestringcontact_form (default)
ip_addressstringSubmitter IP
user_agentstringBrowser user agent

Admin Notification

When a contact form is submitted, all admin users receive:

  • Database notification (bell icon badge)
  • Real-time broadcast notification
  • Deep link to submission detail page

Anti-Spam Protections

The public contact form is gated by two zero-UX-impact bot defenses in ContactController:

  1. Honeypot field — a visually and semantically hidden website input is rendered in the form. Real users never see or interact with it; bots that auto-fill all fields will populate it. A non-empty value triggers a silent drop.
  2. Time trap — on GET /contact, the controller stores the current Unix timestamp in the session under contact_form_loaded_at. On POST, the controller rejects submissions that arrive in under 3 seconds or with no recorded render time (i.e., the bot POSTed directly without ever loading the form).

When either tripwire fires, the controller:

  • Returns the same success redirect and flash message a legitimate submission would (so bots cannot tell the drop from an accept and adapt their tactics)
  • Writes nothing to contact_submissions
  • Sends no admin notification
  • Logs a contact.spam_dropped event with the IP, user agent, submitted name/email, and reason (honeypot_filled, no_render_timestamp, or submitted_too_fast)

Constants live as private const on ContactController:

  • HONEYPOT_FIELD = 'website'
  • FORM_LOADED_AT_SESSION_KEY = 'contact_form_loaded_at'
  • MIN_FORM_FILL_SECONDS = 3

Test coverage: tests/Feature/Http/Controllers/Marketing/ContactControllerTest.php (the "Spam Protection Tests" section).

If sophisticated bots adapt past these defenses, the next escalation tier is Cloudflare Turnstile / hCaptcha plus per-IP rate limiting.


Case Studies

The case studies section showcases completed projects and client success stories.

Case Studies Feature Toggle

Case Studies can be enabled/disabled via a system setting accessible in the admin panel.

Setting: case_studies_enabled (boolean, default: true)

Location: Admin → Settings (marketing group)

Behavior when disabled:

  • Navigation links removed from header (desktop and mobile)
  • Direct URL access returns 404
  • Setting is cached for performance

Implementation:

  • App\Models\Settings\SystemSetting::getValue('case_studies_enabled', true)
  • Check performed in CaseStudyController::ensureCaseStudiesEnabled()
  • Conditional rendering in resources/views/marketing/partials/header.blade.php

Case Study Model

Location: App\Models\Marketing\CaseStudy

FieldTypeDescription
titlestringCase study title
slugstringURL slug
client_namestringClient or company name
industrystringIndustry category
service_typestringPrimary service delivered
challengetextThe problem/challenge
solutiontextHow it was solved
resultstextOutcomes and metrics
featured_imagestringHero image path
is_featuredbooleanShow on homepage
is_publishedbooleanPublicly visible

Case Study Views

resources/views/marketing/case-studies/
├── index.blade.php    # Case studies grid with filtering
└── show.blade.php     # Individual case study detail

SEO Optimization

The marketing site includes comprehensive SEO features for improved search engine visibility.

SEO Features

FeatureImplementation
Meta titlesUnique per-page titles via SeoService
Meta descriptions155 character descriptions
Open Graph tagsog:title, og:description, og:image, og:type, og:url
Twitter Cardssummary_large_image format
Canonical URLsSet on all pages
JSON-LD structured dataOrganization, WebSite, Service, BreadcrumbList
SitemapDynamic XML at /sitemap.xml
robots.txtSitemap reference, admin/portal disallow

SEO Configuration

Location: config/seo.php

return [
    'site_name' => 'Scopeforged',
    'default_title' => 'Professional Software Development',
    'default_description' => 'Scopeforged provides...',
    'twitter_handle' => '@scopeforged',
    'og_image' => '/images/og-default.jpg',
    'locale' => 'en_US',

    'organization' => [
        'name' => 'Scopeforged',
        'url' => 'https://scopeforged.com',
        'logo' => '/images/logo.png',
        // ...
    ],
];

SeoService

Location: app/Services/SeoService.php

// Usage in views
$seoService = app(SeoService::class);
$seoService->setTitle('About Us');
$seoService->setDescription('Learn about Scopeforged...');
$seoService->addJsonLd(['@type' => 'BreadcrumbList', ...]);

SEO Component

Location: resources/views/components/seo/meta.blade.php

<x-seo.meta
    :title="$seoTitle"
    :description="$seoDescription"
    :canonical="$seoCanonical"
    :og-image="$seoOgImage"
    :json-ld="$seoJsonLd"
/>

Sitemap

Route: /sitemap.xml

Controller: app/Http/Controllers/Marketing/SitemapController.php

The sitemap is dynamically generated and includes:

  • All public marketing pages
  • Priority and changefreq for each URL
  • Last modification timestamps

Per-Page SEO

PageTitle PatternJSON-LD Schemas
HomeScopeforged - Professional Software DevelopmentOrganization, WebSite
ProcessHow We Work - Our 5-Phase Process | ScopeforgedBreadcrumbList
ServicesSoftware Development Services | ScopeforgedBreadcrumbList
Service Detail{Service Name} | ScopeforgedService, BreadcrumbList
AuditsTechnical Audit Catalog | ScopeforgedBreadcrumbList
AboutAbout ScopeforgedBreadcrumbList
ContactContact Us | ScopeforgedBreadcrumbList

Team & Founder Profile

The About page features a founder profile section that humanizes the brand and builds trust.

Founder Profile Component

Location: resources/views/components/marketing/founder-profile.blade.php

<x-marketing.founder-profile
    name="Philip Rehberger"
    title="Founder & Lead Developer"
    photo="/images/team/founder.jpg"
    :credentials="['Laravel Expert', 'Security Specialist', 'Full-Stack Developer']"
    linkedin="https://linkedin.com/in/philiprehberger"
    github="https://github.com/philiprehberger"
>
    <x-slot:bio>
        <p>Bio content here...</p>
    </x-slot:bio>
</x-marketing.founder-profile>
PropTypeRequiredDescription
namestringYesFull name
titlestringYesJob title
photostringYesPath to photo
credentialsarrayNoList of credentials/skills
linkedinstringNoLinkedIn profile URL
twitterstringNoTwitter/X profile URL
githubstringNoGitHub profile URL
bioslotYesBio content (HTML allowed)

Team Member Card Component

Location: resources/views/components/marketing/team-member-card.blade.php

A compact card for displaying team members in a grid layout. Useful if the team expands.

<x-marketing.team-member-card
    name="Team Member"
    title="Role"
    photo="/images/team/member.jpg"
    bio="Short bio"
    linkedin="..."
/>

Required Assets

AssetLocationNotes
Founder photo/public/images/team/founder.jpgMinimum 800x800px, professional headshot

Performance Optimizations

Performance improvements applied based on Lighthouse audit (2026-02-16).

Font Loading

Fonts are loaded asynchronously using the media="print" onload pattern to avoid render-blocking:

<link rel="preconnect" href="https://fonts.bunny.net" crossorigin>
<link rel="preload" href="..." as="style">
<link href="..." rel="stylesheet" media="print" onload="this.media='all'">
<noscript><link href="..." rel="stylesheet"></noscript>

JS Bundle Optimization

Echo/Pusher (73KB) are dynamically imported only when VITE_REVERB_APP_KEY is set. Marketing pages never load WebSocket dependencies. See resources/js/bootstrap.js and resources/js/echo-setup.js.

Animation Performance

The btn-shimmer effect uses transform: translateX() instead of animating the left property, running on the compositor thread to avoid CLS (layout shifts).

Cache Headers

Vite-hashed assets (app-CXfhYMq5.css) get immutable 1-year cache headers via .htaccess FilesMatch with a regex matching Vite's alphanumeric hash format.

Accessibility

  • "Pending" badge in browser mockup uses text-gray-600 for WCAG AA contrast compliance (5.74:1 ratio)
  • Cookie consent link uses descriptive text: "Learn more about our privacy policy"

Implementation Phases

Phase 1 (Completed)

  • Core public pages (home, process, services, audits, about, contact)
  • Centralized authentication (login, signup, password reset)
  • Role-based redirects
  • Auth middleware updates
  • Privacy policy and terms of service

Phase 2 (Completed)

  • Contact form submission management
  • Admin notification for new submissions
  • SEO optimization with meta tags and structured data
  • Dynamic XML sitemap
  • robots.txt with sitemap reference
  • Team & Founder profile section on About page
  • Person schema.org markup for founder

Phase 3 (Planned)

  • Blog system
  • Analytics integration
  • Lead magnet system
  • A/B testing capability