AmoleoFamily

Layout Components

Welcome back

One Amoleo account for Pets, Connections, and everything else in the family.

Sign In

Powered by Amoleo·Accounts

No account yet? Signing in creates one the first time — there's nothing separate to fill in.

No local password field anywhere — the button redirects to Accounts' hosted sign-in, which handles both signing in and registration. Coloured with Pets' own --accent (#D9603F); Connections' AuthScreen.jsx is the other live implementation, same shape.

Family auth box — the login/register component

The sign-in-or-create-an-account card every logged-in Amoleo product shows before a visitor is authenticated. Amoleo-Connections' AuthScreen.jsx / .auth-card is the reference implementation — this doc writes down what about it is shared family design versus what any product wearing it is free to change.

docs/family-header.md already named Connections as this pattern's origin ("Two states, not three... modelled on Connections' actual implementation") and recorded that Connections' component "becomes the canonical one — not just for Connections." This doc is that promise kept: the component's own mechanics, moved out of the header spec (which only needed to say where it sits) and into a spec of its own, the same split family-wordmark.md made for the header and footer sizes that reference it.

Where it sits inside a page is the header spec's job, not this one's — desktop hero + in-page form vs. mobile sticky pop-down, breakpoints, how it relates to the header bar. See family-header.md, "Two states, not three." This doc covers the card itself: its structure, its states, and — the part that actually varies product to product — where it takes its colour from.

node tools/check-auth-box.mjs

1. One component, five products' worth of accent

The whole point: the box looks identical in shape across every product and never identical in colour. Tabs, fields, buttons, spacing, radii — all one shared design. The highlight colour — the active tab, the focus ring, the submit button, the link hover — is always the current product's own --accent, never a fixed hex baked into the component.

This is the same relationship the footer lockup has to --brand-* (shared structure, per-product colour — family-footer.md §2) and the header's link/button rule has to each site's theme tokens (family-header.md §4). The auth box is the third surface that shape applies to, and the one where getting it wrong is easiest to miss: a hardcoded #0b6e8f (Connections' own accent) copied into Pets' version of this component would render, would look intentional, and would be wrong the day anyone reused the component without also swapping the colour by hand.

Two tokens carry the whole rule:

Token Used for
--accent Active tab background, input focus outline, submit button, link/hover colour
--on-accent Text/icon colour sitting on top of --accent fills (the active tab's label, the submit button's label)

Everything else the card uses is neutral — family-theme.md's shared base (panel, bg, text, muted, border) plus the semantic --danger / --danger-tint pair for the error state, under whatever names each repo's own theme gives them (family-theme.md §2 already documents that Website, Connections and Pets don't agree on names for the same five concepts — the auth box inherits that aliasing, it doesn't invent a second scheme).

Checked, not just written down: check-auth-box.mjs reads the CSS rule that styles the active tab and the submit button in every adopted repo and fails if either sets its highlight colour to a literal hex/rgb() instead of a var(--...) reference — the same shape of check checkSuffixColour already runs for the wordmark (family-theme.md §3.5). It cannot confirm the variable resolves to that product's own accent rather than someone else's (that needs the alias map a human keeps current in auth-box.json, same as baseTheme.repos.<name>.aliases) — only that it isn't a number.


2. Structure — the part that's a literal shared component

Unlike the header (rules, not one markup block — different repos need genuinely different content) the auth box is one component, the way the footer is: the same tabs, the same fields, the same states, copied into each repo rather than each repo inventing its own shape. tools/auth-box.json's classes section is the literal class-name contract check-auth-box.mjs looks for.

Reference markup: Amoleo-Connections/client/src/components/AuthScreen.jsx. The CSS itself was extracted from Connections' /* Sign in and create account */ block into tools/family-css/components/auth-box.css, compiled into family-css/base.css — see docs/family-css-system.md. Connections wired the shared file in and completed the --panel-2/--border rename family-css-system.md §4 describes on 6 Aug 2026 — its own duplicated auth box CSS is gone from styles.css now, replaced by the shared file plus two small per-context overrides (.landing-auth .auth-card's padding delta, noted inline). What's canonical lives in the one file now, not two converging copies.


3. Validation is touched-based, not eager

A field only shows .field-problem once it has been left (onBlur) or the form has been submitted — never while the visitor is still typing the first character. Telling someone their email is invalid before they've finished typing it is nagging, not help. This is a behavioural rule, not something a text-search checker can verify from CSS — it's listed here so a reimplementation doesn't quietly drop it, and is one of the items in §6 a human still confirms by eye.

What each product validates is its own business rule and stays that way. Password length (Connections: 10 characters), username shape and reserved words, whatever server-side rules a product enforces — none of that is shared design, and this spec does not try to make it so. What's shared is the pattern — touched-based reveal, a hint that becomes a problem, one slot for both — not the specific rules run through it.


4. States — two tabs, not three, and not a modal

Corrected the same day family-header.md was: the login/register form is not a separate screen from the marketing/landing content, and sign-in and register are not two separate screens either. There is exactly one pre-auth state, and inside it exactly one card whose two tabs swap which half of the form is visible. No route change, no modal, no page navigation between "login" and "register" — switchMode() just flips local state.


5. Per-repo status

Repo Applicable? Adopted? Notes
Amoleo-Connections Yes Yes — reference implementation AuthScreen.jsx / .auth-card in client/src/. Everything in §1–4 above was extracted from this code, not designed fresh.
Amoleo-Pets Yes No Separate LoginForm.jsx / RegisterForm.jsx on the generic .card class — no tabs (a "Create New Account" button instead), no password show/hide, no field-hint/field-problem split, eager-ish validation. Recorded in family-header.md §2 as owed work: Pets moves onto the Connections pattern wholesale, header and auth box together, not two separate migrations.
Amoleo-Website No No login system. Nothing renders in its place.
Amoleo-Rissbrook No No login system, and none planned — a static genealogy archive.
Amoleo-Accounts Yes Yes — adopted via #6 client/src/components/AuthCard.jsx, wired to the server-side interaction plumbing (server/src/routes/interactionApi.js) and placed per Decision 9 (family-header.md). This row said "no code yet" for some time after Accounts shipped — corrected 3 Sept 2026; tools/auth-box.json had the current state right the whole time, only this table had drifted.
Amoleo-Todo Unknown No — no code yet Design-only; whether Todo gets its own login or rides Accounts' SSO isn't decided. Not registered in auth-box.json until it is.

6. What to check afterwards

Automated (check-auth-box.mjs):

By eye, on top of that:

Generated from PetWeightTracker/client/src/components/AuthCard.jsx + K-Drama Connections/client/src/components/AuthScreen.jsx (live implementations — docs/family-auth-box.md and tools/auth-box.json are stale, see note above). Edit there and re-run npm run build in docs-site-src/ — never hand-edit a page.