829 lines
25 KiB
HTML
829 lines
25 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>Burgundy & Dusty Rose — ADHD-Friendly Login Demo</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: #FBF7F8;
|
|
--page-accent: #F2E6E9;
|
|
--surface: #FFFFFF;
|
|
--surface-alt: #F8EEF1;
|
|
--surface-strong: #EBDADF;
|
|
--text: #38272D;
|
|
--muted: #75656B;
|
|
--border: #DFC9D0;
|
|
--primary: #7E374D;
|
|
--primary-hover: #61263A;
|
|
--on-primary: #FFFFFF;
|
|
--secondary: #E7D8DE;
|
|
--secondary-hover: #D9C5CD;
|
|
--on-secondary: #38272D;
|
|
--accent-1: #B07D8D;
|
|
--accent-2: #718B92;
|
|
--accent-3: #C0A06F;
|
|
--danger: #A64E5D;
|
|
--danger-soft: #F4E3E7;
|
|
--success: #698873;
|
|
--focus: #BD8D9D;
|
|
--shadow-lg: 0 28px 70px color-mix(in srgb, var(--primary) 14%, transparent);
|
|
--shadow-sm: 0 10px 24px color-mix(in srgb, var(--primary) 9%, transparent);
|
|
--radius-sm: .55rem;
|
|
--radius-md: .9rem;
|
|
--radius-lg: 1.5rem;
|
|
}
|
|
|
|
html[data-theme="dark"] {
|
|
color-scheme: dark;
|
|
--page: #050203;
|
|
--page-accent: #0C0608;
|
|
--surface: #170D11;
|
|
--surface-alt: #24151B;
|
|
--surface-strong: #38202A;
|
|
--text: #F8EFF2;
|
|
--muted: #CABAC0;
|
|
--border: #583B46;
|
|
--primary: #B85F7A;
|
|
--primary-hover: #99445F;
|
|
--on-primary: #290E17;
|
|
--secondary: #624754;
|
|
--secondary-hover: #765867;
|
|
--on-secondary: #F8EFF2;
|
|
--accent-1: #C78DA0;
|
|
--accent-2: #7D9BA1;
|
|
--accent-3: #D0B17B;
|
|
--danger: #DA8795;
|
|
--danger-soft: #42272F;
|
|
--success: #90B098;
|
|
--focus: #D9A8B8;
|
|
--shadow-lg: 0 38px 96px rgb(0 0 0 / 58%);
|
|
--shadow-sm: 0 16px 38px rgb(0 0 0 / 42%);
|
|
}
|
|
|
|
* { 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(--accent-2) 16%, transparent), transparent 28%),
|
|
radial-gradient(circle at 88% 16%, color-mix(in srgb, var(--accent-1) 13%, 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(--primary);
|
|
text-decoration-thickness: .08em;
|
|
text-underline-offset: .18em;
|
|
}
|
|
|
|
a:hover { color: var(--primary-hover); }
|
|
|
|
: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, .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: var(--on-primary);
|
|
background:
|
|
radial-gradient(circle at 80% 18%, color-mix(in srgb, var(--accent-1) 20%, transparent), transparent 30%),
|
|
radial-gradient(circle at 20% 82%, color-mix(in srgb, var(--accent-2) 18%, transparent), transparent 34%),
|
|
linear-gradient(150deg, var(--primary-hover), var(--primary));
|
|
}
|
|
|
|
.visual-panel::before,
|
|
.visual-panel::after {
|
|
content: "";
|
|
position: absolute;
|
|
border-radius: 999px;
|
|
opacity: .9;
|
|
filter: blur(2px);
|
|
}
|
|
|
|
.visual-panel::before {
|
|
width: 24rem;
|
|
height: 24rem;
|
|
top: -8rem;
|
|
right: -8rem;
|
|
background: color-mix(in srgb, var(--accent-1) 20%, transparent);
|
|
}
|
|
|
|
.visual-panel::after {
|
|
width: 18rem;
|
|
height: 18rem;
|
|
left: -7rem;
|
|
bottom: -6rem;
|
|
background: color-mix(in srgb, var(--accent-2) 22%, transparent);
|
|
}
|
|
|
|
.brand, .hero-copy, .trust-row {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.brand {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: .8rem;
|
|
font-family: var(--font-ui);
|
|
font-weight: 700;
|
|
letter-spacing: -.02em;
|
|
}
|
|
|
|
.brand-mark {
|
|
display: grid;
|
|
place-items: center;
|
|
width: 2.7rem;
|
|
aspect-ratio: 1;
|
|
border: 1px solid color-mix(in srgb, var(--on-primary) 30%, transparent);
|
|
border-radius: .85rem;
|
|
background: color-mix(in srgb, var(--on-primary) 10%, transparent);
|
|
backdrop-filter: blur(10px);
|
|
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--on-primary) 18%, transparent);
|
|
}
|
|
|
|
.brand-mark svg { width: 1.55rem; height: 1.55rem; }
|
|
|
|
.hero-copy {
|
|
max-width: 34rem;
|
|
margin-block: auto;
|
|
padding-block: 4rem;
|
|
}
|
|
|
|
.eyebrow {
|
|
margin: 0 0 .8rem;
|
|
color: color-mix(in srgb, var(--on-primary) 80%, var(--accent-3));
|
|
font-family: var(--font-ui);
|
|
font-size: .84rem;
|
|
font-weight: 700;
|
|
letter-spacing: .11em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
h1, h2 {
|
|
margin: 0;
|
|
font-family: var(--font-ui);
|
|
line-height: 1.14;
|
|
letter-spacing: -.035em;
|
|
}
|
|
|
|
.hero-copy h1 {
|
|
max-width: 12ch;
|
|
font-size: clamp(2.7rem, 6vw, 5.6rem);
|
|
}
|
|
|
|
.hero-copy p {
|
|
max-width: 34rem;
|
|
margin: 1.4rem 0 0;
|
|
color: color-mix(in srgb, var(--on-primary) 84%, transparent);
|
|
font-size: 1.08rem;
|
|
}
|
|
|
|
.feature-list {
|
|
display: grid;
|
|
gap: .8rem;
|
|
margin: 2rem 0 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
|
|
.feature-list li {
|
|
display: flex;
|
|
gap: .7rem;
|
|
align-items: flex-start;
|
|
color: color-mix(in srgb, var(--on-primary) 90%, transparent);
|
|
}
|
|
|
|
.feature-list svg {
|
|
flex: 0 0 auto;
|
|
width: 1.1rem;
|
|
margin-top: .23rem;
|
|
}
|
|
|
|
.feature-list li:nth-child(1) svg { color: color-mix(in srgb, var(--on-primary) 72%, var(--accent-1)); }
|
|
.feature-list li:nth-child(2) svg { color: color-mix(in srgb, var(--on-primary) 72%, var(--accent-2)); }
|
|
.feature-list li:nth-child(3) svg { color: color-mix(in srgb, var(--on-primary) 72%, var(--accent-3)); }
|
|
|
|
.trust-row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: .75rem;
|
|
color: color-mix(in srgb, var(--on-primary) 72%, transparent);
|
|
font-size: .86rem;
|
|
}
|
|
|
|
.trust-pill {
|
|
padding: .35rem .62rem;
|
|
border: 1px solid color-mix(in srgb, var(--on-primary) 20%, transparent);
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--on-primary) 8%, transparent);
|
|
}
|
|
|
|
.login-panel {
|
|
position: relative;
|
|
display: grid;
|
|
place-items: center;
|
|
min-height: 100vh;
|
|
padding: clamp(1.2rem, 4vw, 3rem);
|
|
background: color-mix(in srgb, var(--page-accent) 72%, transparent);
|
|
backdrop-filter: blur(14px);
|
|
}
|
|
|
|
.theme-toggle {
|
|
position: absolute;
|
|
top: 1.3rem;
|
|
right: 1.3rem;
|
|
display: inline-flex;
|
|
gap: .35rem;
|
|
padding: .32rem;
|
|
border: 1px solid var(--border);
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--surface) 90%, 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 {
|
|
position: relative;
|
|
overflow: hidden;
|
|
width: min(100%, 28rem);
|
|
padding: clamp(1.35rem, 4vw, 2.35rem);
|
|
background: color-mix(in srgb, var(--surface) 98%, transparent);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-lg);
|
|
}
|
|
|
|
.login-card::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0 0 auto;
|
|
height: .28rem;
|
|
background: linear-gradient(90deg, var(--primary), var(--accent-1), var(--accent-2), var(--accent-3));
|
|
}
|
|
|
|
.login-card header { margin-bottom: 1.8rem; }
|
|
|
|
.login-kicker {
|
|
display: inline-flex;
|
|
gap: .5rem;
|
|
align-items: center;
|
|
margin-bottom: .7rem;
|
|
color: var(--muted);
|
|
font-family: var(--font-ui);
|
|
font-size: .78rem;
|
|
font-weight: 700;
|
|
letter-spacing: .08em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.secure-dot {
|
|
width: .52rem;
|
|
height: .52rem;
|
|
border-radius: 999px;
|
|
background: var(--primary);
|
|
box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 14%, transparent);
|
|
}
|
|
|
|
.login-card h2 { font-size: clamp(1.8rem, 4vw, 2.35rem); }
|
|
|
|
.login-card header p {
|
|
margin: .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: .42rem;
|
|
}
|
|
|
|
label {
|
|
font-family: var(--font-ui);
|
|
font-size: .93rem;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.field-row a { font-size: .88rem; }
|
|
.input-wrap { position: relative; }
|
|
|
|
input[type="email"],
|
|
input[type="password"],
|
|
input[type="text"] {
|
|
width: 100%;
|
|
min-height: 3.15rem;
|
|
padding: .78rem .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: .82; }
|
|
input:hover { border-color: color-mix(in srgb, var(--border) 55%, var(--primary)); }
|
|
|
|
input:focus {
|
|
border-color: var(--primary);
|
|
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% .55rem auto auto;
|
|
display: grid;
|
|
place-items: center;
|
|
width: 2.2rem;
|
|
aspect-ratio: 1;
|
|
padding: 0;
|
|
color: var(--muted);
|
|
border: 0;
|
|
border-radius: .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: .2rem 0 1.25rem;
|
|
}
|
|
|
|
.checkbox-label {
|
|
display: inline-flex;
|
|
gap: .55rem;
|
|
align-items: center;
|
|
color: var(--muted);
|
|
font-family: var(--font-body);
|
|
font-size: .94rem;
|
|
font-weight: 400;
|
|
cursor: pointer;
|
|
}
|
|
|
|
input[type="checkbox"] {
|
|
width: 1.05rem;
|
|
height: 1.05rem;
|
|
margin: 0;
|
|
accent-color: var(--primary);
|
|
}
|
|
|
|
.primary-button {
|
|
width: 100%;
|
|
min-height: 3.15rem;
|
|
padding: .8rem 1rem;
|
|
color: var(--on-primary);
|
|
background: var(--primary);
|
|
border: 1px solid var(--primary);
|
|
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(--primary) 22%, transparent);
|
|
transition: transform 140ms ease, background-color 140ms ease, box-shadow 140ms ease;
|
|
}
|
|
|
|
.primary-button:hover {
|
|
background: var(--primary-hover);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 14px 30px color-mix(in srgb, var(--primary) 26%, transparent);
|
|
}
|
|
|
|
.primary-button:active { transform: translateY(0); }
|
|
|
|
.divider {
|
|
display: grid;
|
|
grid-template-columns: 1fr auto 1fr;
|
|
gap: .8rem;
|
|
align-items: center;
|
|
margin: 1.3rem 0;
|
|
color: var(--muted);
|
|
font-size: .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: .7rem;
|
|
align-items: center;
|
|
padding: .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: .94rem;
|
|
}
|
|
|
|
.helper-message {
|
|
display: none;
|
|
margin: .5rem 0 0;
|
|
padding: .58rem .7rem;
|
|
color: var(--danger);
|
|
background: var(--danger-soft);
|
|
border-left: .3rem solid var(--danger);
|
|
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
|
|
font-size: .87rem;
|
|
}
|
|
|
|
.helper-message.visible { display: block; }
|
|
|
|
.privacy-note {
|
|
width: min(100%, 28rem);
|
|
margin: 1rem auto 0;
|
|
color: var(--muted);
|
|
font-size: .82rem;
|
|
text-align: center;
|
|
}
|
|
|
|
|
|
.sample-card {
|
|
width: min(100%, 28rem);
|
|
margin: 1rem auto 0;
|
|
padding: 1.25rem 1.3rem;
|
|
color: var(--text);
|
|
background: color-mix(in srgb, var(--surface) 96%, transparent);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
.sample-card__eyebrow {
|
|
margin: 0 0 0.45rem;
|
|
color: var(--primary);
|
|
font-family: var(--font-ui);
|
|
font-size: 0.76rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.09em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.sample-card h3 {
|
|
margin: 0;
|
|
color: var(--text);
|
|
font-family: var(--font-ui);
|
|
font-size: 1.25rem;
|
|
line-height: 1.22;
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.sample-card__subheading {
|
|
margin: 0.38rem 0 0;
|
|
color: var(--muted);
|
|
font-family: var(--font-ui);
|
|
font-size: 0.94rem;
|
|
font-weight: 500;
|
|
line-height: 1.45;
|
|
}
|
|
|
|
.sample-card__body {
|
|
margin: 0.9rem 0 0;
|
|
color: var(--text);
|
|
font-family: var(--font-body);
|
|
font-size: 1rem;
|
|
line-height: 1.68;
|
|
}
|
|
|
|
.sample-card__footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 1rem;
|
|
align-items: center;
|
|
margin-top: 1rem;
|
|
padding-top: 0.85rem;
|
|
border-top: 1px solid var(--border);
|
|
color: var(--muted);
|
|
font-size: 0.82rem;
|
|
}
|
|
|
|
.sample-card__badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: 0.25rem 0.5rem;
|
|
color: var(--on-secondary);
|
|
background: var(--secondary);
|
|
border-radius: 999px;
|
|
font-family: var(--font-ui);
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
@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: .7rem; }
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*, *::before, *::after {
|
|
animation-duration: .01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
scroll-behavior: auto !important;
|
|
transition-duration: .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>Merlot</span>
|
|
</div>
|
|
|
|
<div class="hero-copy">
|
|
<p class="eyebrow">Burgundy & Dusty Rose</p>
|
|
<h1 id="welcome-title">Quiet confidence. Rich clarity.</h1>
|
|
<p>A mature burgundy system softened by dusty rose and warm neutral surfaces.</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>
|
|
<div class="login-kicker">
|
|
<span class="secure-dot" aria-hidden="true"></span>
|
|
Secure sign-in
|
|
</div>
|
|
<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>
|
|
|
|
<article class="sample-card" aria-labelledby="sample-card-title">
|
|
<p class="sample-card__eyebrow">Typography sample</p>
|
|
<h3 id="sample-card-title">A calm and readable card heading</h3>
|
|
<p class="sample-card__subheading">
|
|
A concise subheading demonstrates Lexend at a smaller interface size.
|
|
</p>
|
|
<p class="sample-card__body">
|
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer
|
|
posuere, neque vitae facilisis luctus, justo sapien posuere lorem,
|
|
sed cursus mauris erat vel sem. Donec vitae lectus at mi tincidunt
|
|
suscipit.
|
|
</p>
|
|
<footer class="sample-card__footer">
|
|
<span>Atkinson Hyperlegible body text</span>
|
|
<span class="sample-card__badge">Lexend UI</span>
|
|
</footer>
|
|
</article>
|
|
|
|
</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 storageKey = "burgundy-rose-theme";
|
|
|
|
const setTheme = (theme) => {
|
|
root.dataset.theme = theme;
|
|
themeButtons.forEach((button) => {
|
|
button.setAttribute("aria-pressed", String(button.dataset.theme === theme));
|
|
});
|
|
localStorage.setItem(storageKey, theme);
|
|
};
|
|
|
|
const storedTheme = localStorage.getItem(storageKey);
|
|
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: this login form is not connected to a backend.");
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|