Skip to content

Redesign UI with terminal-style status panel and improved styling - #10

Open
ajsteele wants to merge 6 commits into
mainfrom
claude/improve-calculator-styling-w2yTa
Open

ajsteele wants to merge 6 commits into
mainfrom
claude/improve-calculator-styling-w2yTa

Conversation

@ajsteele

@ajsteele ajsteele commented May 4, 2026

Copy link
Copy Markdown
Owner

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

  • Updated color palette across light and dark themes with new accent colors (#2e5ea8 for light, #5b9bd5 for dark)
  • Added new semantic color tokens for terminal styling, info states, and input validation
  • Introduced --calc-radius token (4px) for consistent border-radius across components
  • Refined typography with improved line-height (1.5) and letter-spacing on headings

Status Communication

  • New status terminal component: Replaced scattered warning divs with a unified terminal-style panel (status-terminal) that displays all non-field-specific messages in one place
  • Terminal shows calculation status (complete/ok), defaults warnings, implausible value alerts, and awaiting-input prompts with visual indicators (✓, !, ✗)
  • Implemented clearStatus(), addStatus(), and setStatusHeading() functions to manage terminal output
  • Graduated warning levels for defaults (error for ≥2/3 filled, warning for ≥1/3 filled)

Form & Input Improvements

  • Date section redesign: Converted to flex layout with colored info/error cards that wrap inline messages
  • Date rows now visually escalate to error styling when validation fails
  • Added age readout display in test date row
  • Moved CSV upload and storage notice into a date-tools row on the right side
  • Improved select styling with custom SVG chevrons (theme-aware) and disabled state handling
  • Added focus states with accent color and soft shadow for better accessibility
  • Input validation states now use dedicated border colors (--calc-input-border-error, --calc-input-border-warn)

Default Values Handling

  • Introduced AUTO_TOKEN ('auto') to mark population-default values in serialized forms (URL, CSV, localStorage)
  • Added isAutoValue() helper to detect auto-filled values
  • Refactored to preserve default-value styling when loading from storage
  • Default values now display with italic text and info-bg styling to indicate they're system-provided

Code Organization

  • Consolidated button styling under calculator-scoped selectors (#phenoAgeForm button, #shareSection button, #saveSection button)
  • Reorganized CSS with clear section headers (Base, Form controls, Biomarker table, Date section, etc.)
  • Improved comment clarity with explanations for custom select styling and disabled state behavior
  • Fixed translation string lookup to use explicit in check instead of || to preserve empty values

Bug Fixes & Details

  • Date validation errors now stay inline (no duplication in status panel)
  • DOB prompt now parents to the appropriate date row instead of floating separately
  • Removed duplicate error messages from status panel when field-specific errors exist
  • Unit select inputs skip tab order (tabindex="-1") since they're typically mouse-operated
  • Improved localStorage restoration to properly mark auto-filled values with pending-auto class

Notable Implementation Details

  • The status terminal is rebuilt on every calculateResult() call, ensuring it reflects current state rather than accumulating history
  • Date row styling uses transitions for smooth background/border changes
  • Terminal uses monospace font with custom line prefixes (>, ✓, !, ✗) for visual hierarchy
  • Form table uses separate border-spacing for cleaner layout while maintaining alignment

https://claude.ai/code/session_019k6FFmsULqWJPK5F5uifZW

claude and others added 6 commits May 3, 2026 21:47
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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +1668 to +1677
// 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');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants