Skip to content

[Task][Web] Keep header visible and normalize Recovery/Firmware dividers #203

Description

@miso-develop

Parent spec

#137

Owner

  • ACTIVE_ROLE: implementation
  • DOMAIN: web

State

READY_FOR_IMPLEMENTATION

Baseline / current evidence

Specification baseline: main = b3aa8fc0cc06143990dcf32a971853264f73eba8.

Current Web structure was inspected on this baseline.

Global header

All three production pages use:

<header id="site-header"></header>

and ui-localization.ts renders the shared .site-nav-shell containing:

  • M5Authenticator product mark;
  • Provisioner / Firmware Flash / Help tabs;
  • EN / 日本語 language switcher.

Current #site-header CSS has padding only; it is not sticky/fixed.

Provisioning security subsections

web/src/security/security-panel.ts renders Recovery Package and Change Recovery Passphrase as h3 subsections inside one outer section.panel.

The #188 divider contract covers major peer .panel sections, so these two internal security subsections currently have no divider immediately above their headings.

Firmware double divider

web/src/flasher.ts creates outer #flash-status.panel, then inserts firstInstallChoice(...) and updateChoice(...), each of which is also a .panel.

The shared .panel top-border contract therefore produces a duplicated visual divider before the first-install region.

Objective

Refine the shared Web shell and section boundaries so:

  1. the global title/tab header stays visible during vertical scrolling;
  2. the two requested Security & Recovery subsections receive explicit separators;
  3. Firmware First install has exactly one separator, not two.

This is a presentation/layout change only. Do not change provisioning, recovery, flashing, release, Protocol, Vault, credential, or Device semantics.

Scope

1. Sticky global header on all Web pages

The shared header containing the product title and top-level navigation must remain visible at the top of the viewport while the page content scrolls vertically.

Applies to:

  • Provisioner (index.html);
  • Firmware Flash (flash.html);
  • Help / Usage (help.html).

Required behavior:

  • keep the entire existing shared header unit fixed in view, including:
    • M5Authenticator product mark;
    • top-level tab links;
    • language switcher;
  • use normal browser/CSS layout behavior; position: sticky; top: 0 is preferred unless the existing shell requires an equivalent implementation;
  • preserve the current max-width/alignment of .site-nav-shell;
  • preserve responsive behavior, including the existing two-row tab layout on narrower widths;
  • provide an opaque/background treatment so scrolled page content does not visually bleed through the header region;
  • give the header sufficient stacking order to stay above ordinary page content;
  • do not place it above security-critical modal/presence overlays that are intended to cover/intercept the UI;
  • header fixation must not change active-tab semantics, localization, keyboard navigation, or link destinations;
  • scrolling must not introduce horizontal layout shift, header-width jitter, or a new horizontal scrollbar;
  • ordinary page content must remain reachable/readable and must not be permanently hidden behind the fixed header.

Do not duplicate the header per page. Preserve the shared #site-header / navigation renderer contract.

2. Divider above Recovery Package

