Skip to content

Polish Bahunya around a touch-first native-app visual system - #18

Merged
Kimeiga merged 32 commits into
masterfrom
design/chatgpt-ios-polish
Oct 1, 2026
Merged

Kimeiga merged 32 commits into
masterfrom
design/chatgpt-ios-polish

Conversation

@Kimeiga

@Kimeiga Kimeiga commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Visual system

  • introduce shared spacing, radius, surface, shadow, control-height, and content-width tokens
  • shift the dark palette toward quieter neutral surfaces while preserving Bahunya gold as the accent
  • preserve a coordinated light theme with accessible accent contrast
  • replace the oversized heading scale with responsive clamp() typography and tighter vertical rhythm
  • constrain the first semantic hero image so logos do not dominate mobile screens

Interaction

  • turn primary navigation into a compact sticky glass-like surface with touch-sized links
  • keep navbar markup fully classless and make list-based navigation wrap intentionally instead of using the old brand spacer
  • make buttons and form controls 44px-class touch targets with consistent radii and focus states
  • give submit controls a clear accent treatment while keeping secondary actions neutral
  • add restrained transitions and honor prefers-reduced-motion

Surfaces

  • unify articles, fieldsets, code blocks, tables, details, dialogs, asides, and iframes
  • improve table overflow/readability and dialog/backdrop treatment
  • modernize range controls
  • update print styles for the new surfaces

Project/demo

  • reduce the project-page logo footprint
  • remove leftover CSS classes from the element demo so the demo is genuinely classless
  • extend regression tests to protect the responsive, touch-first, zero-class design contract
  • regenerate committed distribution CSS from source

The design takes the usability principles visible in polished native mobile apps (clear hierarchy, quiet surfaces, consistent geometry, large touch targets, restrained accent use) without copying app-specific chrome or compromising Bahunya's semantic/classless model.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-01T20:01:22.941823Z 379b5ed PR opened
🔒 Security Review ✅ Completed 2026-10-01T19:56:42.229649Z 379b5ed PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Kimeiga
Kimeiga merged commit 14713b9 into master Oct 1, 2026
2 checks passed

@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: 379b5edd53

ℹ️ 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 thread src/parts/_navbar.css
display: none;
position: absolute;
top: 100%;
top: calc(100% + var(--space-2));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep the hover path connected to dropdowns

When a nested menu is opened solely by pointer hover, this offset leaves a 0.5rem gap between the triggering li and its absolutely positioned submenu. Moving the cursor through that gap clears the li:hover state, so the rules below hide the menu before the pointer can reach it; the documented pointer-hover dropdown flow therefore requires the trigger to be focused as a workaround. Keep the boxes contiguous or add a hoverable bridge across the gap.

Useful? React with 👍 / 👎.

Comment thread src/parts/_navbar.css
position: fixed;
top: 0;
left: 0;
position: sticky;

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 stickiness for header-contained navigation

For the documented <body><header><nav>…</nav></header> structure, a sticky element is constrained by the bounds of its containing header. A typical header containing only this nav ends immediately below it, so the navbar scrolls away with the header rather than remaining sticky through the page; only the direct-child-of-body variant retains the intended behavior. The sticky element needs a containing block that spans the document, or this supported structure needs separate positioning.

Useful? React with 👍 / 👎.

Comment thread src/parts/_navbar.css
Comment on lines +123 to +124
right: 0;
left: auto;

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 Avoid right-aligning last dropdowns that are not at the edge

In a list-based navbar with only a brand and one short dropdown, or whenever wrapping leaves the final item away from the right edge, anchoring the 18rem submenu to that narrow item's right side pushes much of it left of the viewport. The earlier brand spacer was removed, so being :last-child no longer guarantees that the item is right-aligned. Clamp the submenu to the viewport or apply right alignment only when its position requires it.

Useful? React with 👍 / 👎.

Comment thread src/parts/_forms.css
input,
textarea,
select {
min-height: var(--control-height);

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 Exclude checkboxes and radios from the global minimum height

Because min-height takes precedence over the later height: 1.15em, every checkbox and radio is forced to be at least 2.75rem tall while remaining only 1.15em wide. This produces a tall, narrow native control and expands each label's line box rather than creating a compact indicator with an appropriate touch target. Limit this minimum height to text-like controls or explicitly reset it for checkbox and radio inputs.

Useful? React with 👍 / 👎.

Comment thread src/parts/_print.css
select,
textarea {
background-color: #fff;
background: #fff;

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 Reset foregrounds when whitening print surfaces

When printing the default dark theme, this rule turns the newly styled surfaces white but the later black-text list omits aside, dialog, and th. Their explicit screen colors therefore remain #c7c7cc or #f4f4f5, yielding only about 1.68:1 or 1.10:1 contrast against the white print background and making their contents or table headings effectively unreadable. Reset the foreground colors of every surface that is whitened here.

Useful? React with 👍 / 👎.

Comment thread src/parts/_forms.css

input:not([type="checkbox"]):not([type="radio"]),
select {
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="color"]),

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 Keep image submit controls content-sized

For forms using <input type="image">, this broad selector still matches because image is not among the excluded button-like types, so the submit image is changed to a block with width: 100%. That stretches an image button across the form instead of preserving its intrinsic dimensions, unlike the explicitly excluded submit, reset, and button inputs. Exclude type="image" from this full-width text-control rule.

Useful? React with 👍 / 👎.

Comment thread src/parts/_variables.css
--button-hover: #324759;
--form-placeholder: #a9a9a9;
--button-hover: #2b2c31;
--form-placeholder: #7d7e85;

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 Increase default placeholder contrast

In the default dark theme, placeholders now render as #7d7e85 on the #17181c input background, a contrast ratio of about 4.39:1. Since form placeholders use normal 1rem text, this falls below the 4.5:1 minimum and is a regression from the previous high-contrast placeholder color. Use a slightly lighter placeholder token so instructions remain legible.

Useful? React with 👍 / 👎.

Comment thread src/parts/_variables.css
--mark-text: #111214;
--text-main: #3a3a3c;
--text-bright: #1c1c1e;
--text-muted: #737378;

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 Increase muted-text contrast in the light theme

With the light theme enabled, #737378 against the #f7f7f8 body background has only about 4.41:1 contrast. This token is used by ordinary small text such as the 0.875rem footer, so it no longer meets the 4.5:1 requirement that the previous light-theme muted color satisfied. Darken the light-theme muted token enough to retain readable secondary text.

Useful? React with 👍 / 👎.

Comment thread src/parts/_buttons.css
box-shadow 140ms ease;
}

input[type="submit"] {

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 Style button-based submit controls as primary actions

A form using the semantic <button type="submit"> element receives only the neutral button surface because the new accent rule targets input[type="submit"] exclusively. The equivalent input submit is gold, so in this classless framework the primary-action hierarchy now depends on which native submit element the author chooses; include explicit submit buttons, and their hover state, in the accent treatment.

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.

1 participant