diff --git a/services/web/frontend/stories/page-layouts.stories.tsx b/services/web/frontend/stories/page-layouts.stories.tsx
new file mode 100644
index 0000000000..d482fc641e
--- /dev/null
+++ b/services/web/frontend/stories/page-layouts.stories.tsx
@@ -0,0 +1,297 @@
+import _ from 'lodash'
+import { ComponentType } from 'react'
+import { Navbar } from 'react-bootstrap'
+import OLPageContentCard from '@/shared/components/ol/ol-page-content-card'
+import OLRow from '@/shared/components/ol/ol-row'
+import OLCol from '@/shared/components/ol/ol-col'
+import OLButton from '@/shared/components/ol/ol-button'
+import overleafLogo from '@/shared/svgs/overleaf-a-ds-solution-mallard.svg'
+
+const lorem = (n: number) => {
+ const quacks = ['quack', 'quack', 'quack', 'quak']
+ let result = ''
+ if (n >= 1) result += 'Lorem'
+ if (n >= 2) result += ' epsom'
+ for (let i = 2; i < n; i++) {
+ const next =
+ result.at(-1) === '.'
+ ? ' ' + _.capitalize(quacks[Math.floor(Math.random() * quacks.length)])
+ : quacks[Math.floor(Math.random() * (quacks.length + 1))]
+ result += next ? ' ' + next : '.'
+ }
+ if (result.at(-1) !== '.') result += '.'
+ return result
+}
+
+const Nav = () =>
+
+export const UnsuportedBrowser = () => (
+
+
+
+
+
Unsupported Browser
+
{lorem(60)}
+
+
{lorem(40)}
+
+
+
+
+)
+
+export const Error400 = () => (
+
+
+
+
+
Something went wrong, sorry.
+
{lorem(15)}
+
+
+
+
+)
+
+export const Error404 = () => (
+ <>
+
+
+
+
+
+
Not found
+
{lorem(20)}
+
+
+
+
+ >
+)
+
+export const Closed = () => (
+ <>
+
+
+
+
+
+
+
Maintenance
+
+
{lorem(6)}
+
+
+
+
+ >
+)
+
+export const PlannedMaintenance = () => (
+ <>
+
+
+
+
+
+
+
Planned Maintenance
+
+
{lorem(6)}
+
+
+
+
+ >
+)
+
+export const PostGateway = () => (
+ <>
+
+
+
+
+
+
+
+ Please wait while we process your request.
+
+
+
+
+
+
+
+ >
+)
+
+export const AccountSuspended = () => (
+
+
+
+
+
Your account is suspended
+
{lorem(6)}
+
+
+
+
+)
+
+export const Restricted = () => (
+ <>
+
+
+
+
+
+
+
+ Restricted, sorry you don’t have permission to load this page.
+
+
+
{lorem(23)}
+
+
+
+
+ >
+)
+
+export const OneTimeLogin = () => (
+ <>
+
+
+
+
+
+
+
+
+
We're back!
+
+
Overleaf is now running normally.
+
+
+
+
+
+
+ >
+)
+
+export const Invite = () => (
+
+
+
+
+
+
+
+ max.mustermann@example.com
+ {' '}
+ has invited you to join a group subscription on Overleaf
+
+
+ {lorem(20)}
+
+
+
+
+)
+
+export const NotValid = () => (
+ <>
+
+
+
+
+
+
+
+
+
Invite not valid
+
+
+
+
+
+
+
+
+ >
+)
+
+export const CompleteRegistration = () => (
+ <>
+
+
+
+
+
+
+
+
+
Dropbox Sync
+
+
{lorem(20)}
+
+
+
+
+
+
+ >
+)
+
+export const Ciam = () => (
+
+
+
+
+ Create your Overleaf account
+ {lorem(20)}
+
+ {lorem(20)}
+ Button
+
+
+
+
+)
+
+export default {
+ title: 'Shared / Layouts',
+ args: {
+ label: 'Option',
+ },
+
+ parameters: {
+ layout: 'fullscreen', // This is crucial for vh/vw layouts
+ },
+ decorators: [
+ (Story: ComponentType) => (
+
+
+
+
+ ),
+ ],
+}
diff --git a/services/web/frontend/stylesheets/pages/all.scss b/services/web/frontend/stylesheets/pages/all.scss
index 73cd27d06c..4a93eaadb6 100644
--- a/services/web/frontend/stylesheets/pages/all.scss
+++ b/services/web/frontend/stylesheets/pages/all.scss
@@ -1,4 +1,5 @@
@import 'account-settings';
+@import 'ciam';
@import 'cms';
@import 'content';
@import 'project-list';
diff --git a/services/web/frontend/stylesheets/pages/ciam-colors.scss b/services/web/frontend/stylesheets/pages/ciam-colors.scss
new file mode 100644
index 0000000000..622ff3cf5f
--- /dev/null
+++ b/services/web/frontend/stylesheets/pages/ciam-colors.scss
@@ -0,0 +1,68 @@
+.ciam-layout {
+ --ciam-color-neutral-50: #fafafa;
+ --ciam-color-neutral-100: #f2f2f2;
+ --ciam-color-neutral-200: #e6e6e6;
+ --ciam-color-neutral-300: #d6d6d6;
+ --ciam-color-neutral-400: #c7c7c7;
+ --ciam-color-neutral-500: #b5b5b5;
+ --ciam-color-neutral-600: #a1a1a1;
+ --ciam-color-neutral-700: #8a8a8a;
+ --ciam-color-neutral-800: #6b6b6b;
+ --ciam-color-neutral-900: #383838;
+ --ciam-color-neutral-950: #262626;
+ --ciam-color-green-50: #f2f8f5;
+ --ciam-color-green-100: #e3f2eb;
+ --ciam-color-green-200: #c0e7d6;
+ --ciam-color-green-300: #8adbb7;
+ --ciam-color-green-400: #38cc89;
+ --ciam-color-green-500: #26b072;
+ --ciam-color-green-600: #158954;
+ --ciam-color-green-700: #19754c;
+ --ciam-color-green-800: #196241;
+ --ciam-color-green-900: #164630;
+ --ciam-color-green-950: #112c20;
+ --ciam-color-yellow-50: #fffaeb;
+ --ciam-color-yellow-100: #fff7db;
+ --ciam-color-yellow-200: #ffeeb8;
+ --ciam-color-yellow-300: #ffe58f;
+ --ciam-color-yellow-400: #ffda61;
+ --ciam-color-yellow-500: #ffcc20;
+ --ciam-color-yellow-600: #f0b800;
+ --ciam-color-yellow-700: #d1a000;
+ --ciam-color-yellow-800: #ad8500;
+ --ciam-color-yellow-900: #806200;
+ --ciam-color-yellow-950: #574200;
+ --ciam-color-red-50: #fff5f7;
+ --ciam-color-red-100: #fee7eb;
+ --ciam-color-red-200: #fdc9d3;
+ --ciam-color-red-300: #fba7b7;
+ --ciam-color-red-400: #f97b92;
+ --ciam-color-red-500: #f51d43;
+ --ciam-color-red-600: #e60a32;
+ --ciam-color-red-700: #c3092b;
+ --ciam-color-red-800: #a10723;
+ --ciam-color-red-900: #75051a;
+ --ciam-color-red-950: #530412;
+ --ciam-color-blue-50: #f7fafd;
+ --ciam-color-blue-100: #ecf2f9;
+ --ciam-color-blue-200: #d4e3f2;
+ --ciam-color-blue-300: #bdd4ea;
+ --ciam-color-blue-400: #a2c3e2;
+ --ciam-color-blue-500: #7facd7;
+ --ciam-color-blue-600: #5893cb;
+ --ciam-color-blue-700: #3470a8;
+ --ciam-color-blue-800: #2b5d8c;
+ --ciam-color-blue-900: #1e4161;
+ --ciam-color-blue-950: #17314a;
+ --ciam-color-teal-50: #f1f8f8;
+ --ciam-color-teal-100: #e3f2f1;
+ --ciam-color-teal-200: #c1e2df;
+ --ciam-color-teal-300: #9ed1cd;
+ --ciam-color-teal-400: #6dbab4;
+ --ciam-color-teal-500: #4a9d96;
+ --ciam-color-teal-600: #438e88;
+ --ciam-color-teal-700: #3b7d77;
+ --ciam-color-teal-800: #2f6460;
+ --ciam-color-teal-900: #244c49;
+ --ciam-color-teal-950: #193432;
+}
diff --git a/services/web/frontend/stylesheets/pages/ciam-mixins.scss b/services/web/frontend/stylesheets/pages/ciam-mixins.scss
new file mode 100644
index 0000000000..781ec1e200
--- /dev/null
+++ b/services/web/frontend/stylesheets/pages/ciam-mixins.scss
@@ -0,0 +1,107 @@
+@mixin ciam-body-xs-regular() {
+ font-size: 0.75rem;
+ font-weight: 400;
+ line-height: 1.25rem;
+}
+
+@mixin ciam-body-xs-semibold() {
+ font-size: 0.75rem;
+ font-weight: 600;
+ line-height: 1.25rem;
+}
+
+@mixin ciam-body-sm-regular() {
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: 1.25rem;
+}
+
+@mixin ciam-body-sm-semibold() {
+ font-size: 0.875rem;
+ font-weight: 600;
+ line-height: 1.25rem;
+}
+
+@mixin ciam-body-md-regular() {
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5rem;
+}
+
+@mixin ciam-body-md-semibold() {
+ font-size: 1rem;
+ font-weight: 600;
+ line-height: 1.5rem;
+}
+
+@mixin ciam-body-lg-regular() {
+ font-size: 1.125rem;
+ font-weight: 400;
+ line-height: 1.75rem;
+}
+
+@mixin ciam-body-lg-semibold() {
+ font-size: 1.125rem;
+ font-weight: 600;
+ line-height: 1.75rem;
+}
+
+@mixin ciam-heading-xs-regular() {
+ font-size: 1.125rem;
+ font-weight: 400;
+ line-height: 1.5rem;
+}
+
+@mixin ciam-heading-xs-semibold() {
+ font-size: 1.125rem;
+ font-weight: 600;
+ line-height: 1.5rem;
+}
+
+@mixin ciam-heading-sm-regular() {
+ font-size: 1.25rem;
+ font-weight: 400;
+ line-height: 1.75rem;
+}
+
+@mixin ciam-heading-sm-semibold() {
+ font-size: 1.25rem;
+ font-weight: 600;
+ line-height: 1.75rem;
+}
+
+@mixin ciam-heading-md-regular() {
+ font-size: 1.5rem;
+ font-weight: 400;
+ line-height: 2rem;
+}
+
+@mixin ciam-heading-md-semibold() {
+ font-size: 1.5rem;
+ font-weight: 600;
+ line-height: 2rem;
+}
+
+@mixin ciam-heading-lg-regular() {
+ font-size: 2rem;
+ font-weight: 400;
+ line-height: 2.5rem;
+}
+
+@mixin ciam-heading-lg-semibold() {
+ font-size: 2rem;
+ font-weight: 600;
+ line-height: 2.5rem;
+}
+
+@mixin ciam-heading-xl-regular() {
+ font-size: 2.5rem;
+ font-weight: 400;
+ line-height: 3rem;
+}
+
+@mixin ciam-heading-xl-semibold() {
+ font-size: 2.5rem;
+ font-weight: 600;
+ line-height: 3rem;
+}
diff --git a/services/web/frontend/stylesheets/pages/ciam-variables.scss b/services/web/frontend/stylesheets/pages/ciam-variables.scss
new file mode 100644
index 0000000000..110d25aba8
--- /dev/null
+++ b/services/web/frontend/stylesheets/pages/ciam-variables.scss
@@ -0,0 +1,35 @@
+@import 'ciam-mixins';
+@import 'ciam-colors';
+
+// TODO: Replace `fuchsia` by the correct colors.
+
+.ciam-layout {
+ // Spacings
+ --ciam-spacing-200: 8px;
+ --ciam-spacing-250: 10px;
+ --ciam-spacing-350: 12px;
+ --ciam-spacing-400: 16px;
+ --ciam-spacing-600: 24px; // TODO: confirm this variable name (couldn't find in design system)
+ --ciam-spacing-800: 32px; // TODO: confirm this variable name (couldn't find in design system)
+ --ciam-spacing-1300: 52px;
+
+ // Base variables
+ --ciam-color-text-secondary: var(--ciam-color-neutral-800);
+ --ciam-color-text-primary: var(--ciam-color-neutral-900);
+ --ciam-border-radius-200: var(--ciam-spacing-300);
+ --ciam-border-radius-400: var(--ciam-spacing-400);
+ --ciam-font-family-sans: 'Inter', sans-serif;
+
+ // Links
+ // used in services/web/frontend/stylesheets/base/links.scss
+ --link-color: var(--ciam-color-text-secondary);
+ --link-hover-color: fuchsia;
+
+ // TODO: validate that this is correct
+ --link-visited-color: var(--ciam-color-text-secondary);
+ --link-color-dark: fuchsia;
+ --link-hover-color-dark: fuchsia;
+ --link-visited-color-dark: fuchsia;
+ --link-text-decoration: underline;
+ --link-hover-text-decoration: none;
+}
diff --git a/services/web/frontend/stylesheets/pages/ciam.scss b/services/web/frontend/stylesheets/pages/ciam.scss
new file mode 100644
index 0000000000..cc91d31b92
--- /dev/null
+++ b/services/web/frontend/stylesheets/pages/ciam.scss
@@ -0,0 +1,70 @@
+@import 'ciam-variables';
+@import 'ciam-mixins';
+
+.ciam-layout {
+ padding: var(--ciam-spacing-350);
+ display: flex;
+ min-height: 100%;
+ flex-direction: column;
+ font-family: var(--ciam-font-family-sans), sans-serif;
+ color: var(--ciam-color-text-primary);
+ font-size: var(--ciam-font-size-400);
+ line-height: 1.5;
+
+ @include ciam-body-md-regular;
+
+ .ciam-container {
+ flex: 1 1 auto;
+ }
+
+ .brand {
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-size: contain;
+ height: 64px;
+ width: 130px;
+ margin: var(--ciam-spacing-350) auto;
+ display: block;
+
+ @include media-breakpoint-up(sm) {
+ margin: var(--ciam-spacing-350) var(--ciam-spacing-800);
+ }
+ }
+
+ h1 {
+ @include ciam-heading-sm-semibold;
+ }
+
+ .ciam-card {
+ box-shadow:
+ 0 4px 6px -4px rgb(0 0 0 / 10%),
+ 0 1px 29px -3px rgb(0 0 0 / 16%);
+ padding: var(--ciam-spacing-800) var(--ciam-spacing-400);
+ border-radius: var(--ciam-border-radius-400);
+ max-width: 460px;
+ margin: var(--ciam-spacing-400) auto;
+
+ @include media-breakpoint-up(sm) {
+ padding: var(--ciam-spacing-1300);
+ }
+ }
+
+ footer {
+ display: flex;
+ gap: var(--ciam-spacing-600);
+ text-transform: uppercase;
+ justify-content: center;
+ margin: var(--ciam-spacing-350) auto;
+
+ @include media-breakpoint-up(sm) {
+ margin: var(--ciam-spacing-350) var(--ciam-spacing-800);
+ justify-content: start;
+ }
+
+ a {
+ text-decoration: none;
+
+ @include ciam-body-sm-regular;
+ }
+ }
+}