Skip to content

fix(ui): keep the theme toggle and the way back in guest mode - #345

Merged
argszero merged 1 commit into
mainfrom
fix/guest-mode-keeps-theme-toggle
Oct 8, 2026
Merged

argszero merged 1 commit into
mainfrom
fix/guest-mode-keeps-theme-toggle

Conversation

@argszero

@argszero argszero commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Summary

In guest mode the sidebar hid both of the things it must keep: the theme
toggle (hidden as a side effect) and the only control that leads back to the
login view. setGuestSidebar's own comment claimed the theme toggle stayed
usable, and that claim had never been checked against the markup.

Two faces, one hide set:

  1. #theme-toggle is a descendant of .user-chip. The sidebar rework moved
    the toggle into the user chip, and .hidden is display: none !important,
    so hiding the chip hid the toggle with it. The theme toggle is a device
    preference
    , not account identity.
  2. #logout-btn is the app's only control wired to exitGuest(). A visitor
    never reaches the 401 path, so hiding that button removed the guest's only way
    back to the login view: the marketplace answers "sign in to use this model",
    and there is nowhere to sign in from. The guest then makes zero further
    requests for the rest of the session.

Measured on the unfixed tree with an out-of-repo jsdom probe: of the 16 reachable
controls in the guest shell, none returns to the login view.

Related Issue

None — found while auditing the identity-boundary family of the sidebar.

Changes

  • ui/js/app.js — setGuestSidebar(on) now addresses the account-identity
    children only (.user-chip .avatar, .user-chip .chip-text). The theme toggle
    and the logout button stay reachable. Comment corrected and expanded; the
    previous wording stated the opposite of what the code did.
  • ui/css/style.css — .user-chip > .theme-toggle { margin-left: auto; } so the
    lone toggle does not hug the sidebar edge once the chip text is concealed.
    (No effect while .chip-text — flex: 1 — is present.)
  • ui/index.html — cache-bust tokens for the two changed assets.
  • ui/README.md — the guest-mode contract now states that only account identity
    is concealed, with the scope of the static gate spelled out.
  • src/state_gate.rs — the_guest_shell_keeps_the_toggle_and_the_way_back plus
    the_c2182_guest_shell_extractors_have_teeth.

The gate pins the shape, not the pixels: it parses the real sidebar markup
(tag pairing gives parent/child), reads the concealment selectors out of
setGuestSidebar's body, and asserts four things — no interactive element inside
.user-chip is reached by those selectors; the exit control (found by looking for
exitGuest( call sites, skipping the definition) is not reached either; every
account-identity child is reached; and both the enter and exit paths call the
function. Rosters are derived from ui/index.html / ui/js/app.js, with no
exception list; the positive control pins today's three rosters so a silently
narrowed derivation cannot pass vacuously.

Tests

  • cargo test — 482 passed, 0 failed (baseline 480; +2)
  • cargo fmt --check — clean
  • cargo clippy --all-targets -- -D warnings — clean
  • New unit tests added

Out-of-repo verification (jsdom 30.1.0, no JS runner in CI): 5 trees x 7 legs,
all as declared. The unfixed tree reproduces the defect (toggle unreachable,
logout unreachable, no control returns to the login view); the fixed tree passes
all four axis legs; and three competing fixes are each rejected by exactly the
leg they break — deleting the concealment (identity leaks), hiding the chip only
(toggle still swallowed), and moving the toggle out of the chip while keeping the
old hide set (visitor stranded).

Checklist

  • Branch name follows the convention (fix/)
  • Commit message uses Conventional Commits
  • One change, minimal diff

`setGuestSidebar(on)` hid `.user-chip` and `#logout-btn` when a guest
entered the app.  Its own comment claimed the opposite -- that the theme
toggle stayed usable -- and that claim had never been checked.

Two faces, both from the same hide set:

1. `#theme-toggle` is a DESCENDANT of `.user-chip` (the sidebar rework
   moved it there), and `.hidden` is `display: none !important`, so
   hiding the chip hid the toggle with it.  The theme toggle is a device
   preference, not account identity.
2. `#logout-btn` is the app's ONLY control wired to `exitGuest()`.  A
   guest never reaches the 401 path, so hiding that button removed the
   visitor's only way back to the login view: the market tells them
   "sign in to use this", and there is nowhere to sign in from.

Fix: `setGuestSidebar` now addresses the account-identity children only
(`.user-chip .avatar` and `.user-chip .chip-text`); the toggle and the
logout button stay reachable.  A `.user-chip > .theme-toggle` rule pushes
the lone toggle to the right edge once the chip text is concealed.

Shape is pinned by `state_gate::the_guest_shell_keeps_the_toggle_and_the_way_back`;
the rosters (survivors, account identity, exit handles) are all derived
from `ui/index.html` and `ui/js/app.js`, with no exception list.
@argszero
argszero merged commit c27d6c7 into main Oct 8, 2026
2 checks passed
@argszero
argszero deleted the fix/guest-mode-keeps-theme-toggle branch October 8, 2026 20:47
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