Novus Technologies Novus Technologies design kit v0.9.0
Menu

Navigation

User menu

Header account menu on native details: identity, Profile, theme, and Sign out at its foot.

.userdd · .userdd__trigger · .userdd__menu

ops.admin
Operations Adminops.admin@novustech.com.sg
Profile
Theme
Header account menu (native details, works with JavaScript off)
<div class="appheader" style="justify-content:flex-end;align-items:flex-start;min-height:15rem">
  <div class="appheader__right">
    <span class="appheader__endorse"><span class="brandmark" role="img" aria-label="Novus Technologies"></span></span>
    <span class="appheader__sep"></span>
    <details class="userdd" data-dismiss>
      <summary class="btn btn--ghost btn--sm userdd__trigger"><svg class="icon icon--sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="3.75"/><path d="M4.75 20a7.25 7.25 0 0 1 14.5 0"/></svg><span class="userdd__name truncate">ops.admin</span><svg class="icon icon--sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg></summary>
      <div class="card userdd__menu">
        <div class="userdd__who"><b>Operations Admin</b><span class="muted">ops.admin@novustech.com.sg</span></div>
        <a class="userdd__item" href="settings-layout.html#sl-profile"><svg class="icon icon--sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="3.75"/><path d="M4.75 20a7.25 7.25 0 0 1 14.5 0"/></svg> Profile</a>
        <div class="userdd__row"><span class="muted">Theme</span><button type="button" class="btn btn--ghost btn--sm toggle44 themetoggle" data-theme-toggle aria-label="Toggle light and dark theme"><svg class="icon ic-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 14.5A8 8 0 0 1 9.5 4a8 8 0 1 0 10.5 10.5Z"/></svg><svg class="icon ic-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.3 5.3l1.4 1.4M17.3 17.3l1.4 1.4M18.7 5.3l-1.4 1.4M6.7 17.3l-1.4 1.4"/></svg></button></div>
        <div class="userdd__foot"><a class="btn btn--secondary btn--sm" href="signed-out-page.html"><svg class="icon icon--sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4"/><path d="m15 8 4 4-4 4M19 12H9"/></svg> Sign out</a></div>
      </div>
    </details>
  </div>
</div>

Usage

  • The trigger is a person icon, the user's handle, and a chevron. The handle truncates; below 520px only the icon shows and the name stays available to assistive technology.
  • The panel lists identity first, then Profile as the one destination it offers, then preferences as label and control rows (on consoles the theme toggle lives here), then Sign out alone at the ruled foot. Profile and Sign out both carry a label and an icon, so neither is a row of unlabelled glyphs.
  • Profile lives in the account menu, not the side navigation. The header already carries the person's identity, and a side navigation entry for their own profile would push the console's actual destinations around.
  • Profile goes to the person's own settings, the Profile section of the settings page.
  • Native details opens and closes with JavaScript off; the console layer's script adds Escape and outside-click dismissal for any details[data-dismiss].
  • Sign out goes to the signed-out page.

CSS

These rules ship in the console pattern layer, admin-kits/shared/novus-admin.css, which this site and every Admin Kit flavor load after tokens.css. Copy the whole layer, or only the sections below; every value is a token.

@pattern user-menu
.userdd { position: relative; min-width: 0; }
.userdd__trigger { list-style: none; gap: var(--space-2); min-height: 2.75rem; max-width: 14rem; }
.userdd__trigger::-webkit-details-marker { display: none; }
.userdd[open] > .userdd__trigger { background: var(--accent-subtle); }
.userdd__name { max-width: 10rem; }
.userdd__menu { position: absolute; inset-inline-end: 0; top: calc(100% + var(--space-2)); z-index: 60; min-width: 17rem; padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); box-shadow: var(--shadow-3); font-size: var(--text-sm); line-height: var(--lh-sm); }
.userdd__who { display: flex; flex-direction: column; gap: calc(var(--space-1) / 2); min-width: 0; padding-bottom: var(--space-2); border-bottom: 1px solid var(--border); }
.userdd__who > * { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.userdd__row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.userdd__item { display: flex; align-items: center; gap: var(--space-2); min-height: 2.5rem; margin: 0 calc(var(--space-3) * -1); padding: var(--space-1) var(--space-3); color: var(--text); text-decoration: none; }
.userdd__item:hover { background: var(--bg-subtle); text-decoration: none; }
.userdd__foot { display: flex; justify-content: flex-end; padding-top: var(--space-2); border-top: 1px solid var(--border); }
@media (max-width: 519.98px) {
  .userdd__name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
}