Conversation
Aligns the embed styling with the main LI website (cream background, blue accent, dark navy text) and tackles the layout issues called out in review: - Inputs and selects share padding, border-radius, and a common focus ring; selects get a custom chevron and uniform width so they no longer look like raw OS controls. - Form labels are right-aligned in their column so they sit flush against the inputs; body is centred with a sensible max width so alerts no longer feel detached on wide iframes. - Date-of-birth and test-date fields each sit in a soft info card; the card escalates to an error tone when an inline message is injected (e.g. "Must be after date of birth"), so the message visually belongs to the field it relates to. - Range warnings/errors render attached to the input above (no border between them) so it's obvious which field they describe. - Unit selects are removed from tab order (`tabindex="-1"`), giving consistent keyboard navigation regardless of whether a row has alternative units. Mouse and assistive-tech access is unchanged. - New terminal-style status panel collects non-field events (CSV loaded, defaults filled, calculation complete, awaiting input, configuration errors). Field-specific errors stay inline only — no more duplicate "Error: Test date must be after date of birth" alongside the inline message. https://claude.ai/code/session_019k6FFmsULqWJPK5F5uifZW
- Drop the traffic-light dots from the terminal header — too elaborate;
the "Status" label is enough.
- Status panel now shows a single, current-state line rather than
accumulating a log. "Ready", "awaiting values" and "complete" no
longer coexist.
- Fix `t()` returning the key when a string value is the empty string
(so "{1}" plural suffixes resolve correctly — previously rendered
as e.g. "field defaults_filled_singular").
- Reroute defaults warnings: 1 or "few" defaults surface in the
status panel as a heads-up; "very" approximates use a yellow result
banner; "extreme"/"all" are red. The previous styling had base/severe
inverted, so a single default was rendered red and most defaults
yellow.
- Strengthen the biomarker label selector so right-alignment actually
applies (was being missed because of an over-specific tbody chain).
- Widen the unit selector cell so longer units (mmol/L, µkat/L) fit
without bulging out of the form.
- Show the calculated age at the test date next to the test-date
field, so users can sanity-check the dates without scrolling down.
https://claude.ai/code/session_019k6FFmsULqWJPK5F5uifZW
- CSS: rewrite for clarity. One generic button selector covers all
calculator buttons (was four near-identical declarations); dead
rules dropped (errorNaN, .bioageform .result, the inverted
result-warning-severe etc.); colour vars used everywhere; biomarker
labels are bold again. Disabled unit selects now keep their box
shape (faded text, no chevron) so the unit column reads as a
consistent grid even when the unit can't be changed.
- Default-flagged values now serialise as the AUTO_TOKEN string
("auto") in URL anchors, CSVs, and localStorage, rather than
storing the rounded computed value. On load they're re-imputed
from the user's current age, so a saved link still uses sensible
defaults if the imputation method changes (and it doesn't
masquerade as user-entered data when inspected). Legacy formats
("isDefault: true" in localStorage; " (population default)" suffix
in old CSVs) still load.
- Status terminal now reflects current state across multiple lines:
"Calculation complete" plus the defaults-count notice plus the
implausible-values warning all stack together. Cleared and rebuilt
on every calculateResult call so superseded states never linger.
The standalone result-warning HTML banners are gone.
- Storage-restored notice (with "Clear saved data" link) groups with
the "Load from CSV" button on the right of the date section, so
it doesn't sit alone at the bottom of the form.
- Result summary text moved above the share image — was previously
unmoored at the bottom of the share section.
- Move hardcoded "Warning: " prefix from JS into en.json.
https://claude.ai/code/session_019k6FFmsULqWJPK5F5uifZW
- Auto-filled biomarker inputs now share the same friendly-blue tint as the date-of-birth prompt (italic info-bg/text), so they read visually as "we filled this in for you" rather than as a real entry. - "Fill missing values..." button changes to a faded blue when defaults are present and reports how many are filled (e.g. "1 value filled with a population average" / "9 values filled with population averages"). Reverts to the original CTA if the user types over every default. - Drop legacy compat for the pre-public formats: the `isDefault` hint in old localStorage and the " (population default)" suffix in old CSVs. AUTO_TOKEN is the only serialised flag. https://claude.ai/code/session_019k6FFmsULqWJPK5F5uifZW
- input.default-value now beats the input[type] selectors on specificity, so auto-filled biomarker rows actually get the friendly-blue tint and italics. - Disabled unit selects keep normal text colour and background; only the chevron and pointer are removed. Faded text was making it look like something was broken. - Range alerts are self-contained banners with all four borders and the standard radius, separated from the input above by a small gap. The "attached to input" trick relied on hidden bottom-border math that the user (rightly) read as a bug. - fillAutoValues now also calls updateDefaultsButton at its tail, so the "Fill missing values" button reliably reflects the count of defaults regardless of which entry path triggered the fill. https://claude.ai/code/session_019k6FFmsULqWJPK5F5uifZW
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7066ad4e6a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Biomarker value. | ||
| var input = document.getElementById(field); | ||
| if (input && cleanValue) { | ||
| input.value = cleanValue; | ||
| input.classList.remove('default-value'); | ||
| if (input && value) { | ||
| if (isAutoValue(value)) { | ||
| input.value = ''; | ||
| input.classList.remove('default-value'); | ||
| input.classList.add('pending-auto'); | ||
| } else { | ||
| input.value = value; | ||
| input.classList.remove('default-value'); |
There was a problem hiding this comment.
Preserve legacy CSV default-value suffix on import
CSV uploads no longer strip the legacy " (population default)" suffix from biomarker values before assigning them to numeric inputs. Any CSV exported by previous versions will now load values like "4.2 (population default)" verbatim, which then fail Number(...) parsing and trigger invalid-value errors instead of restoring data. Please normalize this old format during import so previously downloaded CSV files remain usable.
Useful? React with 👍 / 👎.
Summary
This PR redesigns the calculator's user interface with a comprehensive visual refresh, introducing a terminal-style status panel for messages, improving form styling, and refactoring how status information is communicated to users.
Key Changes
Visual Design & Theming
--calc-radiustoken (4px) for consistent border-radius across componentsStatus Communication
status-terminal) that displays all non-field-specific messages in one placeclearStatus(),addStatus(), andsetStatusHeading()functions to manage terminal outputForm & Input Improvements
date-toolsrow on the right side--calc-input-border-error,--calc-input-border-warn)Default Values Handling
AUTO_TOKEN('auto') to mark population-default values in serialized forms (URL, CSV, localStorage)isAutoValue()helper to detect auto-filled valuesCode Organization
#phenoAgeForm button,#shareSection button,#saveSection button)incheck instead of||to preserve empty valuesBug Fixes & Details
pending-autoclassNotable Implementation Details
calculateResult()call, ensuring it reflects current state rather than accumulating historyhttps://claude.ai/code/session_019k6FFmsULqWJPK5F5uifZW