diff --git a/Modules/Licensing/Database/Migrations/2026_10_12_160000_extend_download_products.php b/Modules/Licensing/Database/Migrations/2026_10_12_160000_extend_download_products.php
index 420dd74..bedbed4 100644
--- a/Modules/Licensing/Database/Migrations/2026_10_12_160000_extend_download_products.php
+++ b/Modules/Licensing/Database/Migrations/2026_10_12_160000_extend_download_products.php
@@ -3,6 +3,16 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
- public function up(): void { Schema::table('download_products',function(Blueprint $table){$table->longText('release_notes')->nullable();$table->text('minimum_system')->nullable();$table->integer('sort_order')->default(0);}); }
- public function down(): void {Schema::table('download_products',function(Blueprint $table){$table->dropColumn(['release_notes','minimum_system','sort_order']);});}
+ public function up(): void {
+ if (!Schema::hasTable('download_products')) return;
+ foreach (['release_notes' => 'longText', 'minimum_system' => 'text', 'sort_order' => 'integer'] as $column => $type) {
+ if (!Schema::hasColumn('download_products', $column)) {
+ Schema::table('download_products', function (Blueprint $table) use ($column, $type) {
+ $definition = $table->{$type}($column);
+ if ($column === 'sort_order') $definition->default(0); else $definition->nullable();
+ });
+ }
+ }
+ }
+ public function down(): void { /* Preserve existing download metadata. */ }
};
diff --git a/Modules/Licensing/Database/Migrations/2026_10_12_210000_repair_download_product_columns.php b/Modules/Licensing/Database/Migrations/2026_10_12_210000_repair_download_product_columns.php
new file mode 100644
index 0000000..a6789c8
--- /dev/null
+++ b/Modules/Licensing/Database/Migrations/2026_10_12_210000_repair_download_product_columns.php
@@ -0,0 +1,15 @@
+'longText','minimum_system'=>'text','sort_order'=>'integer'] as $column=>$type) {
+ if (!Schema::hasColumn('download_products',$column)) Schema::table('download_products',function(Blueprint $table) use ($column,$type) {
+ $c=$table->{$type}($column); if ($column==='sort_order') $c->default(0); else $c->nullable();
+ });
+ }
+ }
+ public function down(): void { /* Keep uploaded download metadata intact. */ }
+};
diff --git a/Modules/Licensing/Resources/views/downloads/index.blade.php b/Modules/Licensing/Resources/views/downloads/index.blade.php
index e799f9f..e0beb2c 100644
--- a/Modules/Licensing/Resources/views/downloads/index.blade.php
+++ b/Modules/Licensing/Resources/views/downloads/index.blade.php
@@ -1,4 +1,6 @@
-
Product downloads · ABSDEV ABSDEV SOFTWARE Downloads & releases Get the latest versions of SonarDesk, SonarDisk and additional tools. Choose the installer that matches your system.
-@if($latest)LATEST STABLE · SONARDESK SonarDesk {{ $latest->version }} {{ \Illuminate\Support\Str::limit(strip_tags($latest->release_notes ?: 'Native SonarQube monitoring for macOS.'),180) }}
SonarDesk Native code quality dashboard
@endif
-@if($products->isNotEmpty())SOFTWARE LIBRARY Products & alternative downloads Installers are grouped by product, with each available platform and version listed together.
@foreach($products->groupBy('name') as $name => $files){{ $name }} {{ $files->first()->description ?: 'Available downloads and supporting files.' }}
{{ $files->count() }} {{ $files->count() === 1 ? 'download' : 'downloads' }} @foreach($files as $file)
{{ $file->version ? 'Version '.$file->version : ($file->original_filename ?: 'Download') }} {{ $file->platform ?: 'All platforms' }} @if($file->file_size) · {{ number_format($file->file_size / 1048576,1) }} MB @endif
@endforeach
@endforeach @endif
-RELEASE HISTORY SonarDesk versions Full release notes and system requirements are available on each release page.
@forelse($releases as $release)
SonarDesk {{ $release->version }} Build {{ $release->build_number }} · {{ ucfirst($release->channel) }} {{ \Illuminate\Support\Str::limit(strip_tags($release->release_notes ?: 'Release information'),120) }}
@empty
No SonarDesk releases published yet.
@endforelse
\ No newline at end of file
+@extends('sonardesk.layout')
+@section('title','Software downloads and releases')
+@section('content')ABSDEV Software Library Downloads & releases. Find SonarDesk, SonarDisk and alternative installers, grouped by product. Release notes and system requirements are on the detail pages.
+@if($latest)
Latest stable · SonarDesk SonarDesk {{ $latest->version }} {{ \Illuminate\Support\Str::limit(strip_tags($latest->release_notes ?: 'Native SonarQube monitoring for macOS.'), 180) }}
Latest release @endif
+@if($products->isNotEmpty())
Product catalogue Products & alternative downloads Each product lists its available versions and platforms together.
@foreach($products->groupBy('name') as $name=>$files){{ $name }} {{ $files->first()->description ?: 'Installers and supporting downloads.' }}
{{ $files->count() }} {{ $files->count() === 1 ? 'file' : 'files' }} @foreach($files as $file){{ $file->version ? 'Version '.$file->version : ($file->original_filename ?: 'Download') }} {{ $file->platform ?: 'All platforms' }} @if($file->file_size) · {{ number_format($file->file_size/1048576,1) }} MB @endif {{ \Illuminate\Support\Str::limit(strip_tags($file->release_notes ?: $file->description ?: ''),120) }}
@endforeach @endforeach@endif
+
Release archive
SonarDesk release history @forelse($releases as $release)
SonarDesk {{ $release->version }} Build {{ $release->build_number }} · {{ ucfirst($release->channel) }} {{ \Illuminate\Support\Str::limit(strip_tags($release->release_notes ?: 'Release information'),125) }}
@empty
No SonarDesk releases have been published yet.
@endforelse
@endsection
diff --git a/Modules/Licensing/Resources/views/downloads/product.blade.php b/Modules/Licensing/Resources/views/downloads/product.blade.php
index 04a4955..e59b04d 100644
--- a/Modules/Licensing/Resources/views/downloads/product.blade.php
+++ b/Modules/Licensing/Resources/views/downloads/product.blade.php
@@ -1 +1,3 @@
-{{ $product->name }} · ABSDEV ← All downloads PRODUCT DOWNLOAD {{ $product->name }} {{ $product->description }}
Version {{ $product->version ?: 'Unspecified' }} {{ $product->platform ?: 'All platforms' }}
Download {{ $product->original_filename }} ↓ @if($product->release_notes)Release notes {{ $product->release_notes }}
@endif@if($product->minimum_system)System requirements {{ $product->minimum_system }}
@endif
\ No newline at end of file
+@extends('sonardesk.layout')
+@section('title',$product->name.' download')
+@section('content')← All downloads Product download
{{ $product->name }} {{ $product->description }}
{{ $product->platform ?: 'All platforms' }} Version {{ $product->version ?: 'Unspecified' }}
Download {{ $product->original_filename }} ↓ @if($product->release_notes)Full release notes {{ $product->release_notes }}
@endif@if($product->minimum_system)System requirements {{ $product->minimum_system }}
@endif @endsection
diff --git a/Modules/Licensing/Resources/views/downloads/release.blade.php b/Modules/Licensing/Resources/views/downloads/release.blade.php
index bf79a03..52c7a1b 100644
--- a/Modules/Licensing/Resources/views/downloads/release.blade.php
+++ b/Modules/Licensing/Resources/views/downloads/release.blade.php
@@ -1 +1,3 @@
-SonarDesk {{ $release->version }} · ABSDEV ← All downloads SONARDESK · {{ strtoupper($release->channel) }} SonarDesk {{ $release->version }} Build {{ $release->build_number }}
Download {{ $release->original_filename }} ↓ Release notes {{ $release->release_notes ?: 'No release notes provided.' }}
System requirements macOS {{ $release->minimum_macos ?: 'See application documentation' }} or later.
@if($release->sha256)File verification SHA-256
{{ $release->sha256 }} @endif
\ No newline at end of file
+@extends('sonardesk.layout')
+@section('title','SonarDesk '.$release->version.' release notes')
+@section('content')← All downloads SonarDesk · {{ strtoupper($release->channel) }}
SonarDesk {{ $release->version }} Build {{ $release->build_number }}
Download {{ $release->original_filename }} ↓ Full release notes {{ $release->release_notes ?: 'No release notes provided.' }}
System requirements macOS {{ $release->minimum_macos ?: 'See application documentation' }} or later.
@if($release->sha256)File verification · SHA-256 {{ $release->sha256 }}@endif @endsection
diff --git a/public/css/sonardesk-product.css b/public/css/sonardesk-product.css
new file mode 100644
index 0000000..a0eabde
--- /dev/null
+++ b/public/css/sonardesk-product.css
@@ -0,0 +1,2 @@
+/* SonarDesk product UI: follows the original light marketing design, ABSDEV orange accent. */
+:root{--orange:#f97316;--orange-deep:#c2410c;--ink:#172033;--muted:#667085;--line:#e4e7ec;--bg:#f7f9fc;--nav:#0b1220;--surface:#fff}*{box-sizing:border-box}html{scroll-behavior:smooth}body.product-site{margin:0;background:var(--bg);color:var(--ink);font:15px/1.65 -apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",sans-serif;-webkit-font-smoothing:antialiased}a{color:inherit}img{max-width:100%}.product-shell{max-width:1220px;margin:0 auto;padding:0 26px}.product-header{background:var(--nav);color:white;position:sticky;top:0;z-index:30;border-bottom:1px solid #ffffff1a}.header-inner{display:flex;align-items:center;gap:32px;min-height:74px}.product-brand{display:flex;align-items:center;gap:11px;text-decoration:none;white-space:nowrap;font-size:20px}.product-brand span:not(.brand-symbol){color:var(--orange)}.brand-symbol{width:38px;height:38px;display:grid;place-items:center;border-radius:11px;background:var(--orange);color:#fff;font-size:21px;font-weight:900}.product-nav{display:flex;align-items:center;gap:6px;flex:1}.product-nav a,.header-parent{font-weight:650;text-decoration:none;font-size:14px;color:#d7dfed;padding:9px 12px;border-radius:8px}.product-nav a:hover,.header-parent:hover{background:#ffffff18;color:white}.header-parent{color:#ffb784}.product-footer{background:var(--nav);color:#f1f5f9;padding:46px 0}.footer-inner{display:flex;justify-content:space-between;gap:32px}.footer-inner p{color:#aebcd0;margin:6px 0}.footer-links{display:flex;flex-wrap:wrap;gap:22px}.footer-links a{text-decoration:none;color:#d6e0ef}.footer-links a:hover{color:#ffb784}.product-hero{background:linear-gradient(120deg,#0b1220,#18253b);color:#fff;padding:92px 0 98px}.hero-grid{display:grid;grid-template-columns:1.08fr .92fr;gap:54px;align-items:center}.eyebrow{color:var(--orange);text-transform:uppercase;font-weight:850;font-size:12px;letter-spacing:.14em}.product-hero h1{font-size:clamp(46px,5vw,74px);line-height:1.04;letter-spacing:-.055em;margin:16px 0 22px}.product-hero h1 em{font-style:normal;color:#ff9c58}.lead{font-size:19px;line-height:1.65;color:#cdd7e6;max-width:670px}.actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:27px}.button{display:inline-flex;align-items:center;justify-content:center;padding:13px 19px;border-radius:10px;background:var(--orange);color:#fff!important;font-weight:750;text-decoration:none;border:1px solid var(--orange)}.button:hover{background:var(--orange-deep)}.button.secondary{background:transparent;color:inherit!important;border-color:#ffffff55}.button.outline{background:white;color:var(--ink)!important;border-color:var(--line)}.button.small{padding:8px 13px;font-size:13px}.app-window{background:#fff;color:#172033;border-radius:16px;box-shadow:0 24px 70px #0006;overflow:hidden;border:1px solid #ffffff4a}.app-window-bar{background:#eef2f7;padding:14px 18px;display:flex;gap:7px;border-bottom:1px solid #dbe2ea}.app-window-bar i{width:11px;height:11px;border-radius:50%;background:#ff6057}.app-window-bar i:nth-child(2){background:#febc2e}.app-window-bar i:nth-child(3){background:#28c840}.app-window-body{padding:26px}.app-window h3{margin:0 0 18px}.app-stats{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}.app-stat{padding:18px;border-radius:11px;border:1px solid var(--line);background:#fafbfc}.app-stat b{display:block;font-size:23px}.app-stat span{color:var(--muted);font-size:12px}.product-section{padding:76px 0}.product-section.alt{background:#fff}.section-heading{max-width:790px;margin-bottom:32px}.section-heading h2,.page-heading h1{font-size:clamp(34px,3.7vw,49px);letter-spacing:-.04em;line-height:1.12;margin:10px 0 14px}.section-heading p,.page-heading p{color:var(--muted);font-size:17px}.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}.card,.download-group,.detail-panel{background:white;border:1px solid var(--line);border-radius:16px;padding:27px;box-shadow:0 2px 12px #10182808}.card h3{font-size:20px;margin:8px 0}.card p{color:var(--muted)}.card a,.text-link{color:var(--orange-deep);font-weight:750;text-decoration:none}.card a:hover,.text-link:hover{text-decoration:underline}.page-heading{padding:66px 0 32px}.page-heading h1{max-width:850px}.price-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px;max-width:940px}.price-card{background:#fff;border:1px solid var(--line);border-radius:18px;padding:32px}.price-card.featured{border-color:var(--orange);box-shadow:0 16px 42px #f973161a}.price-number{font-size:39px;font-weight:850;letter-spacing:-.05em}.price-number small{font-size:15px;color:var(--muted);letter-spacing:0}.feature-list{padding-left:21px;color:#475467;line-height:2}.callout{background:#121c2e;color:white;border-radius:20px;padding:42px;display:flex;align-items:center;justify-content:space-between;gap:26px}.callout h2{margin:0 0 7px;font-size:29px}.callout p{color:#cbd5e1;margin:0}.download-group{margin:20px 0}.download-group-head{display:flex;justify-content:space-between;gap:16px;align-items:flex-start}.download-group h2{font-size:26px;margin:0 0 6px}.download-group-head p{color:var(--muted);margin:0 0 14px}.badge{display:inline-block;border-radius:999px;padding:4px 11px;background:#fff2e9;color:#a53c0a;font-weight:800;font-size:12px;white-space:nowrap}.download-row{border-top:1px solid var(--line);padding:19px 0;display:flex;justify-content:space-between;gap:20px;align-items:center}.download-row strong{display:block}.download-row small{display:block;color:var(--muted)}.download-row p{margin:5px 0 0;color:var(--muted);max-width:700px}.row-actions{display:flex;align-items:center;gap:15px;white-space:nowrap}.detail-panel{max-width:980px;margin:22px 0 64px}.detail-panel h2{margin:34px 0 10px}.preformatted{white-space:pre-wrap;overflow-wrap:anywhere;color:#475467}.hash{overflow-wrap:anywhere;display:block;padding:13px;background:#f3f5f8;border-radius:8px}.muted{color:var(--muted)}.pagination{margin:26px 0 50px}.pagination nav{max-width:100%}@media(max-width:980px){.hero-grid{grid-template-columns:1fr}.cards{grid-template-columns:repeat(2,1fr)}.product-nav{gap:0}.header-inner{gap:14px}}@media(max-width:700px){.product-header{position:static}.header-inner{flex-wrap:wrap;padding-top:12px;padding-bottom:12px}.product-nav{order:3;flex-basis:100%;overflow-x:auto}.product-nav a{white-space:nowrap}.header-parent{margin-left:auto}.product-hero{padding:60px 0}.cards,.price-grid{grid-template-columns:1fr}.download-row,.download-group-head,.callout,.footer-inner{flex-direction:column;align-items:flex-start}.row-actions{flex-wrap:wrap}.product-section{padding:50px 0}.app-window-body{padding:17px}.product-shell{padding-left:18px;padding-right:18px}}
diff --git a/resources/views/sonardesk/features.blade.php b/resources/views/sonardesk/features.blade.php
index 179e950..dd4ef15 100644
--- a/resources/views/sonardesk/features.blade.php
+++ b/resources/views/sonardesk/features.blade.php
@@ -1,3 +1,3 @@
@extends('sonardesk.layout')
@section('title','SonarDesk Features')
-@section('content')Built for developers Everything important. Nothing distracting. A native Mac workspace for SonarQube project monitoring and issue investigation.
Quality gate status Monitor project health and identify failing quality gates.
Bugs & vulnerabilities Investigate reliability and security findings in context.
Code smells See maintainability issues without switching between browser tabs.
Project management Organise multiple projects and switch between them quickly.
Multiple SonarQube servers Manage connections and access projects across servers.
Export reports Generate project reports for review and further analysis.
@endsection
+@section('content')Features A native workspace for SonarQube. Stay close to your projects, quality gates and issues without the browser overhead.
Quality gates Spot passing and failing projects immediately.
Bugs & vulnerabilities Inspect reliability and security issues in context.
Code smells Explore maintainability findings and issue details.
Multiple projects Keep your project list organised and switch context quickly.
Multiple servers Manage connections to your SonarQube environments.
Export reports Produce project reports for sharing and AI-assisted analysis.
Download SonarDesk Find current installers and complete release notes.
Downloads → @endsection
diff --git a/resources/views/sonardesk/home.blade.php b/resources/views/sonardesk/home.blade.php
index 7743f22..8826aba 100644
--- a/resources/views/sonardesk/home.blade.php
+++ b/resources/views/sonardesk/home.blade.php
@@ -1,7 +1,7 @@
@extends('sonardesk.layout')
-@section('title','SonarDesk — Native SonarQube monitoring for macOS')
+@section('title','SonarDesk — Native SonarQube dashboard for macOS')
@section('content')
-SonarDesk · Native macOS software Code quality.Clearly in view. Bring SonarQube projects, quality gates, bugs, vulnerabilities and code smells together in a focused desktop experience. Spend less time navigating dashboards and more time shipping reliable code.
Project overview ● Quality gate passed
✓ Quality gate
12 Issues to review
3 Projects
1 Security hotspot
Illustrative dashboard — not live project data
-Why SonarDesk Your code health, at a glance. A purpose-built native macOS companion for SonarQube, designed for developers who want useful signals without unnecessary complexity.
01 / Monitor Quality gates See project status, bugs, vulnerabilities and code smells from one dashboard.
02 / Investigate Issue exploration Review issues, navigate details and focus on the changes that matter.
03 / Organise Multiple projects Keep projects and servers organised in a native Mac workspace.
-Get started Everything you need to get moving. Features Explore the native tools built around your SonarQube workflow.
Explore features → Simple pricing Choose Personal or Professional licensing for your needs.
Compare plans → Downloads & updates Find published installers, release history and detailed release notes.
Browse downloads →
+Native macOS · SonarQube Code quality.Without the clutter. A dedicated Mac dashboard for SonarQube. Track quality gates, bugs, vulnerabilities and code smells across projects without living in a browser.
Built for macOS · Multiple SonarQube servers · Native workflow
Project overview Code health at a glance ✓ Passed Quality gate
12 Issues to review
3 Projects
1 Security hotspots
Illustrative preview, not live project data.
+Everything in one workspace See the signals. Investigate the issues. Designed for developers who need actionable SonarQube information without switching tabs.
01 · Monitor Quality gates & metrics See gate status, bugs, vulnerabilities and maintainability at a glance.
02 · Investigate Issue navigation Browse issues and move through details quickly, from one native workspace.
03 · Organise Projects & servers Switch between projects and manage SonarQube server connections.
04 · Share Project reports Export reports for review and AI-assisted analysis.
05 · Native Made for your Mac A focused desktop application that respects macOS workflows.
06 · Explore More than a status badge Drill into code smells, bugs and security findings by project.
+Ready to see your code clearly? Browse the latest installers, release notes and available licence plans.
@endsection
diff --git a/resources/views/sonardesk/layout.blade.php b/resources/views/sonardesk/layout.blade.php
index fe95d02..27be27a 100644
--- a/resources/views/sonardesk/layout.blade.php
+++ b/resources/views/sonardesk/layout.blade.php
@@ -2,8 +2,16 @@
$dedicated = in_array(request()->getHost(), ['sonardesk.absdev.net','sonardesk.co.uk','www.sonardesk.co.uk'], true);
$base = $dedicated ? '' : '/sonardesk';
@endphp
-
-@yield('title','SonarDesk') | ABSDEV
-
-
-@yield('content')
+
+
+@yield('title', 'SonarDesk') · ABSDEV
+
+
+
+@yield('content')
+
+
diff --git a/resources/views/sonardesk/pricing.blade.php b/resources/views/sonardesk/pricing.blade.php
index b60d75b..31ba6cb 100644
--- a/resources/views/sonardesk/pricing.blade.php
+++ b/resources/views/sonardesk/pricing.blade.php
@@ -1,3 +1,3 @@
@extends('sonardesk.layout')
@section('title','SonarDesk Pricing')
-@section('content')Straightforward licensing Choose your SonarDesk plan. Simple subscriptions for native macOS SonarQube monitoring. Checkout is handled by the existing SonarDesk licensing service.
Personal For individual developers £4.99 / month
Or £39.99 per year.
Native project monitoring and issue exploration for your development workflow.
View purchase options → Professional For professional workflows £8.99 / month
Or £79.99 per year.
Professional SonarDesk licensing for developers who work across more projects and environments.
View purchase options → Prices shown are indicative of the existing SonarDesk plans; final terms and available billing options are confirmed by the checkout service.
@endsection
+@section('content')Licensing Choose the right SonarDesk plan. Personal and Professional licensing for a native macOS SonarQube workflow.
Personal For individual developers £4.99 / month
Or £39.99 per year
Native macOS dashboard Project quality gates and issues Organised SonarQube workflow Choose Personal → Professional For professional workflows £8.99 / month
Or £79.99 per year
Professional SonarDesk licence Multi-project workflows Developer-focused issue exploration Choose Professional → Final billing options and terms are shown by the existing licensing checkout.
@endsection