Add BeingOne front page: new Squeeze-themed design with working demos
Phase 1 of the BeingOne plan: a front page with a tappable Australia map, match finder with scores, four-check verification demo, photo privacy demo, interest/accept/chat demo, family view, safety tools, and join/log in forms that post nowhere yet. Includes the PRD. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01829HyWt1ur24ovhzCVeBx4
This commit is contained in:
9 files changed
+967
No files matched your search
@@ -0,0 +1 @@
|
||||
.hallmark/shots/
|
||||
@@ -0,0 +1,5 @@
|
||||
shots/
|
||||
before/
|
||||
before.json
|
||||
before.txt
|
||||
compare.html
|
||||
@@ -0,0 +1,31 @@
|
||||
[
|
||||
{
|
||||
"shape": "Marquee Hero",
|
||||
"theme": "squeeze",
|
||||
"axes": "mid/geometric-sans/warm",
|
||||
"hero": "Banner",
|
||||
"nav": "edge-aligned",
|
||||
"footer": "letter close",
|
||||
"imagery": "photographs, library 1, natural",
|
||||
"photos": [
|
||||
"worm-bay"
|
||||
],
|
||||
"entry": "BeingOne front page",
|
||||
"sections": [
|
||||
"Hero",
|
||||
"Path",
|
||||
"Finder",
|
||||
"Checks",
|
||||
"Privacy",
|
||||
"Talk",
|
||||
"Family+Safety",
|
||||
"Questions+Join",
|
||||
"Footer"
|
||||
],
|
||||
"signature": "match finder with a tappable map of Australia and a moving score",
|
||||
"waived": [],
|
||||
"prompt": "BeingOne marriage site for Australians",
|
||||
"date": "2026-10-23",
|
||||
"mode": "build"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,65 @@
|
||||
# BeingOne: plan (PRD)
|
||||
|
||||
Tagline: Real people. Real profiles. Real marriage.
|
||||
For: Australians, and the families of Australians, who want to find a life partner. English only. Australia only.
|
||||
Written for: Keith. Plain words on purpose.
|
||||
|
||||
## The big idea
|
||||
|
||||
BeingOne is a marriage website where every profile is checked to be a real person. People find matches, talk safely, and families can be part of it.
|
||||
|
||||
## The 13 core features (from Keith's plan)
|
||||
|
||||
1. Sign up and log in with email.
|
||||
2. Make a profile: photos, age, city, job, things you love, a short "about me".
|
||||
3. Check the profile is real: phone check, photo check, ID check, and a quick look by a person on the team.
|
||||
4. Search by Australian city, age and shared interests.
|
||||
5. Match score: a number showing how well two people fit.
|
||||
6. Photo privacy: you decide who sees your photos.
|
||||
7. Send an interest. The other person accepts or says no thanks.
|
||||
8. Private chat that opens only when both say yes.
|
||||
9. Family view: a parent or sibling helps look at profiles.
|
||||
10. Safety tools: block, report, hide your profile.
|
||||
11. Free plan and paid plan (payments).
|
||||
12. Admin area for the BeingOne team: review profiles, handle reports, see numbers.
|
||||
13. Emails and phone alerts: new matches, interests, messages.
|
||||
|
||||
## Phase 1 (today): the new look, with working demos
|
||||
|
||||
What you get: one front page in a new design. Everything on it is a demo that runs in your browser, with made-up sample people.
|
||||
|
||||
| Feature | Where it shows up on the page |
|
||||
| --- | --- |
|
||||
| 1 Sign up, log in | The join card at the bottom (Join and Log in tabs). It does not save anything yet. |
|
||||
| 2 Profile | Shown through the sample people and the checks demo. The real profile editor is Phase 3. |
|
||||
| 3 Checks | "Every profile is checked": run the four checks on a sample profile. |
|
||||
| 4 Search | "Find your match across Australia": map of Australia, city, ages, interests. |
|
||||
| 5 Match score | The score and bar on every sample person. |
|
||||
| 6 Photo privacy | "You choose who sees your photos": pick who can see, pick who is looking. |
|
||||
| 7 Interest, accept | "Chat opens when both say yes": accept or say no thanks. |
|
||||
| 8 Private chat | Same section: the chat unlocks after Accept. |
|
||||
| 9 Family view | "Family view" tile: pick who helps you look. |
|
||||
| 10 Safety tools | "Safety tools" tile: block, report, hide. |
|
||||
| 11 Plans | The "What does it cost?" answer. The paid price is left blank until you give it. |
|
||||
| 12 Admin | Mentioned in "Who runs the site?". The real admin area is Phase 7 and is a separate private page. |
|
||||
| 13 Alerts | The "Will I get alerts?" answer. Real alerts are Phase 6. |
|
||||
|
||||
Tests, in this order:
|
||||
1. The page loads with no errors.
|
||||
2. Every button, chip, slider, tab and form reacts.
|
||||
3. Real connections: none yet, so nothing to test.
|
||||
4. Security: no passwords, no keys, no calls to other servers for data. The forms only show a message on screen.
|
||||
|
||||
## Phases 2 to 8 (one at a time, each must work before the next)
|
||||
|
||||
2. Real sign-up and login (needs a host, a domain, a privacy policy and a consent step).
|
||||
3. Real profiles and photos, with private photo storage.
|
||||
4. Real checks (phone code, ID check through a trusted provider, team review screen).
|
||||
5. Real search and matching on real profiles.
|
||||
6. Private chat, block and report, email and phone alerts.
|
||||
7. Payments (test mode first) and the admin area.
|
||||
8. Launch checks: speed, phones, privacy rules, backups, a trial with friends and family.
|
||||
|
||||
## Important
|
||||
|
||||
Marriage sites hold very private details. In Australia some of them are "sensitive information" under the Privacy Act 1988, so people must clearly agree to how they are used. Plan the privacy policy and consent step in Phase 2. Please check with a lawyer before launch. This is not legal advice.
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
(() => {
|
||||
'use strict';
|
||||
const $ = (s, r = document) => r.querySelector(s);
|
||||
const $$ = (s, r = document) => Array.from(r.querySelectorAll(s));
|
||||
const cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
||||
|
||||
/* made-up sample people; nothing here is a real person */
|
||||
const PEOPLE = [
|
||||
{ n: 'Mia', a: 28, c: 'Sydney', l: ['beach', 'coffee', 'travel'], t: 'a' },
|
||||
{ n: 'Arjun', a: 31, c: 'Melbourne', l: ['footy', 'cooking', 'music'], t: 'b' },
|
||||
{ n: 'Hannah', a: 27, c: 'Brisbane', l: ['beach', 'hiking', 'pets'], t: 'c' },
|
||||
{ n: 'Wei', a: 30, c: 'Perth', l: ['coffee', 'travel', 'hiking'], t: 'd' },
|
||||
{ n: 'Sana', a: 29, c: 'Adelaide', l: ['cooking', 'music', 'pets'], t: 'a' },
|
||||
{ n: 'Tom', a: 33, c: 'Hobart', l: ['hiking', 'footy', 'coffee'], t: 'b' },
|
||||
{ n: 'Priya', a: 26, c: 'Sydney', l: ['music', 'cooking', 'beach'], t: 'c' },
|
||||
{ n: 'Jack', a: 35, c: 'Melbourne', l: ['footy', 'beach', 'pets'], t: 'd' },
|
||||
{ n: 'Elena', a: 32, c: 'Brisbane', l: ['travel', 'coffee', 'music'], t: 'a' },
|
||||
{ n: 'Dev', a: 34, c: 'Perth', l: ['footy', 'cooking', 'hiking'], t: 'b' },
|
||||
{ n: 'Grace', a: 30, c: 'Canberra', l: ['hiking', 'coffee', 'pets'], t: 'c' },
|
||||
{ n: 'Sam', a: 28, c: 'Darwin', l: ['beach', 'footy', 'travel'], t: 'd' },
|
||||
{ n: 'Lena', a: 38, c: 'Sydney', l: ['travel', 'music', 'pets'], t: 'a' },
|
||||
{ n: 'Omar', a: 29, c: 'Melbourne', l: ['coffee', 'cooking', 'hiking'], t: 'c' }
|
||||
];
|
||||
|
||||
/* ---------- one reveal, once ---------- */
|
||||
const revealEls = $$('[data-reveal]');
|
||||
if ('IntersectionObserver' in window) {
|
||||
const io = new IntersectionObserver((es) => es.forEach((e) => {
|
||||
if (e.isIntersecting) { e.target.classList.add('is-in'); io.unobserve(e.target); }
|
||||
}), { rootMargin: '0px 0px -10% 0px' });
|
||||
revealEls.forEach((el) => io.observe(el));
|
||||
} else {
|
||||
revealEls.forEach((el) => el.classList.add('is-in'));
|
||||
}
|
||||
|
||||
/* ---------- match finder ---------- */
|
||||
const st = { city: 'Anywhere', from: 25, to: 40, likes: new Set(), sent: new Set() };
|
||||
const selCity = $('#f-city'), from = $('#f-from'), to = $('#f-to');
|
||||
const oFrom = $('#o-from'), oTo = $('#o-to'), results = $('#results');
|
||||
const status = $('#finder-status'), mapCity = $('#map-city');
|
||||
const pins = $$('.pin');
|
||||
|
||||
function scoreOf(p) {
|
||||
const mid = (st.from + st.to) / 2, half = Math.max((st.to - st.from) / 2, 1);
|
||||
const ageFit = Math.max(0, 1 - Math.abs(p.a - mid) / (half + 4));
|
||||
const shared = p.l.filter((x) => st.likes.has(x)).length;
|
||||
const likeFit = st.likes.size ? Math.min(1, shared / Math.min(st.likes.size, 3)) : 0.5;
|
||||
const cityFit = st.city === 'Anywhere' ? 0.7 : 1;
|
||||
return Math.round(55 + 45 * (0.5 * likeFit + 0.3 * ageFit + 0.2 * cityFit));
|
||||
}
|
||||
|
||||
function tile(r, i) {
|
||||
const p = r.p, sent = st.sent.has(p.n);
|
||||
const tags = p.l.map((x) => '<li' + (st.likes.has(x) ? ' class="is-shared"' : '') + '>' + cap(x) + '</li>').join('');
|
||||
return '<article class="person" style="--i:' + i + '">' +
|
||||
'<div class="person__who"><span class="avatar" style="--tone:var(--tone-' + p.t + ')" aria-hidden="true">' + p.n.charAt(0) + '</span>' +
|
||||
'<div><h3>' + p.n + ', ' + p.a + '</h3><p class="label">' + p.c + '</p></div></div>' +
|
||||
'<div><div class="score"><b>' + r.score + '</b><span class="label" title="Counts shared interests, city and age">match</span></div>' +
|
||||
'<div class="bar" role="img" aria-label="Match score ' + r.score + ' out of 100"><i style="--s:' + r.score + '"></i></div></div>' +
|
||||
'<ul class="tags">' + tags + '</ul>' +
|
||||
'<button class="btn btn--sm" type="button" data-interest="' + p.n + '" aria-pressed="' + sent + '">' + (sent ? 'Interest sent' : 'Send interest') + '</button>' +
|
||||
'</article>';
|
||||
}
|
||||
|
||||
function renderFinder() {
|
||||
const pool = PEOPLE
|
||||
.filter((p) => (st.city === 'Anywhere' || p.c === st.city) && p.a >= st.from && p.a <= st.to)
|
||||
.map((p) => ({ p, score: scoreOf(p) }))
|
||||
.sort((x, y) => y.score - x.score || x.p.n.localeCompare(y.p.n));
|
||||
const top = pool.slice(0, 4);
|
||||
results.innerHTML = top.length
|
||||
? top.map(tile).join('')
|
||||
: '<p class="results__empty">No one fits yet. Widen the ages or try another city.</p>';
|
||||
const where = st.city === 'Anywhere' ? 'all of Australia' : st.city;
|
||||
status.textContent = top.length ? top.length + ' of ' + pool.length + ' shown.' : '';
|
||||
mapCity.textContent = st.city === 'Anywhere' ? 'All of Australia' : st.city;
|
||||
selCity.value = st.city;
|
||||
pins.forEach((b) => b.setAttribute('aria-pressed', String(b.dataset.city === st.city)));
|
||||
}
|
||||
|
||||
pins.forEach((b) => b.addEventListener('click', () => {
|
||||
st.city = st.city === b.dataset.city ? 'Anywhere' : b.dataset.city;
|
||||
renderFinder();
|
||||
}));
|
||||
selCity.addEventListener('change', () => { st.city = selCity.value; renderFinder(); });
|
||||
from.addEventListener('input', () => {
|
||||
st.from = +from.value;
|
||||
if (st.from > st.to) { st.to = st.from; to.value = st.to; }
|
||||
oFrom.textContent = st.from; oTo.textContent = st.to; renderFinder();
|
||||
});
|
||||
to.addEventListener('input', () => {
|
||||
st.to = +to.value;
|
||||
if (st.to < st.from) { st.from = st.to; from.value = st.from; }
|
||||
oFrom.textContent = st.from; oTo.textContent = st.to; renderFinder();
|
||||
});
|
||||
$$('#f-likes input').forEach((c) => c.addEventListener('change', () => {
|
||||
c.checked ? st.likes.add(c.value) : st.likes.delete(c.value);
|
||||
renderFinder();
|
||||
}));
|
||||
results.addEventListener('click', (e) => {
|
||||
const b = e.target.closest('[data-interest]');
|
||||
if (!b) return;
|
||||
const name = b.dataset.interest;
|
||||
st.sent.has(name) ? st.sent.delete(name) : st.sent.add(name);
|
||||
const on = st.sent.has(name);
|
||||
b.setAttribute('aria-pressed', String(on));
|
||||
b.textContent = on ? 'Interest sent' : 'Send interest';
|
||||
});
|
||||
renderFinder();
|
||||
|
||||
/* ---------- the four checks ---------- */
|
||||
const rows = $$('[data-check]'), vStatus = $('#v-status'), vText = $('#v-status-text');
|
||||
const timers = new Map();
|
||||
function updateChecks() {
|
||||
const n = rows.filter((r) => r.classList.contains('is-done')).length;
|
||||
vStatus.dataset.state = n === rows.length ? 'done' : 'idle';
|
||||
vText.textContent = n === rows.length ? 'Verified' : n ? n + ' of 4 passed' : 'Not verified yet';
|
||||
}
|
||||
function runCheck(row) {
|
||||
if (row.classList.contains('is-done') || timers.has(row)) return;
|
||||
const btn = $('[data-run]', row);
|
||||
btn.setAttribute('aria-busy', 'true'); btn.disabled = true; btn.textContent = 'Checking…';
|
||||
timers.set(row, setTimeout(() => {
|
||||
timers.delete(row);
|
||||
row.classList.add('is-done');
|
||||
btn.hidden = true; btn.removeAttribute('aria-busy');
|
||||
$('.passed', row).hidden = false;
|
||||
updateChecks();
|
||||
}, 800));
|
||||
}
|
||||
rows.forEach((r) => $('[data-run]', r).addEventListener('click', () => runCheck(r)));
|
||||
$('#v-all').addEventListener('click', () => rows.forEach((r, i) => setTimeout(() => runCheck(r), i * 250)));
|
||||
$('#v-reset').addEventListener('click', () => {
|
||||
timers.forEach((t) => clearTimeout(t)); timers.clear();
|
||||
rows.forEach((r) => {
|
||||
r.classList.remove('is-done');
|
||||
const btn = $('[data-run]', r);
|
||||
btn.hidden = false; btn.disabled = false; btn.removeAttribute('aria-busy'); btn.textContent = 'Run check';
|
||||
$('.passed', r).hidden = true;
|
||||
});
|
||||
updateChecks();
|
||||
});
|
||||
|
||||
/* ---------- photo privacy ---------- */
|
||||
const photo = $('#photo'), photoState = $('#photo-state');
|
||||
const rank = { stranger: 0, verified: 1, accepted: 2 };
|
||||
function renderPhoto() {
|
||||
const setting = $('input[name="setting"]:checked').value;
|
||||
const viewer = $('input[name="viewer"]:checked').value;
|
||||
const can = setting === 'everyone' ||
|
||||
(setting === 'verified' && rank[viewer] >= 1) ||
|
||||
(setting === 'accepted' && rank[viewer] >= 2);
|
||||
photo.classList.toggle('is-hidden', !can);
|
||||
photoState.textContent = can ? 'Visible to this visitor' : 'Hidden from this visitor';
|
||||
}
|
||||
$$('input[name="setting"], input[name="viewer"]').forEach((r) => r.addEventListener('change', renderPhoto));
|
||||
renderPhoto();
|
||||
|
||||
/* ---------- interest, accept, chat ---------- */
|
||||
const chat = $('#chat'), log = $('#chat-log'), tResult = $('#t-result');
|
||||
const accept = $('#t-accept'), decline = $('#t-decline'), tReset = $('#t-reset');
|
||||
const chatForm = $('#chat-form'), chatInput = $('#chat-input');
|
||||
function addLine(text, cls) {
|
||||
const li = document.createElement('li');
|
||||
if (cls) li.className = cls;
|
||||
li.textContent = text;
|
||||
log.appendChild(li);
|
||||
log.scrollTop = log.scrollHeight;
|
||||
}
|
||||
function decide(yes) {
|
||||
accept.hidden = true; decline.hidden = true; tReset.hidden = false;
|
||||
tResult.textContent = yes ? 'You both said yes. Say hello.' : 'You said no thanks. Nothing opens.';
|
||||
if (yes) {
|
||||
chat.classList.remove('is-locked');
|
||||
addLine('You and Priya both said yes.', 'note');
|
||||
chatInput.focus();
|
||||
}
|
||||
}
|
||||
accept.addEventListener('click', () => decide(true));
|
||||
decline.addEventListener('click', () => decide(false));
|
||||
tReset.addEventListener('click', () => {
|
||||
accept.hidden = false; decline.hidden = false; tReset.hidden = true;
|
||||
tResult.textContent = ''; log.textContent = '';
|
||||
chat.classList.add('is-locked'); chatInput.value = '';
|
||||
});
|
||||
chatForm.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
const v = chatInput.value.trim();
|
||||
if (!v) { chatInput.focus(); return; }
|
||||
addLine(v, 'me'); chatInput.value = ''; chatInput.focus();
|
||||
});
|
||||
|
||||
/* ---------- family view and safety tools ---------- */
|
||||
const famStatus = $('#fam-status');
|
||||
function renderFam() {
|
||||
const on = $$('#fam input:checked').map((c) => c.value);
|
||||
famStatus.textContent = !on.length ? 'Just you for now.'
|
||||
: (on.length === 1 ? on[0] : on.slice(0, -1).join(', ') + ' and ' + on[on.length - 1]) +
|
||||
(on.length === 1 ? ' is' : ' are') + ' looking with you.';
|
||||
}
|
||||
$$('#fam input').forEach((c) => c.addEventListener('change', renderFam));
|
||||
|
||||
const safe = $('#safe-status'), sBlock = $('#s-block'), sHide = $('#s-hide'), sReport = $('#s-report');
|
||||
let blocked = false;
|
||||
sBlock.addEventListener('click', () => {
|
||||
blocked = !blocked;
|
||||
$('span', sBlock).textContent = blocked ? 'Unblock' : 'Block';
|
||||
sBlock.setAttribute('aria-pressed', String(blocked));
|
||||
safe.textContent = blocked ? 'Jack is blocked. He cannot message you.' : 'Jack is unblocked.';
|
||||
});
|
||||
sReport.addEventListener('click', () => { safe.textContent = 'Demo only: nothing was sent to our team.'; });
|
||||
sHide.addEventListener('click', () => {
|
||||
const on = sHide.getAttribute('aria-pressed') !== 'true';
|
||||
sHide.setAttribute('aria-pressed', String(on));
|
||||
$('span', sHide).textContent = on ? 'Show my profile' : 'Hide my profile';
|
||||
safe.textContent = on ? 'Your profile is hidden from search.' : 'Your profile shows in search.';
|
||||
});
|
||||
|
||||
/* ---------- join card: tabs and forms that post nowhere yet ---------- */
|
||||
const tabs = $$('[role="tab"]', $('#join-card'));
|
||||
const panels = { join: $('#panel-join'), login: $('#panel-login') };
|
||||
function openTab(name, focus) {
|
||||
tabs.forEach((t) => {
|
||||
const on = t.id === 'tab-' + name;
|
||||
t.setAttribute('aria-selected', String(on));
|
||||
t.tabIndex = on ? 0 : -1;
|
||||
if (on && focus) t.focus();
|
||||
});
|
||||
Object.keys(panels).forEach((k) => { panels[k].hidden = k !== name; });
|
||||
}
|
||||
tabs.forEach((t, i) => {
|
||||
t.addEventListener('click', () => openTab(t.id.replace('tab-', '')));
|
||||
t.addEventListener('keydown', (e) => {
|
||||
if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return;
|
||||
e.preventDefault();
|
||||
const next = tabs[(i + (e.key === 'ArrowRight' ? 1 : tabs.length - 1)) % tabs.length];
|
||||
openTab(next.id.replace('tab-', ''), true);
|
||||
});
|
||||
});
|
||||
$$('[data-open-tab]').forEach((a) => a.addEventListener('click', () => openTab(a.dataset.openTab)));
|
||||
openTab('join');
|
||||
|
||||
$$('form[data-endpoint]').forEach((form) => {
|
||||
const help = $('.form-help', form);
|
||||
form.addEventListener('input', (e) => { e.target.removeAttribute && e.target.removeAttribute('aria-invalid'); });
|
||||
form.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
help.classList.remove('is-error');
|
||||
const bad = $$('input', form).filter((i) => !i.checkValidity());
|
||||
$$('input', form).forEach((i) => i.toggleAttribute('aria-invalid', bad.includes(i)));
|
||||
if (bad.length) {
|
||||
help.classList.add('is-error');
|
||||
help.textContent = bad[0].type === 'email'
|
||||
? 'That email looks incomplete. Write it as name@example.com.'
|
||||
: 'Please fill in the highlighted field.';
|
||||
bad[0].focus();
|
||||
return;
|
||||
}
|
||||
if (!form.dataset.endpoint) { help.textContent = 'Nothing was sent: this form is not connected yet.'; return; }
|
||||
});
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,27 @@
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body { overflow-x: clip; }
|
||||
html { scrollbar-color: var(--color-muted) var(--color-paper); scroll-padding-top: var(--space-3xl); }
|
||||
body { margin: 0; background: var(--color-paper); color: var(--color-ink); font-family: var(--font-body); font-size: var(--text-md); line-height: 1.55; -webkit-font-smoothing: antialiased; caret-color: var(--color-accent); }
|
||||
::selection { background: color-mix(in oklab, var(--color-accent) 45%, transparent); color: var(--color-card-ink); }
|
||||
:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
|
||||
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.16em; }
|
||||
h1, h2, h3 { margin: 0; font-family: var(--font-display); font-weight: var(--display-weight, 700); font-synthesis: none; letter-spacing: var(--tracking-display); line-height: 1.05; overflow-wrap: break-word; min-width: 0; text-wrap: balance; }
|
||||
h1 { max-width: 20ch; font-size: var(--text-display); } h2 { max-width: 30ch; font-size: var(--text-section); } h3 { max-width: 40ch; font-size: var(--text-title); line-height: 1.2; }
|
||||
.lead { font-size: var(--text-lead); line-height: 1.45; max-width: 52ch; }
|
||||
p { margin: 0; text-wrap: pretty; }
|
||||
p:not([class]) { max-width: 65ch; }
|
||||
img, video { max-width: 100%; height: auto; display: block; }
|
||||
svg { display: block; }
|
||||
[hidden] { display: none !important; }
|
||||
button, input, select, textarea { font: inherit; }
|
||||
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); box-sizing: border-box; }
|
||||
.num, .figure, td.num { font-variant-numeric: tabular-nums; }
|
||||
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
|
||||
[data-slot] { position: relative; overflow: hidden; background: linear-gradient(160deg, var(--color-paper-2, var(--color-paper)), var(--color-paper-3, var(--color-paper))); }
|
||||
[data-slot] > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; }
|
||||
[data-slot]:has(> img) > :not(img):not([data-keep]) { display: none !important; }
|
||||
@media (max-width: 60rem) { :root { --gutter: 24px; --section-gap-s: 80px; --section-gap: 96px; --section-gap-l: 120px; } }
|
||||
@media (max-width: 40rem) { :root { --gutter: 16px; --section-gap-s: 56px; --section-gap: 72px; --section-gap-l: 96px; --gap-columns: 16px; } }
|
||||
@media (prefers-reduced-motion: reduce) { *:not(.keep-motion), *:not(.keep-motion)::before, *:not(.keep-motion)::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } }
|
||||
/* photographs: natural vib=12 con=4 */
|
||||
[data-slot] > img { filter: saturate(1.06) contrast(1.04); }
|
||||
@@ -0,0 +1,318 @@
|
||||
<!doctype html>
|
||||
<html lang="en-AU">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>BeingOne: marriage profiles for Australians, every one checked</title>
|
||||
<meta name="description" content="BeingOne is a marriage website for Australians and their families where every profile is checked to be a real person.">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Gabarito:wght@800&family=Manrope:wght@500;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script>document.documentElement.classList.add('js');</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
|
||||
<symbol id="i-check" viewBox="0 0 24 24"><path d="M20 6 9 17l-5-5"/></symbol>
|
||||
<symbol id="i-lock" viewBox="0 0 24 24"><rect width="18" height="11" x="3" y="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></symbol>
|
||||
<symbol id="i-eye" viewBox="0 0 24 24"><path d="M2.06 12.35a1 1 0 0 1 0-.7 10.75 10.75 0 0 1 19.88 0 1 1 0 0 1 0 .7 10.75 10.75 0 0 1-19.88 0"/><circle cx="12" cy="12" r="3"/></symbol>
|
||||
<symbol id="i-shield" viewBox="0 0 24 24"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></symbol>
|
||||
<symbol id="i-phone" viewBox="0 0 24 24"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/></symbol>
|
||||
<symbol id="i-camera" viewBox="0 0 24 24"><path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/></symbol>
|
||||
<symbol id="i-id" viewBox="0 0 24 24"><rect x="2" y="5" width="20" height="14" rx="2"/><circle cx="9" cy="11" r="2"/><path d="M5.5 16c.5-1.5 2-2.5 3.5-2.5s3 1 3.5 2.5M15 10h4M15 14h3"/></symbol>
|
||||
<symbol id="i-users" viewBox="0 0 24 24"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/></symbol>
|
||||
<symbol id="i-ban" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="m4.9 4.9 14.2 14.2"/></symbol>
|
||||
<symbol id="i-flag" viewBox="0 0 24 24"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><path d="M4 22v-7"/></symbol>
|
||||
<symbol id="i-send" viewBox="0 0 24 24"><path d="m22 2-7 20-4-9-9-4z"/><path d="M22 2 11 13"/></symbol>
|
||||
</svg>
|
||||
|
||||
<a class="skip" href="#main">Skip to content</a>
|
||||
|
||||
<header class="nav">
|
||||
<div class="container">
|
||||
<a class="wordmark" href="#top" aria-label="BeingOne, back to the top">BeingOne</a>
|
||||
<nav class="nav__links" aria-label="Main">
|
||||
<a class="hide-sm" href="#find">Find</a>
|
||||
<a class="hide-sm" href="#verified">Checks</a>
|
||||
<a class="hide-sm" href="#privacy">Photos</a>
|
||||
<a href="#join" data-open-tab="login">Log in</a>
|
||||
<a class="btn btn--sm" href="#join" data-open-tab="join">Join</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main id="main">
|
||||
|
||||
<section class="hero" id="top" aria-labelledby="hero-title">
|
||||
<div class="container grid">
|
||||
<h1 id="hero-title">
|
||||
<span data-reveal style="--i:0">Real people.</span>
|
||||
<span data-reveal style="--i:1">Real profiles.</span>
|
||||
<span data-reveal style="--i:2">Real marriage.</span>
|
||||
</h1>
|
||||
<div class="hero__side" data-reveal style="--i:3">
|
||||
<p class="lead">Every profile is checked, so you meet real people across Australia.</p>
|
||||
<a class="btn btn--primary" href="#join" data-open-tab="join">Make my profile</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="band band--path" id="path" aria-label="How it goes">
|
||||
<div class="container">
|
||||
<ol class="path">
|
||||
<li><a href="#join">Join</a></li>
|
||||
<li><a href="#verified">Get checked</a></li>
|
||||
<li><a href="#find">Find</a></li>
|
||||
<li><a href="#talk">Say yes</a></li>
|
||||
<li><a href="#talk">Chat</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sec finder" id="find" aria-labelledby="find-title">
|
||||
<div class="container">
|
||||
<div class="grid finder__top">
|
||||
<h2 id="find-title" data-reveal>Find your match across Australia</h2>
|
||||
<p class="lead" data-reveal style="--i:1">Pick a city, then ages and what you love.</p>
|
||||
</div>
|
||||
<div class="grid finder__body">
|
||||
<div class="map" role="group" aria-label="Map of Australia. Tap a city to search there.">
|
||||
<svg class="map__svg" viewBox="-40 -20 605 516" role="img" aria-label="Outline of Australia">
|
||||
<path d="M381.3 9.8L393.8 56.0L416.3 70.0L422.5 96.6L435.0 130.2L458.7 144.2L465.0 155.4L485.0 187.6L505.0 208.6L513.7 224.0L512.5 245.0L520.0 260.4L512.5 284.2L506.3 308.0L490.0 334.6L485.0 348.6L476.2 366.8L473.8 385.0L450.0 392.0L430.0 407.4L412.5 397.6L393.8 403.2L362.5 393.4L350.0 385.0L343.8 358.4L326.2 359.1L331.3 347.2L321.2 336.0L300.0 347.2L277.5 322.0L237.5 301.0L212.5 303.8L175.0 312.2L143.8 333.2L123.8 334.6L87.5 348.6L73.8 350.0L38.7 341.6L46.3 326.2L47.5 308.0L32.5 263.2L17.5 224.0L18.8 196.0L26.2 165.2L58.8 149.8L82.5 144.2L118.8 126.0L127.5 112.0L147.5 91.0L168.8 77.0L186.3 54.6L212.5 70.0L221.2 68.6L225.0 46.2L235.0 35.0L256.3 21.0L275.0 28.0L310.0 30.8L306.3 49.0L297.5 72.8L322.5 91.0L343.8 105.0L360.0 103.6L370.0 77.0L368.8 49.0L376.2 30.8ZM408.7 429.8L453.8 432.6L453.8 450.8L441.3 469.0L425.0 470.4L415.0 450.8Z"/>
|
||||
</svg>
|
||||
<button class="pin" type="button" data-city="Perth" aria-pressed="false" aria-label="Perth" title="Perth" style="--x:14.6%;--y:63.4%"></button>
|
||||
<button class="pin" type="button" data-city="Adelaide" aria-pressed="false" aria-label="Adelaide" title="Adelaide" style="--x:61.6%;--y:71.5%"></button>
|
||||
<button class="pin" type="button" data-city="Darwin" aria-pressed="false" aria-label="Darwin" title="Darwin" style="--x:45.5%;--y:10.5%"></button>
|
||||
<button class="pin" type="button" data-city="Brisbane" aria-pressed="false" aria-label="Brisbane" title="Brisbane" style="--x:91.4%;--y:51.3%"></button>
|
||||
<button class="pin" type="button" data-city="Sydney" aria-pressed="false" aria-label="Sydney" title="Sydney" style="--x:87.6%;--y:68.6%"></button>
|
||||
<button class="pin" type="button" data-city="Canberra" aria-pressed="false" aria-label="Canberra" title="Canberra" style="--x:83.3%;--y:72.5%"></button>
|
||||
<button class="pin" type="button" data-city="Melbourne" aria-pressed="false" aria-label="Melbourne" title="Melbourne" style="--x:74.7%;--y:79.3%"></button>
|
||||
<button class="pin" type="button" data-city="Hobart" aria-pressed="false" aria-label="Hobart" title="Hobart" style="--x:79.6%;--y:93.1%"></button>
|
||||
<p class="map__city" id="map-city">All of Australia</p>
|
||||
</div>
|
||||
|
||||
<form class="controls" id="finder-form" onsubmit="return false" aria-label="Match finder">
|
||||
<div class="field">
|
||||
<label for="f-city">City</label>
|
||||
<select id="f-city">
|
||||
<option>Anywhere</option><option>Adelaide</option><option>Brisbane</option><option>Canberra</option><option>Darwin</option><option>Hobart</option><option>Melbourne</option><option>Perth</option><option>Sydney</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="controls__ages">
|
||||
<div class="field">
|
||||
<div class="field__row"><label for="f-from">Age from</label><output id="o-from" for="f-from">25</output></div>
|
||||
<input id="f-from" type="range" min="21" max="60" value="25">
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field__row"><label for="f-to">Age to</label><output id="o-to" for="f-to">40</output></div>
|
||||
<input id="f-to" type="range" min="21" max="60" value="40">
|
||||
</div>
|
||||
</div>
|
||||
<fieldset class="choices" id="f-likes">
|
||||
<legend>You love</legend>
|
||||
<input type="checkbox" id="l-beach" value="beach"><label for="l-beach">Beach</label>
|
||||
<input type="checkbox" id="l-footy" value="footy"><label for="l-footy">Footy</label>
|
||||
<input type="checkbox" id="l-coffee" value="coffee"><label for="l-coffee">Coffee</label>
|
||||
<input type="checkbox" id="l-hiking" value="hiking"><label for="l-hiking">Hiking</label>
|
||||
<input type="checkbox" id="l-cooking" value="cooking"><label for="l-cooking">Cooking</label>
|
||||
<input type="checkbox" id="l-travel" value="travel"><label for="l-travel">Travel</label>
|
||||
<input type="checkbox" id="l-music" value="music"><label for="l-music">Music</label>
|
||||
<input type="checkbox" id="l-pets" value="pets"><label for="l-pets">Pets</label>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="results" id="results" aria-live="polite"></div>
|
||||
<p class="finder__note" id="finder-status"></p>
|
||||
<p class="finder__note">Sample people, made up for this demo.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sec sec--ruled checks" id="verified" aria-labelledby="verified-title">
|
||||
<div class="container grid">
|
||||
<div class="head">
|
||||
<h2 id="verified-title" data-reveal>Every profile is checked</h2>
|
||||
<p class="lead" data-reveal style="--i:1">Run the four checks on a sample profile.</p>
|
||||
</div>
|
||||
<div class="checks__panel">
|
||||
<div class="checks__who">
|
||||
<span class="avatar" style="--tone:var(--tone-a)" aria-hidden="true">M</span>
|
||||
<div><h3>Mia, 28</h3><p class="label">Sydney</p></div>
|
||||
<span class="status" id="v-status" data-state="idle" role="status"><svg class="icon icon--sm" aria-hidden="true"><use href="#i-shield"/></svg><span id="v-status-text">Not verified yet</span></span>
|
||||
</div>
|
||||
<ul class="rows" id="v-rows">
|
||||
<li data-check>
|
||||
<svg class="icon idle" aria-hidden="true"><use href="#i-phone"/></svg><svg class="icon tick" aria-hidden="true"><use href="#i-check"/></svg>
|
||||
<div><h3>Phone check</h3><p>A code arrives by text.</p></div>
|
||||
<button class="btn btn--sm" type="button" data-run>Run check</button><span class="passed" hidden>Passed</span>
|
||||
</li>
|
||||
<li data-check>
|
||||
<svg class="icon idle" aria-hidden="true"><use href="#i-camera"/></svg><svg class="icon tick" aria-hidden="true"><use href="#i-check"/></svg>
|
||||
<div><h3>Photo check</h3><p>Your photo is checked as real.</p></div>
|
||||
<button class="btn btn--sm" type="button" data-run>Run check</button><span class="passed" hidden>Passed</span>
|
||||
</li>
|
||||
<li data-check>
|
||||
<svg class="icon idle" aria-hidden="true"><use href="#i-id"/></svg><svg class="icon tick" aria-hidden="true"><use href="#i-check"/></svg>
|
||||
<div><h3>ID check</h3><p>Your ID is checked against your photo.</p></div>
|
||||
<button class="btn btn--sm" type="button" data-run>Run check</button><span class="passed" hidden>Passed</span>
|
||||
</li>
|
||||
<li data-check>
|
||||
<svg class="icon idle" aria-hidden="true"><use href="#i-users"/></svg><svg class="icon tick" aria-hidden="true"><use href="#i-check"/></svg>
|
||||
<div><h3>Team look</h3><p>A person on our team takes a quick look.</p></div>
|
||||
<button class="btn btn--sm" type="button" data-run>Run check</button><span class="passed" hidden>Passed</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="checks__foot">
|
||||
<button class="btn btn--sm" type="button" id="v-all">Run all four</button>
|
||||
<button class="btn btn--sm" type="button" id="v-reset">Start again</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sec" id="privacy" aria-labelledby="privacy-title">
|
||||
<div class="container grid">
|
||||
<figure class="privacy__photo" id="photo">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg/1280px-Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg" srcset="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg/960px-Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg 960w, https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg/1280px-Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg 1280w, https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg/1920px-Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg 1920w" sizes="(min-width: 60rem) 58vw, 100vw" width="6718" height="4479" alt="A beach below orange sandstone cliffs, standing in for a profile photo" loading="lazy">
|
||||
<img class="blur" src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg/960px-Peterborough_%28AU%29%2C_Port_Campbell_National_Park%2C_Worm_Bay_--_2019_--_0863.jpg" width="6718" height="4479" alt="" aria-hidden="true" loading="lazy">
|
||||
<span class="privacy__lock" aria-hidden="true"><svg class="icon"><use href="#i-lock"/></svg></span>
|
||||
<span class="privacy__badge" role="status"><svg class="icon icon--sm icon-open" aria-hidden="true"><use href="#i-eye"/></svg><svg class="icon icon--sm icon-shut" aria-hidden="true"><use href="#i-lock"/></svg><span id="photo-state">Hidden from this visitor</span></span>
|
||||
</figure>
|
||||
<form class="privacy__panel" onsubmit="return false" aria-label="Photo privacy">
|
||||
<h2 id="privacy-title" data-reveal>You choose who sees your photos</h2>
|
||||
<fieldset class="choices choices--stack" id="p-setting">
|
||||
<legend>Photos are visible to</legend>
|
||||
<input type="radio" name="setting" id="s-everyone" value="everyone"><label for="s-everyone">Everyone</label>
|
||||
<input type="radio" name="setting" id="s-verified" value="verified" checked><label for="s-verified">Verified members</label>
|
||||
<input type="radio" name="setting" id="s-accepted" value="accepted"><label for="s-accepted">People I accept</label>
|
||||
<input type="radio" name="setting" id="s-me" value="me"><label for="s-me">Only me</label>
|
||||
</fieldset>
|
||||
<fieldset class="choices" id="p-viewer">
|
||||
<legend>Right now, a visitor is</legend>
|
||||
<input type="radio" name="viewer" id="v-stranger" value="stranger" checked><label for="v-stranger">A stranger</label>
|
||||
<input type="radio" name="viewer" id="v-member" value="verified"><label for="v-member">A verified member</label>
|
||||
<input type="radio" name="viewer" id="v-accepted" value="accepted"><label for="v-accepted">Someone I accepted</label>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sec sec--tall talk" id="talk" aria-labelledby="talk-title">
|
||||
<div class="container">
|
||||
<div class="talk__top"><h2 id="talk-title" data-reveal>Chat opens when both say yes</h2></div>
|
||||
<div class="grid talk__body">
|
||||
<div class="invite">
|
||||
<div class="invite__who">
|
||||
<span class="avatar" style="--tone:var(--tone-c)" aria-hidden="true">P</span>
|
||||
<div><h3>Priya sent you an interest</h3><p class="label">26, Sydney</p></div>
|
||||
</div>
|
||||
<div class="invite__actions" id="invite-actions">
|
||||
<button class="btn" type="button" id="t-accept">Accept</button>
|
||||
<button class="btn" type="button" id="t-decline">No thanks</button>
|
||||
<button class="btn btn--sm" type="button" id="t-reset" hidden>Start again</button>
|
||||
</div>
|
||||
<p class="invite__result" id="t-result" role="status"></p>
|
||||
</div>
|
||||
<div class="chat is-locked" id="chat">
|
||||
<ul class="chat__log" id="chat-log" role="log" aria-label="Chat with Priya"></ul>
|
||||
<form class="chat__form" id="chat-form" autocomplete="off">
|
||||
<label class="visually-hidden" for="chat-input">Message</label>
|
||||
<input id="chat-input" name="message" type="text" maxlength="300" enterkeyhint="send">
|
||||
<button class="btn btn--sm" type="submit"><svg class="icon" aria-hidden="true"><use href="#i-send"/></svg>Send</button>
|
||||
</form>
|
||||
<div class="chat__lock"><svg class="icon" aria-hidden="true"><use href="#i-lock"/></svg><span>Chat opens when you both say yes.</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sec sec--ruled" id="family" aria-label="Family view and safety tools">
|
||||
<div class="container grid together">
|
||||
<div class="tile tile--wide">
|
||||
<h2>Family view</h2>
|
||||
<p class="lead">A parent or sibling can look at profiles with you.</p>
|
||||
<fieldset class="choices" id="fam">
|
||||
<legend>Who helps you look</legend>
|
||||
<input type="checkbox" id="h-mum" value="Mum"><label for="h-mum">Mum</label>
|
||||
<input type="checkbox" id="h-dad" value="Dad"><label for="h-dad">Dad</label>
|
||||
<input type="checkbox" id="h-sister" value="Sister"><label for="h-sister">Sister</label>
|
||||
<input type="checkbox" id="h-brother" value="Brother"><label for="h-brother">Brother</label>
|
||||
</fieldset>
|
||||
<p class="live" id="fam-status" role="status">Just you for now.</p>
|
||||
</div>
|
||||
<div class="tile tile--narrow">
|
||||
<h2>Safety tools</h2>
|
||||
<div class="safety__who">
|
||||
<span class="avatar" style="--tone:var(--tone-d)" aria-hidden="true">J</span>
|
||||
<div><h3>Jack, 35</h3><p class="label">Melbourne</p></div>
|
||||
</div>
|
||||
<div class="safety__actions">
|
||||
<button class="btn btn--sm" type="button" id="s-block"><svg class="icon" aria-hidden="true"><use href="#i-ban"/></svg><span>Block</span></button>
|
||||
<button class="btn btn--sm" type="button" id="s-report"><svg class="icon" aria-hidden="true"><use href="#i-flag"/></svg><span>Report</span></button>
|
||||
<button class="btn btn--sm" type="button" id="s-hide" aria-pressed="false"><svg class="icon" aria-hidden="true"><use href="#i-lock"/></svg><span>Hide my profile</span></button>
|
||||
</div>
|
||||
<p class="live" id="safe-status" role="status"></p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="band--deep join" id="join" aria-labelledby="join-title">
|
||||
<div class="container grid">
|
||||
<div class="head">
|
||||
<h2 id="join-title" data-reveal>Make your profile</h2>
|
||||
<dl class="qa">
|
||||
<div><dt>What does it cost?</dt><dd>A free plan and a paid plan. Paid price: <span class="fill" data-fill="paid-price">to be announced</span></dd></div>
|
||||
<div><dt>Will I get alerts?</dt><dd>Email and phone alerts for matches, interests and messages.</dd></div>
|
||||
<div><dt>Who runs the site?</dt><dd>Our team reviews profiles and reports.</dd></div>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="card" id="join-card">
|
||||
<div class="tabs" role="tablist" aria-label="Join or log in">
|
||||
<button type="button" role="tab" id="tab-join" aria-selected="true" aria-controls="panel-join">Join</button>
|
||||
<button type="button" role="tab" id="tab-login" aria-selected="false" aria-controls="panel-login" tabindex="-1">Log in</button>
|
||||
</div>
|
||||
<div class="panel" role="tabpanel" id="panel-join" aria-labelledby="tab-join">
|
||||
<form data-endpoint="" novalidate class="panel">
|
||||
<div class="field"><label for="j-name">First name</label><input id="j-name" name="name" type="text" autocomplete="given-name" required></div>
|
||||
<div class="field"><label for="j-email">Email address</label><input id="j-email" name="email" type="email" autocomplete="email" inputmode="email" required></div>
|
||||
<div class="field"><label for="j-for">Joining for</label>
|
||||
<select id="j-for" name="for"><option>Myself</option><option>My son</option><option>My daughter</option><option>My brother or sister</option></select>
|
||||
</div>
|
||||
<button class="btn btn--primary" type="submit">Make my profile</button>
|
||||
<p class="form-help" aria-live="polite"></p>
|
||||
</form>
|
||||
</div>
|
||||
<div class="panel" role="tabpanel" id="panel-login" aria-labelledby="tab-login">
|
||||
<form data-endpoint="" novalidate class="panel">
|
||||
<div class="field"><label for="l-email">Email address</label><input id="l-email" name="email" type="email" autocomplete="email" inputmode="email" required></div>
|
||||
<button class="btn btn--primary" type="submit">Log in</button>
|
||||
<p class="form-help" aria-live="polite"></p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="foot">
|
||||
<div class="container">
|
||||
<p class="foot__sign">Warmly, the BeingOne team.</p>
|
||||
<div class="foot__row">
|
||||
<p>For Australians and their families. <time datetime="2026-10">October 2026</time></p>
|
||||
<ul class="foot__links">
|
||||
<li><a href="#find">Find</a></li>
|
||||
<li><a href="#verified">Checks</a></li>
|
||||
<li><a href="#privacy">Photos</a></li>
|
||||
<li><a href="#talk">Chat</a></li>
|
||||
<li><a href="#join">Join</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<p data-credits>Photographs: <a href="https://commons.wikimedia.org/wiki/File:Peterborough_(AU),_Port_Campbell_National_Park,_Worm_Bay_--_2019_--_0863.jpg">Dietmar Rabich</a> (CC BY-SA 4.0, Wikimedia Commons)</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,237 @@
|
||||
/* Hallmark · shape: Marquee Hero · genre: playful · theme: Squeeze (deal 2/3, seed beingone-marriage-australians-verified-c51f·ff37d1cd·2026-10-23·r0) · job: sign up · draw: 48b5d3
|
||||
* hero: Banner · nav: edge-aligned · footer: letter close · imagery: photographs, library 1, natural · signature: the match finder, a map of Australia you tap and a score that moves
|
||||
* axes: mid/geometric-sans/warm · posture: drenched · contrast: pass · fold: pass · v2.0.0 */
|
||||
/* Hallmark · pre-emit critique: P4 H4 E4 S4 R4 V4 · weakest: S, the sample people could belong to any dating page; the map pins, the four named checks and the photo-privacy rule set make it BeingOne's own */
|
||||
/* Hallmark · answered F4 · the hero button and the join card button are the same primary action, repeated at the close */
|
||||
/* Hallmark · dismissed F7 · the pill radius sits on controls only: nav links, choice chips and the map pins are all pressed to act */
|
||||
/* Hallmark · dismissed F7 · the Squeeze theme is built from tiles at one card radius, and the finder, checks and chat tiles each hold a different kind of control */
|
||||
@import url("./tokens.css");
|
||||
@import url("./base.css");
|
||||
|
||||
:root {
|
||||
--tone-a: oklch(86% 0.09 20); --tone-b: oklch(92% 0.11 98); --tone-c: oklch(85% 0.08 205); --tone-d: oklch(89% 0.09 135);
|
||||
--nav-h: 72px;
|
||||
}
|
||||
|
||||
/* page frame */
|
||||
.skip { position: absolute; left: var(--space-md); top: calc(-1 * var(--space-3xl)); z-index: var(--z-toast); padding: var(--space-xs) var(--space-md); background: var(--color-card); color: var(--color-card-ink); border-radius: var(--radius-control); font-weight: 700; }
|
||||
.skip:focus-visible { top: var(--space-md); }
|
||||
.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap-columns); }
|
||||
.sec { padding-block: var(--space-3xl); }
|
||||
.sec--tall { padding-block: var(--space-4xl); }
|
||||
.sec--ruled > .container { border-top: var(--rule-bar) solid var(--color-rule); padding-top: var(--space-3xl); }
|
||||
.band { background: var(--color-paper-2); color: var(--color-ink); padding-block: var(--section-gap-s); }
|
||||
.band--deep { background: var(--color-paper-3); color: var(--color-ink); padding-block: var(--section-gap-s); }
|
||||
.head { display: grid; gap: var(--space-md); align-content: start; }
|
||||
.head .lead { color: var(--color-muted); }
|
||||
.label { font-size: var(--text-sm); font-weight: 700; color: var(--color-muted); }
|
||||
.muted { color: var(--color-muted); }
|
||||
.fill { padding: 0 0.25em; border: 1px dashed color-mix(in oklch, var(--color-muted) 70%, transparent); border-radius: 3px; color: var(--color-muted); -webkit-box-decoration-break: clone; box-decoration-break: clone; }
|
||||
.icon { width: 24px; height: 24px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.icon--sm { width: 20px; height: 20px; }
|
||||
|
||||
/* nav: edge-aligned */
|
||||
.nav { position: sticky; top: 0; z-index: var(--z-sticky-nav); height: var(--nav-h); background: var(--color-paper); }
|
||||
.nav .container { height: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-lg); }
|
||||
.wordmark { font: 800 var(--text-xl)/1 var(--font-display); letter-spacing: var(--tracking-display); text-decoration: none; color: var(--color-ink); }
|
||||
.nav__links { display: flex; align-items: center; gap: var(--space-xs); }
|
||||
.nav__links a:not(.btn) { padding: var(--space-xs) var(--space-md); border-radius: var(--radius-pill); text-decoration: none; font-weight: 700; font-size: var(--text-sm); transition: background-color var(--dur-short) var(--ease-out); }
|
||||
.nav__links a:not(.btn):hover { background: var(--color-paper-2); }
|
||||
@media (max-width: 60rem) { .nav__links a.hide-sm { display: none; } }
|
||||
|
||||
/* controls */
|
||||
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs); min-height: 52px; padding: 0 var(--space-lg); border: var(--rule-bar) solid var(--color-ink); border-radius: var(--radius-control); background: transparent; color: var(--color-ink); font: 700 var(--text-md)/1.25 var(--font-body); text-decoration: none; white-space: nowrap; cursor: pointer; transition: transform var(--dur-micro) var(--ease-out), background-color var(--dur-micro) var(--ease-out), color var(--dur-micro) var(--ease-out), border-color var(--dur-micro) var(--ease-out); }
|
||||
.btn:hover { background: var(--color-paper-3); }
|
||||
.btn:active { transform: translateY(1px); }
|
||||
.btn--sm { min-height: 44px; padding: 0 var(--space-md); font-size: var(--text-sm); }
|
||||
.btn--primary { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-accent-ink); }
|
||||
.btn--primary:hover { background: var(--color-accent-2); border-color: var(--color-accent-2); }
|
||||
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; transform: none; }
|
||||
.btn[aria-busy="true"] { cursor: progress; }
|
||||
.btn[aria-pressed="true"] { background: var(--color-paper-3); box-shadow: inset 0 0 0 3px var(--color-accent); }
|
||||
.btn .icon { width: 20px; height: 20px; }
|
||||
|
||||
/* chips and choices: radios and checkboxes stay in flow at one pixel */
|
||||
.choices { position: relative; display: flex; flex-wrap: wrap; gap: var(--space-xs); border: 0; margin: 0; padding: 0; min-width: 0; }
|
||||
.choices legend { padding: 0; margin-bottom: var(--space-sm); font-size: var(--text-sm); font-weight: 700; color: var(--color-muted); }
|
||||
.choices input { position: absolute; opacity: 0; width: 1px; height: 1px; }
|
||||
.choices label { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--space-md); border: var(--rule-bar) solid var(--color-rule); border-radius: var(--radius-pill); font-weight: 700; font-size: var(--text-sm); cursor: pointer; transition: background-color var(--dur-short) var(--ease-out), box-shadow var(--dur-short) var(--ease-out); }
|
||||
.choices label:hover { background: var(--color-paper-3); }
|
||||
.choices input:checked + label { background: var(--color-paper-3); border-color: var(--color-paper-3); box-shadow: 0 0 0 3px var(--color-accent); }
|
||||
.choices input:focus-visible + label { outline: 2px solid var(--color-focus); outline-offset: 4px; }
|
||||
.choices--stack { flex-direction: column; flex-wrap: nowrap; }
|
||||
.choices--stack label { border-radius: var(--radius-control); width: 100%; }
|
||||
.choices--stack input:checked + label { box-shadow: inset 0 0 0 3px var(--color-accent); border-color: var(--color-paper-3); }
|
||||
|
||||
.field { display: grid; gap: var(--space-xs); }
|
||||
.field label { font-size: var(--text-sm); font-weight: 700; }
|
||||
.field input:not([type="range"]), .field select, .chat__form input { width: 100%; min-height: 52px; padding: 0 var(--space-md); border: var(--rule-bar) solid var(--color-muted); border-radius: var(--radius-control); background: transparent; color: inherit; outline: 2px solid transparent; outline-offset: -3px; }
|
||||
.field select option { color: var(--color-card-ink); background: var(--color-card); }
|
||||
.field input:not([type="range"]):focus-visible, .field select:focus-visible, .chat__form input:focus-visible { outline-color: var(--color-focus); }
|
||||
.field input[aria-invalid] { border-color: var(--color-error); }
|
||||
.field input[type="range"] { width: 100%; accent-color: var(--color-accent); min-height: 32px; cursor: pointer; }
|
||||
.field output { font: 800 var(--text-lg)/1 var(--font-display); font-variant-numeric: tabular-nums; }
|
||||
.field__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-md); }
|
||||
|
||||
/* hero: banner, poster-scale head */
|
||||
.hero { padding-block: var(--space-xl) var(--space-xl); }
|
||||
.band--path { padding-block: var(--space-lg) var(--space-xl); }
|
||||
.hero h1 { grid-column: 1 / 9; max-width: none; font-size: clamp(3rem, 7.4vw, 6.5rem); line-height: 1; }
|
||||
.hero h1 span { display: block; }
|
||||
.hero__side { grid-column: 9 / 13; align-self: end; display: grid; gap: var(--space-lg); justify-items: start; padding-bottom: var(--space-sm); }
|
||||
.hero__side .lead { color: var(--color-ink-2); }
|
||||
@media (max-width: 60rem) { .hero h1, .hero__side { grid-column: 1 / -1; } .hero__side { margin-top: var(--space-lg); } }
|
||||
|
||||
/* path: a real ol */
|
||||
.path { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--gap-columns); counter-reset: step; }
|
||||
.path li { counter-increment: step; display: grid; gap: var(--space-xs); align-content: start; }
|
||||
.path li::before { content: counter(step); font: 800 clamp(3.5rem, 6vw, 5.5rem)/0.9 var(--font-display); letter-spacing: -0.04em; font-variant-numeric: lining-nums tabular-nums; }
|
||||
.path a { font: 800 var(--text-title)/1.15 var(--font-display); letter-spacing: var(--tracking-display); text-decoration: none; text-underline-offset: 0.2em; }
|
||||
.path a:hover { text-decoration: underline; text-decoration-color: var(--color-accent); text-decoration-thickness: 3px; }
|
||||
@media (max-width: 60rem) { .path { grid-template-columns: minmax(0, 1fr); gap: var(--space-md); } .path li { grid-template-columns: 64px minmax(0, 1fr); align-items: center; } .path li::before { font-size: var(--text-3xl); } }
|
||||
|
||||
/* finder */
|
||||
.finder__top { align-items: end; margin-bottom: var(--space-2xl); }
|
||||
.finder__top h2 { grid-column: 1 / 8; }
|
||||
.finder__top .lead { grid-column: 8 / 13; color: var(--color-muted); }
|
||||
.finder__body { align-items: stretch; }
|
||||
.map { grid-column: 1 / 6; position: relative; aspect-ratio: 605 / 516; background: var(--color-paper-2); border-radius: var(--radius-card); }
|
||||
.map svg { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.map path { fill: var(--color-paper-3); stroke: var(--color-rule); stroke-width: 2; stroke-linejoin: round; }
|
||||
.pin { position: absolute; left: var(--x); top: var(--y); width: 36px; height: 36px; transform: translate(-50%, -50%); padding: 0; border: 0; background: transparent; cursor: pointer; border-radius: var(--radius-pill); }
|
||||
.pin::before { content: ""; position: absolute; inset: 11px; border-radius: var(--radius-pill); background: var(--color-ink); transition: transform var(--dur-short) var(--ease-out), background-color var(--dur-short) var(--ease-out); }
|
||||
.pin:hover::before { transform: scale(1.35); }
|
||||
.pin[aria-pressed="true"]::before { background: var(--color-accent); transform: scale(1.9); box-shadow: 0 0 0 3px var(--color-paper-3); }
|
||||
.pin:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 0; }
|
||||
.map__city { position: absolute; left: var(--space-md); bottom: var(--space-md); padding: var(--space-xs) var(--space-md); border-radius: var(--radius-control); background: var(--color-paper-3); font-size: var(--text-sm); font-weight: 700; }
|
||||
.controls { grid-column: 6 / 13; display: grid; gap: var(--space-lg); align-content: space-between; padding: var(--space-xl); background: var(--color-paper-2); border-radius: var(--radius-card); }
|
||||
.controls__ages { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap-columns); }
|
||||
.results { margin-top: var(--space-xl); display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--gap-columns); min-height: 300px; }
|
||||
.person { display: grid; gap: var(--space-md); align-content: space-between; padding: var(--space-lg); background: var(--color-paper-2); border-radius: var(--radius-card); animation: rise var(--dur-long) var(--ease-out) both; animation-delay: calc(var(--i, 0) * 60ms); }
|
||||
.person__who { display: flex; align-items: center; gap: var(--space-md); }
|
||||
.person h3 { font-size: var(--text-lg); }
|
||||
.avatar { width: 56px; height: 56px; flex-shrink: 0; display: grid; place-items: center; border-radius: var(--radius-pill); background: var(--tone, var(--tone-a)); color: var(--color-card-ink); font: 800 var(--text-lg)/1 var(--font-display); }
|
||||
.score { display: flex; align-items: baseline; gap: var(--space-xs); }
|
||||
.score b { font: 800 var(--text-3xl)/1 var(--font-display); letter-spacing: -0.03em; font-variant-numeric: lining-nums tabular-nums; }
|
||||
.bar { height: 8px; margin-top: var(--space-xs); border-radius: var(--radius-pill); background: var(--color-paper-3); overflow: hidden; }
|
||||
.bar i { display: block; height: 100%; background: var(--color-ink); transform-origin: left; transform: scaleX(calc(var(--s, 0) / 100)); animation: grow var(--dur-long) var(--ease-out) both; animation-delay: calc(var(--i, 0) * 60ms + 120ms); }
|
||||
.tags { display: flex; flex-wrap: wrap; gap: var(--space-xs); padding: 0; margin: 0; list-style: none; }
|
||||
.tags li { padding: var(--space-3xs) var(--space-sm); border-radius: var(--radius-pill); border: var(--rule-bar) solid var(--color-rule); font-size: var(--text-sm); font-weight: 700; }
|
||||
.tags li.is-shared { background: var(--color-paper-3); border-color: var(--color-paper-3); }
|
||||
.results__empty { grid-column: 1 / -1; align-self: center; font: 800 var(--text-xl)/1.2 var(--font-display); max-width: 30ch; }
|
||||
.finder__note { margin-top: var(--space-md); font-size: var(--text-sm); color: var(--color-muted); }
|
||||
@keyframes rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
|
||||
@keyframes grow { from { transform: scaleX(0); } }
|
||||
@media (max-width: 60rem) {
|
||||
.finder__top h2, .finder__top .lead, .map, .controls { grid-column: 1 / -1; }
|
||||
.finder__top .lead { margin-top: var(--space-md); }
|
||||
.controls { margin-top: var(--space-lg); padding: var(--space-lg); }
|
||||
.results { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||
}
|
||||
@media (max-width: 40rem) { .results { grid-template-columns: minmax(0, 1fr); } .controls__ages { grid-template-columns: minmax(0, 1fr); } }
|
||||
|
||||
/* checks */
|
||||
.checks .head { grid-column: 1 / 6; }
|
||||
.checks__panel { grid-column: 7 / 13; background: var(--color-paper-2); color: var(--color-ink); border-radius: var(--radius-card); padding: var(--space-lg); display: grid; gap: var(--space-md); }
|
||||
.checks__who { display: flex; align-items: center; gap: var(--space-md); padding-bottom: var(--space-md); }
|
||||
.checks__who h3 { font-size: var(--text-lg); }
|
||||
.status { margin-left: auto; display: inline-flex; align-items: center; gap: var(--space-xs); padding: var(--space-xs) var(--space-md); border-radius: var(--radius-pill); background: var(--color-paper-3); font-size: var(--text-sm); font-weight: 700; }
|
||||
.status .icon { display: none; }
|
||||
.status[data-state="done"] { background: var(--color-ink); color: var(--color-card-ink); }
|
||||
.status[data-state="done"] .icon { display: block; }
|
||||
.rows { list-style: none; margin: 0; padding: 0; }
|
||||
.rows > li { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; gap: var(--space-md); align-items: center; padding-block: var(--space-md); border-top: var(--rule-hair) solid var(--color-rule); }
|
||||
.rows h3 { font-size: var(--text-md); font-family: var(--font-body); font-weight: 700; letter-spacing: 0; line-height: 1.3; }
|
||||
.rows p { font-size: var(--text-sm); color: var(--color-muted); }
|
||||
.rows .is-done { color: var(--color-ink); }
|
||||
.rows .tick { display: none; }
|
||||
.rows .is-done .tick { display: block; animation: rise var(--dur-short) var(--ease-out) both; }
|
||||
.rows .is-done .idle { display: none; }
|
||||
.rows .passed { font-weight: 700; font-size: var(--text-sm); }
|
||||
.checks__foot { display: flex; justify-content: space-between; align-items: center; gap: var(--space-md); border-top: var(--rule-hair) solid var(--color-rule); padding-top: var(--space-md); }
|
||||
@media (max-width: 60rem) { .checks .head, .checks__panel { grid-column: 1 / -1; } .checks__panel { margin-top: var(--space-xl); } }
|
||||
@media (max-width: 40rem) { .rows > li { grid-template-columns: 24px minmax(0, 1fr); } .rows .btn, .rows .passed { grid-column: 2; justify-self: start; } .checks__who { flex-wrap: wrap; } }
|
||||
|
||||
/* photo privacy */
|
||||
.privacy__photo { grid-column: 1 / 8; position: relative; aspect-ratio: 4 / 3; border-radius: var(--radius-card); overflow: hidden; background: var(--color-paper-3); margin: 0; }
|
||||
.privacy__photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 35% 40%; filter: saturate(1.06) contrast(1.04); }
|
||||
.privacy__photo .blur { filter: blur(28px) saturate(1.06); transform: scale(1.15); transition: opacity var(--dur-long) var(--ease-in-out); }
|
||||
.js .privacy__photo:not(.is-hidden) .blur { opacity: 0; }
|
||||
.privacy__badge { position: absolute; left: var(--space-lg); bottom: var(--space-lg); display: inline-flex; align-items: center; gap: var(--space-xs); padding: var(--space-xs) var(--space-md); border-radius: var(--radius-pill); background: var(--color-paper-3); font-size: var(--text-sm); font-weight: 700; z-index: 2; }
|
||||
.privacy__lock { position: absolute; inset: 0; display: grid; place-items: center; z-index: 2; transition: opacity var(--dur-long) var(--ease-in-out); }
|
||||
.privacy__lock .icon { width: 72px; height: 72px; stroke-width: 1.75; }
|
||||
.js .privacy__photo:not(.is-hidden) .privacy__lock { opacity: 0; }
|
||||
.privacy__panel { grid-column: 9 / 13; display: grid; gap: var(--space-lg); align-content: center; }
|
||||
.privacy__badge .icon-open, .privacy__badge .icon-shut { display: none; }
|
||||
.privacy__photo:not(.is-hidden) .icon-open { display: block; }
|
||||
.privacy__photo.is-hidden .icon-shut { display: block; }
|
||||
@media (max-width: 60rem) { .privacy__photo, .privacy__panel { grid-column: 1 / -1; } .privacy__panel { margin-top: var(--space-xl); } }
|
||||
|
||||
/* talk */
|
||||
.talk__top { margin-bottom: var(--space-2xl); }
|
||||
.talk__body { align-items: stretch; }
|
||||
.invite { grid-column: 1 / 6; display: grid; gap: var(--space-lg); align-content: space-between; padding: var(--space-xl); background: var(--color-paper-2); border-radius: var(--radius-card); }
|
||||
.invite__who { display: flex; align-items: center; gap: var(--space-md); }
|
||||
.invite h3 { font-size: var(--text-xl); }
|
||||
.invite__actions { display: flex; flex-wrap: wrap; gap: var(--space-sm); }
|
||||
.invite__result { min-height: 1lh; font-weight: 700; }
|
||||
.chat { grid-column: 6 / 13; position: relative; display: grid; grid-template-rows: minmax(0, 1fr) auto; min-height: 380px; padding: var(--space-lg); background: var(--color-paper-3); border-radius: var(--radius-card); }
|
||||
.chat__log { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: var(--space-xs); overflow-y: auto; }
|
||||
.chat__log li { max-width: 80%; padding: var(--space-xs) var(--space-md); border-radius: var(--radius-control); background: var(--color-paper-2); animation: rise var(--dur-short) var(--ease-out) both; overflow-wrap: break-word; }
|
||||
.chat__log li.me { align-self: flex-end; background: var(--color-ink); color: var(--color-card-ink); }
|
||||
.chat__log li.note { align-self: center; max-width: 100%; background: transparent; color: var(--color-muted); font-size: var(--text-sm); font-weight: 700; }
|
||||
.chat__form { display: flex; gap: var(--space-sm); margin-top: var(--space-md); }
|
||||
.chat__form input { flex: 1; min-width: 0; }
|
||||
.chat.is-locked .chat__log, .chat.is-locked .chat__form { visibility: hidden; }
|
||||
.chat__lock { position: absolute; inset: 0; display: none; place-items: center; align-content: center; gap: var(--space-sm); text-align: center; padding: var(--space-lg); font: 800 var(--text-xl)/1.2 var(--font-display); }
|
||||
.chat__lock .icon { width: 48px; height: 48px; margin-inline: auto; }
|
||||
.chat.is-locked .chat__lock { display: grid; }
|
||||
@media (max-width: 60rem) { .invite, .chat { grid-column: 1 / -1; } .chat { margin-top: var(--space-lg); } }
|
||||
|
||||
/* family and safety: bento */
|
||||
.together { align-items: stretch; row-gap: var(--gap-columns); }
|
||||
.tile { display: grid; gap: var(--space-lg); align-content: start; padding: var(--space-xl); background: var(--color-paper-2); border-radius: var(--radius-card); }
|
||||
.tile--wide { grid-column: 1 / 8; }
|
||||
.tile--narrow { grid-column: 8 / 13; background: var(--color-paper-3); }
|
||||
.tile h2 { font-size: var(--text-section); }
|
||||
.tile .lead { color: var(--color-muted); }
|
||||
.safety__who { display: flex; align-items: center; gap: var(--space-md); }
|
||||
.safety__actions { display: flex; flex-wrap: wrap; gap: var(--space-sm); }
|
||||
.live { min-height: 1lh; font-weight: 700; }
|
||||
@media (max-width: 60rem) { .tile--wide, .tile--narrow { grid-column: 1 / -1; } .tile { padding: var(--space-lg); } }
|
||||
|
||||
/* questions and join */
|
||||
.join .head { grid-column: 1 / 7; align-content: start; gap: var(--space-xl); }
|
||||
.qa { margin: 0; display: grid; }
|
||||
.qa > div { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--space-md); padding-block: var(--space-md); border-top: var(--rule-hair) solid var(--color-rule); }
|
||||
.qa dt { font: 800 var(--text-md)/1.3 var(--font-display); letter-spacing: var(--tracking-display); }
|
||||
.qa dd { margin: 0; color: var(--color-muted); font-size: var(--text-md); }
|
||||
.card { grid-column: 8 / 13; background: var(--color-card); color: var(--color-card-ink); border-radius: var(--radius-card); box-shadow: var(--shadow-card); padding: var(--space-xl); display: grid; gap: var(--space-lg); align-content: start; }
|
||||
.card :focus-visible { outline-color: var(--color-card-ink); }
|
||||
.card h2 { font-size: var(--text-section); }
|
||||
.tabs { display: flex; gap: var(--space-xs); border-bottom: var(--rule-bar) solid color-mix(in oklab, var(--color-card-ink) 20%, var(--color-card)); }
|
||||
.tabs button { min-height: 44px; padding: 0 var(--space-md); border: 0; border-bottom: 4px solid transparent; margin-bottom: calc(-1 * var(--space-3xs)); background: transparent; color: inherit; font-weight: 700; cursor: pointer; transition: border-color var(--dur-short) var(--ease-out); }
|
||||
.tabs button[aria-selected="true"] { border-bottom-color: var(--color-accent-2); }
|
||||
.card .field input, .card .field select { border-color: color-mix(in oklab, var(--color-card-ink) 70%, var(--color-card)); }
|
||||
.card .field select option { color: var(--color-card-ink); }
|
||||
.card .btn { border-color: var(--color-accent-2); }
|
||||
.card .btn--primary { background: var(--color-accent); border-color: var(--color-accent-2); }
|
||||
.card .btn--primary:hover { background: var(--color-accent-2); }
|
||||
.form-help { min-height: 1lh; font-size: var(--text-sm); }
|
||||
.form-help.is-error { color: var(--color-error); font-weight: 700; }
|
||||
.panel { display: grid; gap: var(--space-md); }
|
||||
@media (max-width: 60rem) { .join .head, .card { grid-column: 1 / -1; } .card { margin-top: var(--space-xl); padding: var(--space-lg); } .qa > div { grid-template-columns: minmax(0, 1fr); gap: var(--space-2xs); } }
|
||||
|
||||
/* footer: letter close */
|
||||
.foot { padding-block: var(--space-3xl) var(--space-xl); }
|
||||
.foot__sign { font: 800 var(--text-section)/1.05 var(--font-display); letter-spacing: var(--tracking-display); max-width: 18ch; text-wrap: balance; }
|
||||
.foot__row { margin-top: var(--space-2xl); display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-lg); font-size: var(--text-sm); }
|
||||
.foot__links { display: flex; flex-wrap: wrap; gap: var(--space-lg); list-style: none; margin: 0; padding: 0; }
|
||||
.foot__links a { font-weight: 700; }
|
||||
.foot__links a:hover { text-decoration-color: var(--color-accent); text-decoration-thickness: 3px; }
|
||||
.foot [data-credits] { margin-top: var(--space-lg); color: var(--color-muted); font-size: var(--text-xs); max-width: 80ch; }
|
||||
|
||||
/* one reveal, visible without script */
|
||||
.js [data-reveal] { opacity: 0; transform: translateY(10px); transition: opacity var(--dur-long) var(--ease-out), transform var(--dur-long) var(--ease-out); transition-delay: calc(var(--i, 0) * 70ms); }
|
||||
.js [data-reveal].is-in { opacity: 1; transform: none; }
|
||||
@media (prefers-reduced-motion: reduce) { .js [data-reveal] { opacity: 1; transform: none; transition: none; } .person, .bar i, .chat__log li, .rows .is-done .tick { animation: none; } .bar i { transform: scaleX(calc(var(--s, 0) / 100)); } }
|
||||
@@ -0,0 +1,21 @@
|
||||
:root {
|
||||
color-scheme: light;
|
||||
--space-3xs: 2px; --space-2xs: 4px; --space-xs: 8px; --space-sm: 12px; --space-md: 16px; --space-lg: 24px; --space-xl: 40px; --space-2xl: 64px; --space-3xl: 96px; --space-4xl: 144px;
|
||||
--text-xs: 0.8125rem; --text-sm: 0.875rem; --text-md: 1rem; --text-lg: 1.25rem; --text-xl: 1.5625rem; --text-2xl: 1.953rem; --text-3xl: 2.441rem;
|
||||
--text-display-s: clamp(2.25rem, 4vw + 0.5rem, 3.75rem); --text-display: clamp(2.75rem, 5vw + 1rem, 5.25rem);
|
||||
--text-section: clamp(2rem, 2.5vw + 1rem, 3.5rem); --text-title: clamp(1.25rem, 0.75vw + 0.875rem, 1.625rem); --text-lead: clamp(1.125rem, 0.35vw + 1rem, 1.375rem);
|
||||
--ease-out: cubic-bezier(0.16, 1, 0.3, 1); --ease-in: cubic-bezier(0.7, 0, 0.84, 0); --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
||||
--dur-micro: 120ms; --dur-short: 220ms; --dur-long: 420ms;
|
||||
--color-error: oklch(52% 0.19 27); --color-success: oklch(50% 0.12 150);
|
||||
--container: 1440px; --gutter: 64px; --gap-columns: 32px; --section-gap-s: 120px; --section-gap: 144px; --section-gap-l: 176px;
|
||||
--z-base: 1; --z-raised: 10; --z-dropdown: 100; --z-sticky: 200; --z-sticky-nav: 300; --z-modal: 400; --z-toast: 500; --z-tooltip: 600;
|
||||
--color-paper: oklch(41% 0.100 154); --color-paper-2: oklch(47% 0.105 154); --color-paper-3: oklch(34% 0.090 156);
|
||||
--color-ink: oklch(99% 0.005 90); --color-ink-2: oklch(94% 0.020 120); --color-muted: oklch(90% 0.030 150); --color-rule: oklch(55% 0.100 154);
|
||||
--color-accent: oklch(83% 0.115 56); --color-accent-2: oklch(74% 0.150 46); --color-accent-ink: oklch(30% 0.070 40); --color-focus: oklch(88% 0.14 85);
|
||||
--color-card: oklch(97% 0.012 85); --color-card-ink: oklch(24% 0.05 160);
|
||||
--font-display: "Gabarito", ui-sans-serif, system-ui, sans-serif; --font-body: "Manrope", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-outlier: var(--font-display);
|
||||
--radius-card: 24px; --radius-control: 16px; --radius-pill: 999px; --rule-hair: 1px; --rule-bar: 2px;
|
||||
--shadow-card: 0 14px 32px -16px oklch(22% 0.05 160 / 0.5);
|
||||
--tracking-display: -0.025em; --display-weight: 800;
|
||||
}
|
||||
Reference in new issue
Block a user