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

0. Two variants, one shell (#62, 30 Sept 2026)

There is no single "reference repo". The card comes in two legitimate variants that share one shell (.auth-card, .auth-heading, .auth-tagline, .auth-submit, .auth-switch):

What varies per site: the accent (--accent / --on-accent), the tagline, and the footnote. Everything else is shared CSS (tools/family-css/components/auth-box.css, compiled into base.css). The redirect variant's JSX is shared too (Amoleo-Accounts#63): the AuthRedirectCard component in family-ui/, published as @valadamoleo/family-ui, takes those three per-site things (plus the heading, CTA label, link and a children slot) as props. It is a plain <a href> — the shape Connections' sign-in already has; an app that needs click-time logic adapts to the link (Pets, for its login nonce, on its own adoption card). It is delivered like the CSS, through each app's isolated scripts/family-css fetcher, not as a normal client/ dependency — see family-css-system.md, "Shared components: @valadamoleo/family-ui", and family-ui/README.md for the adoption checklist. The terminal variant's JSX stays in Accounts (its only consumer). Website, Images and Rissbrook (no React / no login) are unaffected: a separate package, so family-css stays CSS-only.

Size rules (checked by eye, not by check-auth-box.mjs): heading 24px; call to action and every other control at least 44px; every line that carries meaning at least 16px at ≤780px (labels, tagline, tabs, footnote, caption, hints, problems, errors). The 14px caption is decorative-adjacent text on desktop but is real, readable text at ≥4.5:1 in both themes.

Accent contrast is signed off in auth-box.json's contrastSignedOff (text 4.5:1, button edge / focus ring 3:1 against --panel). A new product accent must be added there when its card ships.


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: family-ui/AuthRedirectCard.jsx for the redirect variant (§0); Accounts' client/src/components/AuthCard.jsx for the terminal one. 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

27 Aug 2026 — the reference implementation moved, and this table hadn't caught up until now (corrected 25 Sept 2026). Connections and Pets both cut over their main sign-in surface to Amoleo Accounts OIDC sign-in that day (Connections' issue #4; Pets' #330/#331/#332) — per Amoleo-Accounts/docs/Architecture.md's "no dual-auth period," each app's own tabs/fields form is gone, replaced by one "Sign in with Amoleo Accounts" button that redirects to Accounts' own hosted screen. Amoleo-Accounts is now the only repo where this component's actual tabs/fields shape is live — its AuthCard.jsx, already recorded below as adopted via #6, is what a fresh reimplementation should read as the live reference, not Connections'. Connections' AuthScreen.jsx remains the historical origin (§1–4 above was extracted from it, and nothing about the component's design changed — only which repos still render it), but treat that as history, not a current pointer.

Repo Applicable? Adopted? Notes
Amoleo-Connections Yes No — superseded 27 Aug 2026 (this is the redirect variant, §0 — a legitimate shape, adopting the shared redirect card CSS is on Connections' own card) AuthScreen.jsx / Landing.jsx render one redirect button now, no tabs/fields. Was the reference implementation until this date — see auth-box.json's entry for the detail.
Amoleo-Pets Yes No — superseded 27 Aug 2026 AuthCard.jsx likewise reduced to one redirect button (per Pets' own #332 — not independently verified against Pets' checked-out code by whoever last edited this entry). LoginForm.jsx/RegisterForm.jsx reportedly still live behind ClaimPetView.jsx's separate claim flow — an open question for Pets' own owner, not resolved here.
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 — the terminal variant (§0) 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). The only repo where a visitor still fills in tabs/fields to sign in or register — every other app now just redirects here. See auth-box.json's own entry for its two documented departures from the original spec (autofocus scoping, extra ARIA wiring).
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.