INBOX/new colour try/preview.html
2026-08-07 15:50:54 +02:00

905 lines
No EOL
23 KiB
HTML

<!doctype html>
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<title>Petrol Login Demo — Refined Dark Mode</title>
<style>
@import url("https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible:wght@400;700&family=Lexend:wght@400;500;600;700&display=swap");
:root {
color-scheme: light;
--font-body: "Atkinson Hyperlegible", "Segoe UI", Arial, sans-serif;
--font-ui: "Lexend", "Segoe UI", Arial, sans-serif;
--page: #f2f6f4;
--page-accent: #e3eeea;
--surface: #ffffff;
--surface-alt: #edf4f1;
--surface-strong: #d9e8e2;
--text: #17343a;
--muted: #64777a;
--border: #c5d7d2;
--petrol: #0b4f58;
--petrol-deep: #063840;
--petrol-soft: #d9ebea;
--secondary: #dfe9e6;
--secondary-hover: #d2e1dc;
--secondary-soft: #edf4f1;
--on-secondary: #17343a;
--teal: #4e978f;
--mint: #cfe5dc;
--lavender: #8d87a8;
--lavender-soft: #eceaf3;
--sand: #c7aa73;
--sand-soft: #f2eadc;
--coral: #c97b70;
--coral-soft: #f5e5e2;
--success: #5f8e72;
--danger: #a9605c;
--focus: #6baea8;
--shadow-lg: 0 28px 70px rgb(7 56 64 / 13%);
--shadow-sm: 0 10px 24px rgb(7 56 64 / 8%);
--radius-sm: 0.55rem;
--radius-md: 0.9rem;
--radius-lg: 1.5rem;
}
html[data-theme="dark"] {
color-scheme: dark;
/* Near-black blue-green foundation */
--page: #03090B;
--page-accent: #071216;
--surface: #0C191D;
--surface-alt: #11252B;
--surface-strong: #19343B;
--text: #EDF6F4;
--muted: #AEC1C0;
--border: #29464D;
/* Deep petrol is now the primary colour */
--petrol: #0E6670;
--petrol-deep: #0A4F58;
--petrol-soft: #17383D;
/* Secondary blue-green */
--secondary: #2B5360;
--secondary-hover: #376775;
--secondary-soft: #162B32;
--on-secondary: #EDF6F4;
--teal: #6EA9A3;
--mint: #2D4A45;
--lavender: #9E99B8;
--lavender-soft: #292738;
--sand: #C9AF7D;
--sand-soft: #393321;
--coral: #CD8B82;
--coral-soft: #3B2B29;
--success: #8DBA98;
--danger: #D28F89;
--focus: #9FD9D3;
--shadow-lg: 0 34px 90px rgb(0 0 0 / 48%);
--shadow-sm: 0 14px 34px rgb(0 0 0 / 34%);
}
html[data-theme="dark"] body {
background:
radial-gradient(
circle at 82% 10%,
rgb(43 83 96 / 22%),
transparent 30%
),
radial-gradient(
circle at 18% 88%,
rgb(14 102 112 / 12%),
transparent 34%
),
linear-gradient(145deg, var(--page), var(--page-accent));
}
html[data-theme="dark"] .visual-panel {
background:
linear-gradient(150deg, rgb(5 48 55 / 98%), rgb(10 79 88 / 96%)),
linear-gradient(45deg, var(--petrol-deep), var(--petrol));
}
html[data-theme="dark"] .visual-panel::before {
background: rgb(110 169 163 / 12%);
}
html[data-theme="dark"] .visual-panel::after {
background: rgb(43 83 96 / 26%);
}
html[data-theme="dark"] .login-panel {
background: color-mix(in srgb, var(--page-accent) 78%, transparent);
}
html[data-theme="dark"] .login-card {
background: color-mix(in srgb, var(--surface) 98%, transparent);
}
* {
box-sizing: border-box;
}
html {
font-family: var(--font-body);
font-size: 18px;
line-height: 1.62;
background: var(--page);
color: var(--text);
text-rendering: optimizeLegibility;
}
body {
min-height: 100vh;
margin: 0;
background:
radial-gradient(circle at 12% 10%, color-mix(in srgb, var(--mint) 42%, transparent), transparent 28%),
radial-gradient(circle at 88% 16%, color-mix(in srgb, var(--lavender-soft) 72%, transparent), transparent 26%),
linear-gradient(145deg, var(--page), var(--page-accent));
}
button,
input {
font: inherit;
}
button,
a {
-webkit-tap-highlight-color: transparent;
}
a {
color: var(--petrol);
text-decoration-thickness: 0.08em;
text-underline-offset: 0.18em;
}
a:hover {
color: var(--petrol-deep);
}
:focus-visible {
outline: 3px solid var(--focus);
outline-offset: 3px;
}
.page-shell {
min-height: 100vh;
display: grid;
grid-template-columns: minmax(0, 1.05fr) minmax(360px, 0.95fr);
}
.visual-panel {
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 100vh;
padding: clamp(2rem, 5vw, 4.5rem);
color: #effaf8;
background:
linear-gradient(150deg, rgb(6 56 64 / 96%), rgb(12 79 87 / 94%)),
linear-gradient(45deg, #063840, #0b4f58);
}
.visual-panel::before,
.visual-panel::after {
content: "";
position: absolute;
border-radius: 999px;
opacity: 0.9;
filter: blur(2px);
}
.visual-panel::before {
width: 24rem;
height: 24rem;
top: -8rem;
right: -8rem;
background: rgb(207 229 220 / 16%);
}
.visual-panel::after {
width: 18rem;
height: 18rem;
left: -7rem;
bottom: -6rem;
background: rgb(141 135 168 / 18%);
}
.brand,
.hero-copy,
.trust-row {
position: relative;
z-index: 1;
}
.brand {
display: inline-flex;
align-items: center;
gap: 0.8rem;
font-family: var(--font-ui);
font-weight: 700;
letter-spacing: -0.02em;
}
.brand-mark {
display: grid;
place-items: center;
width: 2.7rem;
aspect-ratio: 1;
border: 1px solid rgb(255 255 255 / 30%);
border-radius: 0.85rem;
background: rgb(255 255 255 / 10%);
backdrop-filter: blur(10px);
box-shadow: inset 0 1px 0 rgb(255 255 255 / 18%);
}
.brand-mark svg {
width: 1.55rem;
height: 1.55rem;
}
.hero-copy {
max-width: 34rem;
margin-block: auto;
padding-block: 4rem;
}
.eyebrow {
margin: 0 0 0.8rem;
color: #cfe5dc;
font-family: var(--font-ui);
font-size: 0.84rem;
font-weight: 700;
letter-spacing: 0.11em;
text-transform: uppercase;
}
h1,
h2 {
margin: 0;
font-family: var(--font-ui);
line-height: 1.14;
letter-spacing: -0.035em;
}
.hero-copy h1 {
max-width: 11ch;
font-size: clamp(2.7rem, 6vw, 5.6rem);
}
.hero-copy p {
max-width: 34rem;
margin: 1.4rem 0 0;
color: rgb(239 250 248 / 82%);
font-size: 1.08rem;
}
.feature-list {
display: grid;
gap: 0.8rem;
margin: 2rem 0 0;
padding: 0;
list-style: none;
}
.feature-list li {
display: flex;
gap: 0.7rem;
align-items: flex-start;
color: rgb(239 250 248 / 90%);
}
.feature-list svg {
flex: 0 0 auto;
width: 1.1rem;
margin-top: 0.23rem;
}
.trust-row {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
color: rgb(239 250 248 / 72%);
font-size: 0.86rem;
}
.trust-pill {
padding: 0.35rem 0.62rem;
border: 1px solid rgb(255 255 255 / 20%);
border-radius: 999px;
background: rgb(255 255 255 / 8%);
}
.login-panel {
position: relative;
display: grid;
place-items: center;
min-height: 100vh;
padding: clamp(1.2rem, 4vw, 3rem);
background: color-mix(in srgb, var(--surface) 52%, transparent);
backdrop-filter: blur(14px);
}
.theme-toggle {
position: absolute;
top: 1.3rem;
right: 1.3rem;
display: inline-flex;
gap: 0.35rem;
padding: 0.32rem;
border: 1px solid var(--border);
border-radius: 999px;
background: color-mix(in srgb, var(--secondary-soft) 92%, transparent);
box-shadow: var(--shadow-sm);
}
.theme-toggle button {
display: grid;
place-items: center;
width: 2.2rem;
aspect-ratio: 1;
padding: 0;
color: var(--muted);
border: 0;
border-radius: 999px;
background: transparent;
cursor: pointer;
}
.theme-toggle button[aria-pressed="true"] {
color: var(--text);
background: var(--surface-strong);
}
.theme-toggle svg {
width: 1rem;
height: 1rem;
}
.login-card {
width: min(100%, 28rem);
padding: clamp(1.35rem, 4vw, 2.35rem);
background: color-mix(in srgb, var(--surface) 97%, transparent);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
}
.login-card header {
margin-bottom: 1.8rem;
}
.login-card h2 {
font-size: clamp(1.8rem, 4vw, 2.35rem);
}
.login-card header p {
margin: 0.65rem 0 0;
color: var(--muted);
}
.field {
margin-bottom: 1.15rem;
}
.field-row {
display: flex;
justify-content: space-between;
gap: 1rem;
align-items: center;
margin-bottom: 0.42rem;
}
label {
font-family: var(--font-ui);
font-size: 0.93rem;
font-weight: 700;
}
.field-row a {
font-size: 0.88rem;
}
.input-wrap {
position: relative;
}
input[type="email"],
input[type="password"],
input[type="text"] {
width: 100%;
min-height: 3.15rem;
padding: 0.78rem 0.95rem;
color: var(--text);
background: var(--surface-alt);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
transition:
border-color 140ms ease,
background-color 140ms ease,
box-shadow 140ms ease;
}
input::placeholder {
color: var(--muted);
opacity: 0.82;
}
input:hover {
border-color: color-mix(in srgb, var(--border) 55%, var(--petrol));
}
input:focus {
border-color: var(--petrol);
background: var(--surface);
box-shadow: 0 0 0 4px color-mix(in srgb, var(--focus) 22%, transparent);
outline: none;
}
.password-input {
padding-right: 3.1rem;
}
.show-password {
position: absolute;
inset: 50% 0.55rem auto auto;
display: grid;
place-items: center;
width: 2.2rem;
aspect-ratio: 1;
padding: 0;
color: var(--muted);
border: 0;
border-radius: 0.55rem;
background: transparent;
transform: translateY(-50%);
cursor: pointer;
}
.show-password:hover {
color: var(--text);
background: var(--surface-strong);
}
.show-password svg {
width: 1.05rem;
height: 1.05rem;
}
.form-options {
display: flex;
justify-content: space-between;
gap: 1rem;
align-items: center;
margin: 0.2rem 0 1.25rem;
}
.checkbox-label {
display: inline-flex;
gap: 0.55rem;
align-items: center;
color: var(--muted);
font-family: var(--font-body);
font-size: 0.94rem;
font-weight: 400;
cursor: pointer;
}
input[type="checkbox"] {
width: 1.05rem;
height: 1.05rem;
margin: 0;
accent-color: var(--petrol);
}
.primary-button {
width: 100%;
min-height: 3.15rem;
padding: 0.8rem 1rem;
color: var(--on-primary);
background: var(--petrol);
border: 1px solid var(--petrol);
border-radius: var(--radius-sm);
font-family: var(--font-ui);
font-weight: 700;
cursor: pointer;
box-shadow: 0 10px 22px color-mix(in srgb, var(--petrol) 22%, transparent);
transition:
transform 140ms ease,
background-color 140ms ease,
box-shadow 140ms ease;
}
.primary-button:hover {
background: var(--petrol-deep);
transform: translateY(-1px);
box-shadow: 0 14px 30px color-mix(in srgb, var(--petrol) 26%, transparent);
}
.primary-button:active {
transform: translateY(0);
}
.divider {
display: grid;
grid-template-columns: 1fr auto 1fr;
gap: 0.8rem;
align-items: center;
margin: 1.3rem 0;
color: var(--muted);
font-size: 0.84rem;
}
.divider::before,
.divider::after {
content: "";
height: 1px;
background: var(--border);
}
.secondary-button {
width: 100%;
min-height: 3rem;
display: inline-flex;
justify-content: center;
gap: 0.7rem;
align-items: center;
padding: 0.72rem 1rem;
color: var(--on-secondary);
background: var(--secondary);
border: 1px solid color-mix(in srgb, var(--secondary) 72%, var(--border));
border-radius: var(--radius-sm);
font-family: var(--font-ui);
font-weight: 600;
cursor: pointer;
}
.secondary-button:hover {
background: var(--secondary-hover);
}
.secondary-button svg {
width: 1.15rem;
height: 1.15rem;
}
.signup-note {
margin: 1.4rem 0 0;
color: var(--muted);
text-align: center;
font-size: 0.94rem;
}
.helper-message {
display: none;
margin: 0.5rem 0 0;
padding: 0.58rem 0.7rem;
color: var(--danger);
background: var(--coral-soft);
border-left: 0.3rem solid var(--danger);
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
font-size: 0.87rem;
}
.helper-message.visible {
display: block;
}
.privacy-note {
width: min(100%, 28rem);
margin: 1rem auto 0;
color: var(--muted);
font-size: 0.82rem;
text-align: center;
}
@media (max-width: 900px) {
.page-shell {
grid-template-columns: 1fr;
}
.visual-panel {
min-height: auto;
padding: 1.5rem 1.2rem 2rem;
}
.hero-copy {
margin: 2.5rem 0 0;
padding: 0;
}
.hero-copy h1 {
max-width: 14ch;
font-size: clamp(2.4rem, 10vw, 4rem);
}
.feature-list,
.trust-row {
display: none;
}
.login-panel {
min-height: auto;
padding: 1.2rem 1rem 2.5rem;
}
.theme-toggle {
top: 1rem;
right: 1rem;
}
}
@media (max-width: 520px) {
html {
font-size: 17px;
}
.login-card {
padding: 1.25rem;
border-radius: 1.15rem;
}
.form-options {
align-items: flex-start;
flex-direction: column;
gap: 0.7rem;
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
scroll-behavior: auto !important;
transition-duration: 0.01ms !important;
}
}
</style>
</head>
<body>
<main class="page-shell">
<section class="visual-panel" aria-labelledby="welcome-title">
<div class="brand">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M5 15.5 12 4l7 11.5-7 4.5-7-4.5Z" stroke="currentColor" stroke-width="1.7"/>
<circle cx="12" cy="12" r="2.2" fill="currentColor"/>
</svg>
</span>
<span>Calmspace</span>
</div>
<div class="hero-copy">
<p class="eyebrow">Clear space. Clear mind.</p>
<h1 id="welcome-title">Work with focus, not friction.</h1>
<p>
A calmer workspace for planning, tracking and finishing what matters—
without clutter, noise or unnecessary decisions.
</p>
<ul class="feature-list">
<li>
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="m5 12 4 4L19 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Clear visual hierarchy and predictable navigation
</li>
<li>
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="m5 12 4 4L19 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Low-noise colours designed for longer sessions
</li>
<li>
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="m5 12 4 4L19 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Readable typography with generous spacing
</li>
</ul>
</div>
<div class="trust-row" aria-label="Product qualities">
<span class="trust-pill">Private by design</span>
<span class="trust-pill">Accessible</span>
<span class="trust-pill">Distraction-aware</span>
</div>
</section>
<section class="login-panel" aria-labelledby="login-title">
<div class="theme-toggle" aria-label="Theme">
<button type="button" data-theme="light" aria-label="Use light mode" aria-pressed="true">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<circle cx="12" cy="12" r="4" stroke="currentColor" stroke-width="1.8"/>
<path d="M12 2v2M12 20v2M4.93 4.93l1.42 1.42M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.42-1.42M17.66 6.34l1.41-1.41" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
</svg>
</button>
<button type="button" data-theme="dark" aria-label="Use dark mode" aria-pressed="false">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M20 15.2A8.3 8.3 0 0 1 8.8 4 8.3 8.3 0 1 0 20 15.2Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
</svg>
</button>
</div>
<div>
<form class="login-card" id="login-form" novalidate>
<header>
<h2 id="login-title">Welcome back</h2>
<p>Sign in to continue to your workspace.</p>
</header>
<div class="field">
<label for="email">Email address</label>
<div class="input-wrap">
<input
id="email"
name="email"
type="email"
autocomplete="email"
placeholder="name@example.com"
required>
</div>
<p class="helper-message" id="email-error">
Enter a valid email address.
</p>
</div>
<div class="field">
<div class="field-row">
<label for="password">Password</label>
<a href="#">Forgot password?</a>
</div>
<div class="input-wrap">
<input
class="password-input"
id="password"
name="password"
type="password"
autocomplete="current-password"
placeholder="Enter your password"
minlength="8"
required>
<button
class="show-password"
type="button"
aria-label="Show password"
aria-pressed="false">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M2.5 12s3.5-5.5 9.5-5.5 9.5 5.5 9.5 5.5-3.5 5.5-9.5 5.5S2.5 12 2.5 12Z" stroke="currentColor" stroke-width="1.7"/>
<circle cx="12" cy="12" r="2.5" stroke="currentColor" stroke-width="1.7"/>
</svg>
</button>
</div>
<p class="helper-message" id="password-error">
Your password must contain at least eight characters.
</p>
</div>
<div class="form-options">
<label class="checkbox-label">
<input type="checkbox" name="remember">
Keep me signed in
</label>
</div>
<button class="primary-button" type="submit">
Sign in
</button>
<div class="divider">or continue with</div>
<button class="secondary-button" type="button">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.7"/>
<path d="M8.5 12h7M12 8.5v7" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/>
</svg>
Single sign-on
</button>
<p class="signup-note">
New here? <a href="#">Create an account</a>
</p>
</form>
<p class="privacy-note">
By signing in, you agree to the terms and privacy policy.
</p>
</div>
</section>
</main>
<script>
const root = document.documentElement;
const themeButtons = document.querySelectorAll("[data-theme]");
const passwordInput = document.querySelector("#password");
const passwordToggle = document.querySelector(".show-password");
const loginForm = document.querySelector("#login-form");
const emailInput = document.querySelector("#email");
const emailError = document.querySelector("#email-error");
const passwordError = document.querySelector("#password-error");
const setTheme = (theme) => {
root.dataset.theme = theme;
themeButtons.forEach((button) => {
button.setAttribute(
"aria-pressed",
String(button.dataset.theme === theme)
);
});
localStorage.setItem("calmspace-theme", theme);
};
const storedTheme = localStorage.getItem("calmspace-theme");
const preferredTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
setTheme(storedTheme || preferredTheme);
themeButtons.forEach((button) => {
button.addEventListener("click", () => {
setTheme(button.dataset.theme);
});
});
passwordToggle.addEventListener("click", () => {
const isVisible = passwordInput.type === "text";
passwordInput.type = isVisible ? "password" : "text";
passwordToggle.setAttribute("aria-pressed", String(!isVisible));
passwordToggle.setAttribute(
"aria-label",
isVisible ? "Show password" : "Hide password"
);
});
loginForm.addEventListener("submit", (event) => {
event.preventDefault();
const emailInvalid = !emailInput.validity.valid;
const passwordInvalid = !passwordInput.validity.valid;
emailError.classList.toggle("visible", emailInvalid);
passwordError.classList.toggle("visible", passwordInvalid);
emailInput.setAttribute("aria-invalid", String(emailInvalid));
passwordInput.setAttribute("aria-invalid", String(passwordInvalid));
if (!emailInvalid && !passwordInvalid) {
alert("Demo only: the login form is visually complete but not connected to a backend.");
}
});
</script>
</body>
</html>