fix: give the token gate some CSS, since it shipped with none - #16
Conversation
The v2 auth prompt is the first thing a new install shows anyone, and neither .hw-auth-prompt nor .hw-auth-status has a single rule anywhere in the stylesheets. The gate rendered as raw flow content underneath the sidebar: a bare heading, an unstyled password box and a default browser button, half of it clipped off the left edge of the viewport. We locked the agent down in v2 and left the front door looking broken. It is a gate, not a panel, so it is now a fixed overlay that covers the app, centred on a card. The [hidden] override is load-bearing: display:flex beats the attribute's UA display:none, so without it the gate would cover the app permanently and never close. The button is outlined rather than filled, and that is measured, not taste. A filled accent button is 3.32:1 in the light theme, under the 4.5:1 AA floor. --hw-accent-primary-dim is worse still, because neither alternate theme redefines it and both silently inherit the base theme's dark olive. Body text on the card measures 14.94 / 13.82 / 14.50 across default, light and terminal, so the accent carries emphasis as a border where its contrast does not matter. The card background needs a var() fallback for the same class of reason: --hw-bg-card exists only in the two alternate themes. Also stops the sidebar lying about the version. It was hard-coded to v1.0.0 in index.html and nothing ever updated it, so a v2.0.2 agent advertised v1.0.0. It now reads /api/v1/health, which is public and so resolves on the token screen too, and says nothing at all when the agent cannot be reached rather than naming a version it never got an answer from. 241 passed, 5 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 35a343a291
ℹ️ 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".
| default browser button, rendered in page flow underneath the sidebar and | ||
| clipped off the viewport. It is a gate, not a panel, so it covers the app | ||
| instead of sitting inside it. */ | ||
| .hw-auth-prompt { |
There was a problem hiding this comment.
Bump the cache keys for the changed frontend assets
On upgrades where a browser has cached /css/components.css?v=1.0.0 or /js/app.js?v=1.0.0, this commit keeps those same URLs in static/index.html, so the browser can reuse the previous files. That leaves the token gate unstyled—the regression this patch is intended to fix—and can leave the newly emptied version label blank because the cached app script lacks showAgentVersion; change the query versions for both modified assets.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Both changed assets now load as ?v=2.0.3 and the pinned components.css digest is updated. Fixed in b2c10c3.
| .hw-auth-prompt { | ||
| position: fixed; | ||
| inset: 0; | ||
| z-index: 100; |
There was a problem hiding this comment.
Raise the gate above the mobile navigation
At viewport widths of 768px or less, .hw-mobile-nav is displayed with z-index: 100 and appears after the auth prompt in the DOM. Giving the prompt the same stacking level causes that navigation bar to paint above the supposedly full-screen gate, so signed-out mobile users can see and interact with underlying navigation; use a higher stacking level for the gate.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The gate moved to z-index 200, above the sidebar and mobile nav layers at 100. Verified in the running app at 375px: a hit-test at the mobile nav's center resolves to the gate in all three themes. Fixed in b2c10c3.
Both changed assets get new cache keys so upgraded installs load the styled gate instead of a stale cached copy, and the gate moves to its own stacking level above the sidebar and mobile nav layers at 100. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b2c10c3f58
ℹ️ 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".
| position: fixed; | ||
| inset: 0; |
There was a problem hiding this comment.
Prevent focus from escaping behind the token gate
When a signed-out keyboard user tabs past the token input and Retry button, focus proceeds to the sidebar or mobile navigation even though this fixed overlay visually covers those controls. The user is then operating concealed links, and activating one can invoke the already-bound hash router while authentication is still pending; make the rest of the app inert or trap focus within the prompt until it closes.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The gate's siblings (sidebar, content, mobile nav) now go inert while the prompt is visible and recover on close, and auth.js gets a new cache key. Verified in the running app: a simulated tab walk from the token input cycles only between the input and Retry. Fixed in HEAD.
Tab order ignores paint order, so the covered sidebar, content, and mobile nav go inert while the gate is visible and recover when it closes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c2a82f218b
ℹ️ 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".
| var siblings = prompt.parentElement ? prompt.parentElement.children : []; | ||
| for (var i = 0; i < siblings.length; i++) { | ||
| if (siblings[i] !== prompt) siblings[i].inert = visible; | ||
| } |
There was a problem hiding this comment.
Release the gate after a rate-limit retry succeeds
When the startup probe hits the authentication-failure 429 limit, handleRateLimited shows this prompt and schedules _authenticateThenStart; if the later probe succeeds, _startProtectedDashboard runs without ever calling _setPromptVisible(false). These new inert assignments therefore leave the sidebar, content, and mobile navigation inaccessible behind the full-screen gate even though authentication succeeded, with a page reload as the only recovery; clear the prompt and inert state on the successful retry path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
_startProtectedDashboard now runs HumWatch.auth.closePrompt(), which hides the gate, clears the inert siblings, and cancels any pending retry. Verified live: handleRateLimited then a successful start leaves the gate hidden and all three siblings interactive. Fixed in HEAD.
| .hw-auth-prompt #auth-error { | ||
| margin: 0; | ||
| font-size: var(--hw-font-size-sm); | ||
| color: var(--hw-status-critical); |
There was a problem hiding this comment.
Use a readable light-theme error color
In the light theme, this renders the 0.8rem authentication error as #ef4444 on the form's white background, which has only about 3.76:1 contrast instead of the 4.5:1 required for small text. The affected text includes the rate-limit notice and token-entry errors users need to recover, so use a darker light-theme critical foreground here.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The gate error now uses --hw-auth-error with the status red as fallback, and the light theme sets it to a darker red measuring 6.47:1 on the white form. Theme stylesheets also gained cache keys so upgraded installs actually load the change. Fixed in HEAD.
… errors The successful probe after a 429 now closes the prompt and clears the inert siblings through one closePrompt path, the light theme gets a darker error red for small text on the white form (6.5:1), and the theme stylesheets pick up cache keys so upgraded installs load them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e857541e13
ℹ️ 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".
| HumWatch.auth.closePrompt = function() { | ||
| HumWatch.auth._promptOpen = false; | ||
| HumWatch.auth._cancelRetry(); | ||
| HumWatch.auth._setPromptVisible(false); | ||
| }; |
There was a problem hiding this comment.
Clear the rate-limit error when closing the gate
When an automatic retry succeeds after handleRateLimited, this hides the prompt but leaves #auth-error visible with the old “retrying” message. If the user later logs out or receives another 401, requireToken() reopens the prompt without clearing that error, falsely claiming that a retry is scheduled; reset the error text/hidden state when closing or reopening the prompt.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
_setPromptVisible now resets the error text and hidden state whenever the prompt shows. Both writers (the rate-limit notice and the submit failure) run after that reset, verified live: rate-limit message shows, gate closes on success, and the reopened prompt is clean. Fixed in HEAD.
The retry notice from a rate-limited probe survived into the next logout or 401 prompt, so the gate now clears the error whenever it shows, before either writer runs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a9d8a6351
ℹ️ 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".
| font-size: var(--hw-font-size-xs); | ||
| letter-spacing: 0.08em; | ||
| text-transform: uppercase; | ||
| color: var(--hw-text-tertiary); |
There was a problem hiding this comment.
Increase the token label's contrast
When the authentication gate is shown, this 0.7rem label has insufficient contrast against the form in every theme: approximately 3.34:1 in default, 3.48:1 in light, and 4.46:1 in terminal, all below the 4.5:1 threshold for small text. Because this label identifies the required credential field, use a higher-contrast foreground such as the theme's primary or secondary text color.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The label now uses the secondary text tone, measured live at 6.45:1 default, 7.30:1 light, and 8.73:1 terminal against the form backdrop. Fixed in HEAD.
The tertiary tone missed 4.5:1 in every theme on the one label that names the credential field. Secondary measures 6.5:1 or better in all three. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e0ca6dfe8d
ℹ️ 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".
| font-family: var(--hw-font-display); | ||
| font-size: var(--hw-font-size-lg); | ||
| font-weight: 500; | ||
| color: var(--hw-accent-primary); |
There was a problem hiding this comment.
Darken the light-theme gate heading
In the light theme, this 1.2rem, weight-500 heading renders as #3b82f6 on the form's white background, giving only about 3.68:1 contrast. At roughly 19.2px it does not qualify as large text, so the token gate's primary heading needs the 4.5:1 ratio; override it with a darker light-theme color or use a readable text token.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The heading now reads --hw-auth-heading with the accent as fallback, and the light theme sets a darker blue measured live at 6.70:1 on the white form. Fixed in HEAD.
| font-size: var(--hw-font-size-xs); | ||
| color: var(--hw-text-tertiary); |
There was a problem hiding this comment.
Increase the authentication status contrast
The 0.7rem authentication state uses the tertiary tone, which is only about 3.34:1 on the default sidebar and 2.82:1 on the light-theme sidebar; the logout label repeats the same failing color below. These are meaningful status and action labels, so use the secondary/sidebar text tone or another color that reaches 4.5:1 in every theme.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Status and logout both moved to the secondary tone: measured 6.45:1 default, 5.91:1 light, 9.13:1 terminal on their sidebar backdrops. Fixed in HEAD.
The light theme overrides the gate heading to a darker blue (6.7:1 on the form), and the sidebar auth status and logout labels move from the tertiary to the secondary tone, reaching 5.9:1 or better everywhere. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 82238bab73
ℹ️ 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".
| font-size: var(--hw-font-size-md); | ||
| padding: var(--hw-space-sm) var(--hw-space-md); | ||
| background: var(--hw-bg-primary); | ||
| border: 1px solid var(--hw-border-color); |
There was a problem hiding this comment.
Give the token input a visible boundary
When the authentication gate is shown and the field is not focused, the custom border does not reach the 3:1 non-text contrast needed to identify an interactive control in any theme: it is roughly 1.39:1 in default, 1.39:1 in light, and 1.66:1 in terminal against the input background, while the input fill is also nearly indistinguishable from the surrounding card. Because this is the only field through which signed-out users can recover access, use a higher-contrast border or a clearly contrasting fill for its resting state.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The resting border now uses --hw-auth-input-border with the secondary text tone as fallback: measured 6.84:1 default, 4.36:1 light (dedicated override), 9.68:1 terminal against the input fill. Fixed in HEAD.
The stock border tone sat under 1.7:1 on the input fill in every theme. The secondary text tone carries it to 6.8:1 default and 9.7:1 terminal, and the light theme overrides to a mid gray at 4.4:1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
From a screenshot of a real v2.0.2 install. This is what every new user currently sees first.
The gap
Neither
.hw-auth-promptnor.hw-auth-statushas a single rule anywhere in the stylesheets.So the gate renders as raw flow content underneath the sidebar: a bare heading, an unstyled password box, a default browser button, and the whole thing clipped off the left edge of the viewport. The heading reads
equiredbecause the rest is off-screen.We locked the agent down in v2 and left the front door looking broken. It is the first screen of every install, and it looks like a rendering failure rather than a security control.
The fix
It is a gate, not a panel, so it is a fixed overlay covering the app, centred on a card, styled entirely through existing
--hw-*tokens so all three themes follow.The
[hidden]override is load-bearing.display: flexbeats the attribute's UAdisplay: none, so without an explicit.hw-auth-prompt[hidden] { display: none }the gate would cover the app permanently and never close after a successful login. Verified in a browser:The button is outlined, and that is measured rather than taste
My first attempt was a filled accent button. It fails:
--hw-accent-primary-dim(what.hw-btn-primaryuses) is worse, because neither alternate theme redefines it and both silently inherit the base theme's dark olive.Body text on the card is the pairing every theme has to keep readable:
So the accent carries emphasis as a border, where its contrast against text does not matter. The card background needs
var(--hw-bg-card, var(--hw-bg-secondary))for the same class of reason:--hw-bg-cardexists only in the two alternate themes.Also: the sidebar was lying about the version
index.htmlhard-codedv1.0.0into#app-versionand nothing ever set it, so a v2.0.2 agent advertised v1.0.0. It now reads/api/v1/health, which is public and therefore resolves on the token screen too, and renders nothing at all when the agent is unreachable rather than naming a version it never got an answer from.Notes
static/vendor/SHA256SUMSis re-pinned forcomponents.css. The supply-chain guard caught the change on the first run, which is the system working.241 passed, 5 skipped.Related: this is the screen #15's guide tells people to paste their token into.
🤖 Generated with Claude Code