Within Provisioning's Security & Recovery panel:

  • render exactly one visible horizontal divider immediately before the Recovery Package subsection heading;
  • divider/spacing should use the existing visual language (#e5e5e5-equivalent neutral section boundary unless the shared palette changes);
  • keep the heading as a semantic subsection heading;
  • preserve all Recovery Package export/import behavior and security warnings;
  • do not introduce a nested card solely to obtain the divider.

Prefer a reusable internal-subsection wrapper/class or shared boundary rule over a one-off inline style.

3. Divider above Change Recovery Passphrase

Within the same Security & Recovery panel:

  • render exactly one visible horizontal divider immediately before Change Recovery Passphrase;
  • use the same subsection-boundary treatment as Recovery Package;
  • preserve all current Passphrase-change security semantics, field-clearing behavior, and enable/disable rules;
  • do not create a double divider due to adjacent content.

EN/JA localization must continue to work with the existing heading text.

4. Remove duplicate divider before Firmware First install

On Firmware Flash:

  • the First install — erase device region must have exactly one visible horizontal divider above it;
  • remove/suppress the duplicate caused by nested .panel boundaries;
  • retain a clear visual boundary between the Firmware page introduction/status region and First install;
  • retain a clear single boundary between First install and Update — keep authenticator data;
  • retain the bottom Build information section hierarchy from [Task][Web] Add build-information sections and consistent Provisioning dividers #188;
  • do not alter destructive First install semantics or state-preserving Update semantics.

Implementation may:

  • make #flash-status a structural container rather than a normal peer .panel;
  • suppress only the first nested panel's redundant border;
  • or use another shared CSS/markup approach that guarantees the single-divider invariant.

Do not solve this with fragile selectors tied only to current English text.

Accessibility / responsive requirements

  • Sticky header must remain usable at latest-stable Desktop Chrome widths covered by current production support.
  • At narrow/mobile-like viewport widths used by existing responsive tests, wrapped tabs and language controls remain fully visible and operable.
  • Focus indicators and keyboard tab order remain unchanged/usable.
  • Section dividers are decorative structure only; heading hierarchy remains the semantic navigation mechanism.
  • Do not add empty hr elements that create confusing accessibility semantics when CSS borders on semantic containers can express the same visual boundary.

Regression coverage

Header

Add deterministic DOM/CSS/browser coverage proving:

  • #site-header uses the shared sticky/fixed contract;
  • Provisioner, Firmware, and Help all receive the same fixed header behavior;
  • active tabs/localization still render;
  • scrolling a long page keeps the header visible at viewport top;
  • page content scrolls beneath/after it without horizontal geometry shift;
  • responsive two-row navigation remains usable;
  • security/presence overlays retain their intended stacking priority.

Provisioning dividers

Cover:

Firmware dividers

Cover:

  • exactly one visible boundary before First install;
  • exactly one boundary between First install and Update;
  • Build information remains a single secondary bottom section;
  • async firmware metadata loading does not reintroduce layout shift/double borders.

Prefer semantic/class/state assertions plus production Chrome layout smoke where visual geometry matters. Avoid brittle pixel-color screenshot assertions unless already supported by existing test infrastructure.

Acceptance criteria

  • Shared Web header remains visible while vertically scrolling Provisioner, Firmware, and Help.
  • Product title, top-level tabs, and language switcher all remain inside that fixed/sticky header.
  • Header remains opaque/readable and above ordinary content, but does not supersede security/presence overlays.
  • Desktop and responsive navigation geometry remains usable with no horizontal-scroll/layout-shift regression.
  • Provisioning shows exactly one divider immediately above Recovery Package.
  • Provisioning shows exactly one divider immediately above Change Recovery Passphrase.
  • Recovery Package / Passphrase behavior and security semantics are unchanged.
  • Firmware shows exactly one divider above First install — erase device.
  • Firmware does not render the currently observed double divider before First install.
  • Firmware retains a single clear divider before Update and preserves Build information hierarchy.
  • Existing [Task][Web] Add build-information sections and consistent Provisioning dividers #188 Provisioning major-section divider contract and Factory Reset danger styling remain intact.
  • EN/JA localization remains correct.
  • Vitest/DOM/CSS coverage and production latest-stable Desktop Chrome smoke/layout tests pass.
  • No Device / Protocol / Vault / recovery / flash-write / release semantics change.

Expected implementation surfaces

Likely:

  • web/src/style.css;
  • web/src/ui-localization.ts only if shared-header markup needs a stable class/structure adjustment;
  • web/src/security/security-panel.ts;
  • web/src/flasher.ts;
  • existing Web layout/Chrome smoke tests.

Avoid unrelated Web behavior changes.

Collision / coordination

At Specification time there are no open PRs.

Implementation must still perform a fresh Issue/PR/branch ownership check immediately before claim, especially for:

  • web/src/style.css;
  • shared navigation/header code;
  • security-panel.ts;
  • flasher.ts.

Serialize with any later-active Web Task touching those surfaces.

References

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions