diff --git a/src/app/app.html b/src/app/app.html
index d85eb68..dba92a9 100644
--- a/src/app/app.html
+++ b/src/app/app.html
@@ -1 +1,5 @@
-
\ No newline at end of file
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/app.scss b/src/app/app.scss
index e40dd26..9b823de 100644
--- a/src/app/app.scss
+++ b/src/app/app.scss
@@ -1,2 +1,12 @@
-:host { display: block; min-height: 100dvh; }
+:host {
+ display: flex;
+ flex-direction: column;
+ min-height: 100dvh;
+}
+
+.app-main {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
diff --git a/src/app/app.ts b/src/app/app.ts
index 2639d94..1a4c6b3 100644
--- a/src/app/app.ts
+++ b/src/app/app.ts
@@ -1,9 +1,11 @@
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
+import { SiteHeader } from './site-header/site-header';
+import { SiteFooter } from './site-footer/site-footer';
@Component({
selector: 'app-root',
- imports: [RouterOutlet],
+ imports: [RouterOutlet, SiteHeader, SiteFooter],
templateUrl: './app.html',
styleUrl: './app.scss'
})
diff --git a/src/app/site-footer/site-footer.html b/src/app/site-footer/site-footer.html
new file mode 100644
index 0000000..f8acadc
--- /dev/null
+++ b/src/app/site-footer/site-footer.html
@@ -0,0 +1,60 @@
+
diff --git a/src/app/site-footer/site-footer.scss b/src/app/site-footer/site-footer.scss
new file mode 100644
index 0000000..5f0beb4
--- /dev/null
+++ b/src/app/site-footer/site-footer.scss
@@ -0,0 +1,156 @@
+:host { display: block; }
+
+.site-footer {
+ background: #0f172a;
+ color: #94a3b8;
+
+ &__inner {
+ max-width: 1100px;
+ margin: 0 auto;
+ padding: 48px 24px 32px;
+ display: grid;
+ grid-template-columns: 2fr 1fr 1fr;
+ gap: 40px;
+
+ @media (max-width: 860px) {
+ grid-template-columns: 1fr 1fr;
+ }
+
+ @media (max-width: 560px) {
+ grid-template-columns: 1fr;
+ gap: 32px;
+ padding: 36px 20px 24px;
+ }
+ }
+
+ &__col {
+ &--brand {
+ @media (max-width: 860px) {
+ grid-column: 1 / -1;
+ }
+ }
+ }
+
+ &__brand {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ text-decoration: none;
+ margin-bottom: 14px;
+
+ img {
+ width: 28px;
+ height: 28px;
+ object-fit: contain;
+ filter: brightness(0) invert(1);
+ opacity: 0.9;
+ }
+ }
+
+ &__wordmark {
+ font-size: 18px;
+ letter-spacing: -0.02em;
+ line-height: 1;
+ }
+
+ &__desc {
+ font-size: 13.5px;
+ line-height: 1.65;
+ color: #64748b;
+ max-width: 380px;
+ }
+
+ &__heading {
+ font-size: 12px;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.8px;
+ color: #e2e8f0;
+ margin-bottom: 16px;
+ }
+
+ &__list {
+ list-style: none;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ margin-bottom: 18px;
+
+ li {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 13.5px;
+
+ svg { flex-shrink: 0; opacity: 0.5; }
+ }
+
+ a {
+ color: #94a3b8;
+ text-decoration: none;
+ transition: color 0.15s;
+
+ &:hover { color: #e2e8f0; }
+ }
+
+ &--legal {
+ li {
+ display: block;
+ font-size: 12.5px;
+ color: #64748b;
+ gap: 0;
+ }
+ }
+ }
+
+ &__note {
+ font-size: 11px;
+ color: #475569;
+ margin-left: 4px;
+ }
+
+ &__hours {
+ font-size: 12.5px;
+ color: #64748b;
+ line-height: 1.7;
+ }
+
+ &__address {
+ color: #475569;
+ font-size: 12px !important;
+ line-height: 1.5;
+ margin-top: 4px;
+ }
+
+ &__bottom {
+ border-top: 1px solid #1e293b;
+ max-width: 1100px;
+ margin: 0 auto;
+ padding: 16px 24px;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px 24px;
+ justify-content: space-between;
+ font-size: 12px;
+ color: #475569;
+
+ @media (max-width: 560px) {
+ flex-direction: column;
+ padding: 14px 20px;
+ }
+ }
+}
+
+.wm-fast {
+ font-weight: 400;
+ font-size: 0.72em;
+ color: #64748b;
+ margin-right: 0.04em;
+}
+.wm-check {
+ font-weight: 700;
+ font-size: 1em;
+ color: #93c5fd;
+ text-transform: uppercase;
+ letter-spacing: 0.03em;
+}
diff --git a/src/app/site-footer/site-footer.ts b/src/app/site-footer/site-footer.ts
new file mode 100644
index 0000000..cf8101b
--- /dev/null
+++ b/src/app/site-footer/site-footer.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-site-footer',
+ templateUrl: './site-footer.html',
+ styleUrl: './site-footer.scss'
+})
+export class SiteFooter {
+ year = new Date().getFullYear();
+}
diff --git a/src/app/site-header/site-header.html b/src/app/site-header/site-header.html
new file mode 100644
index 0000000..bc6aa38
--- /dev/null
+++ b/src/app/site-header/site-header.html
@@ -0,0 +1,46 @@
+
diff --git a/src/app/site-header/site-header.scss b/src/app/site-header/site-header.scss
new file mode 100644
index 0000000..c977834
--- /dev/null
+++ b/src/app/site-header/site-header.scss
@@ -0,0 +1,131 @@
+:host {
+ display: block;
+ position: sticky;
+ top: 0;
+ z-index: 900;
+}
+
+.site-header {
+ background: #fff;
+ border-bottom: 1px solid #e2e8f0;
+ box-shadow: 0 1px 8px rgba(0, 0, 0, 0.06);
+
+ &__inner {
+ max-width: 1100px;
+ margin: 0 auto;
+ padding: 0 24px;
+ height: 60px;
+ display: flex;
+ align-items: center;
+ gap: 32px;
+
+ @media (max-width: 600px) {
+ padding: 0 16px;
+ }
+ }
+
+ &__brand {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ text-decoration: none;
+ flex-shrink: 0;
+
+ img {
+ width: 32px;
+ height: 32px;
+ object-fit: contain;
+ }
+ }
+
+ &__wordmark {
+ font-size: 18px;
+ letter-spacing: -0.02em;
+ white-space: nowrap;
+ line-height: 1;
+ }
+
+ &__nav {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ margin-left: auto;
+
+ @media (max-width: 600px) {
+ display: none;
+ }
+ }
+
+ &__link {
+ padding: 8px 14px;
+ border-radius: 8px;
+ font-size: 14px;
+ font-weight: 500;
+ color: #475569;
+ text-decoration: none;
+ transition: background 0.15s, color 0.15s;
+
+ &:hover {
+ background: #f1f5f9;
+ color: #0f172a;
+ }
+ }
+
+ &__burger {
+ display: none;
+ margin-left: auto;
+ width: 40px;
+ height: 40px;
+ border-radius: 8px;
+ border: none;
+ background: transparent;
+ color: #475569;
+ cursor: pointer;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.15s;
+ -webkit-appearance: none;
+ font-family: inherit;
+
+ &:hover { background: #f1f5f9; }
+
+ @media (max-width: 600px) {
+ display: inline-flex;
+ }
+ }
+
+ &__mobile-menu {
+ border-top: 1px solid #e2e8f0;
+ display: flex;
+ flex-direction: column;
+ padding: 8px 12px 12px;
+ background: #fff;
+ }
+
+ &__mobile-link {
+ padding: 12px 14px;
+ border-radius: 10px;
+ font-size: 15px;
+ font-weight: 500;
+ color: #0f172a;
+ text-decoration: none;
+ transition: background 0.15s;
+
+ &:hover { background: #f1f5f9; }
+ }
+}
+
+// Wordmark colours
+.wm-fast {
+ font-weight: 400;
+ font-size: 0.72em;
+ color: #64748b;
+ margin-right: 0.04em;
+}
+.wm-check {
+ font-weight: 700;
+ font-size: 1em;
+ color: #1e40af;
+ text-transform: uppercase;
+ letter-spacing: 0.03em;
+}
diff --git a/src/app/site-header/site-header.ts b/src/app/site-header/site-header.ts
new file mode 100644
index 0000000..2152d6e
--- /dev/null
+++ b/src/app/site-header/site-header.ts
@@ -0,0 +1,14 @@
+import { Component, signal } from '@angular/core';
+import { RouterLink } from '@angular/router';
+
+@Component({
+ selector: 'app-site-header',
+ imports: [RouterLink],
+ templateUrl: './site-header.html',
+ styleUrl: './site-header.scss'
+})
+export class SiteHeader {
+ menuOpen = signal(false);
+ toggleMenu(): void { this.menuOpen.update(v => !v); }
+ closeMenu(): void { this.menuOpen.set(false); }
+}
diff --git a/src/shared.scss b/src/shared.scss
index 241b99e..3fc0239 100644
--- a/src/shared.scss
+++ b/src/shared.scss
@@ -2,7 +2,7 @@
// Imported via @use './../../../shared' as *;
.page {
- min-height: 100dvh;
+ flex: 1;
display: flex;
align-items: center;
justify-content: center;
@@ -29,7 +29,7 @@
border-radius: 0;
max-width: 100%;
box-shadow: none;
- min-height: 100dvh;
+ flex: 1;
display: flex;
flex-direction: column;
}