diff --git a/src/app/features/content-management/components/static-page-preview/static-page-preview.component.html b/src/app/features/content-management/components/static-page-preview/static-page-preview.component.html
new file mode 100644
index 0000000..e9a13dd
--- /dev/null
+++ b/src/app/features/content-management/components/static-page-preview/static-page-preview.component.html
@@ -0,0 +1,19 @@
+
+
+ @for (device of devices; track device.id) {
+
{{ device.labelKey | translate }}
+ }
+
+
+
+ @if (title()) {
+
{{ title() }}
+ }
+
+
+
+
diff --git a/src/app/features/content-management/components/static-page-preview/static-page-preview.component.scss b/src/app/features/content-management/components/static-page-preview/static-page-preview.component.scss
new file mode 100644
index 0000000..34e5fba
--- /dev/null
+++ b/src/app/features/content-management/components/static-page-preview/static-page-preview.component.scss
@@ -0,0 +1,47 @@
+.static-page-preview {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+.static-page-preview__toolbar {
+ display: flex;
+ gap: 0.5rem;
+}
+
+.static-page-preview__viewport {
+ display: flex;
+ justify-content: center;
+ padding: 1rem;
+ background: var(--bg-secondary, #f5f5f5);
+ border-radius: var(--radius-md, 12px);
+ overflow-x: auto;
+}
+
+.static-page-preview__frame {
+ max-width: 100%;
+ background: var(--bg-primary, #fff);
+ border: 1px solid var(--border-color, #d3dad9);
+ border-radius: var(--radius-md, 12px);
+ padding: 1.5rem;
+ box-shadow: var(--shadow-sm, 0 2px 8px rgba(0, 0, 0, 0.1));
+}
+
+.static-page-preview__title {
+ margin: 0 0 1rem;
+ font-size: 1.5rem;
+ font-weight: 700;
+ color: var(--text-primary, #1e3c38);
+}
+
+.static-page-preview__content {
+ color: var(--text-primary, #1e3c38);
+ line-height: 1.6;
+ overflow-wrap: break-word;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .static-page-preview__frame {
+ transition: none;
+ }
+}
diff --git a/src/app/features/content-management/components/static-page-preview/static-page-preview.component.ts b/src/app/features/content-management/components/static-page-preview/static-page-preview.component.ts
new file mode 100644
index 0000000..0cc9968
--- /dev/null
+++ b/src/app/features/content-management/components/static-page-preview/static-page-preview.component.ts
@@ -0,0 +1,55 @@
+import { ChangeDetectionStrategy, Component, SecurityContext, computed, inject, input, signal } from '@angular/core';
+import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
+import { TranslatePipe } from '../../../../i18n/translate.pipe';
+import { ButtonComponent } from '../../../../shared/ui/button/button.component';
+
+export type PreviewDevice = 'desktop' | 'tablet' | 'mobile';
+
+interface DevicePreset {
+ readonly id: PreviewDevice;
+ readonly labelKey: string;
+ readonly width: string;
+}
+
+const DEVICE_PRESETS: readonly DevicePreset[] = [
+ { id: 'desktop', labelKey: 'staticPages.previewDesktop', width: '100%' },
+ { id: 'tablet', labelKey: 'staticPages.previewTablet', width: '768px' },
+ { id: 'mobile', labelKey: 'staticPages.previewMobile', width: '375px' },
+];
+
+/**
+ * Client-side, sanitized preview of a static page's HTML at desktop/tablet/
+ * mobile widths - no navigation, no publish, no dependency on
+ * ProjectEditorPreviewService's full-app reload. Uses the same
+ * DomSanitizer.sanitize(SecurityContext.HTML, ...) pattern as the real
+ * storefront renderer (StaticPageComponent) so what you preview here is
+ * exactly what will render live.
+ */
+@Component({
+ selector: 'app-static-page-preview',
+ standalone: true,
+ imports: [TranslatePipe, ButtonComponent],
+ templateUrl: './static-page-preview.component.html',
+ styleUrl: './static-page-preview.component.scss',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class StaticPagePreviewComponent {
+ private readonly sanitizer = inject(DomSanitizer);
+
+ readonly html = input.required