Design System

Style guide, component reference, and integration docs for the dhanur.me design system

Color Palette

Semantic colors adapt to the current theme. Toggle dark/light to see them change.

primary
secondary
accent
neutral
info
success
warning
error

Base colors

base-100
base-200
base-300

Typography

Heading 1 — text-4xl

Heading 2 — text-3xl

Heading 3 — text-2xl

Heading 4 — text-xl

Heading 5 — text-lg
Heading 6 — text-base

Body text — default paragraph. The quick brown fox jumps over the lazy dog.

Small text — text-sm with 60% opacity.

Inline code: const x = 42;

Buttons

Variants

Sizes

Shapes

States

Cards

Default Card

Card with bg-base-200 background.

Bordered Card

Card with border and no background fill.

Compact Card

Uses card-compact for tighter padding.

Forms

Range

Badges & Alerts

Badges

primarysecondaryaccentinfosuccesswarningerroroutlineghost

Alerts

Tabs

Collapse / Accordion

What tech stack is used?

Zola (static site generator) + Tailwind CSS v4 + DaisyUI v5. No Node.js runtime needed.

How does cross-subdomain theming work?

A cookie scoped to .dhanur.me stores the theme preference. All subdomains read the same cookie.

Do I need to recompile CSS for new classes?

No. The safelist includes all common Tailwind utilities and DaisyUI components. Only unusual arbitrary values need a recompile.

Tooltips

Progress & Loading

Progress bars

Loading indicators

Keyboard

ABCShiftCtrlAlt

Steps

  • Install
  • Configure
  • Build
  • Deploy

Skeleton

Swap

Theme System

The theme uses a cookie-based system scoped to .dhanur.me, so all subdomains share the same dark/light preference.

AttributeDarkLight
data-themenightlofi
data-brightnessdarker (default) / normal / lighternormal (default) / darker / lighter
colorSchemedarklight

Brightness variants

The darker brightness gives pure black (#000000) backgrounds. lighter gives a softer dark mode.

Reading/setting theme in JS

// Read current theme from cookie
var theme = document.cookie.match(/theme=([^;]*)/)?.[1] || "dark";

// Set theme (if on dhanur.me or subdomain)
window.__setThemeCookie("light"); // or "dark"

// Or manually
document.cookie =
  "theme=dark; path=/; domain=.dhanur.me; max-age=31536000; SameSite=Lax";

Integration Guide

Minimal setup (just the script)

<script src="https://dhanur.me/js/shell.js" defer></script>

This auto-injects main.css + font-awesome.min.css, fetches the layout shell, wraps your page content in the drawer, and handles theming.

Script tag attributes

AttributeDefaultDescription
data-base-urlAuto-detectOverride the base URL for fetching layout + CSS
data-no-css(absent)Skip CSS auto-injection if you already include them

SiteNavConfig API

Set window.SiteNavConfig before the script loads to configure navigation, branding, and chrome visibility.

window.SiteNavConfig = {
  // Layout mode
  // "full" (default) = drawer + sidebar + navbar
  // "navbar" = fixed top bar only, no sidebar (for SPAs)
  mode: "full",

  // Navigation - replace nav items in header + sidebar.
  // null = use dhanur.me's nav as-is.
  nav: [
    { name: "Docs", url: "/docs/", icon: "fa-solid fa-book" },
    { name: "API", url: "/api/", icon: "fa-solid fa-code" },
    // Dropdown (header only):
    {
      name: "Links",
      type: "dropdown",
      icon: "fa-solid fa-link",
      members: [
        {
          name: "GitHub",
          url: "https://github.com/...",
          icon: "fa-brands fa-github",
        },
      ],
    },
  ],

  // Separate sidebar nav (optional). If null, uses `nav`.
  sidebarNav: [
    {
      name: "Getting Started",
      url: "/docs/start/",
      icon: "fa-solid fa-rocket",
      children: [
        { name: "Installation", url: "/docs/start/install/" },
        { name: "Quick Start", url: "/docs/start/quickstart/" },
      ],
    },
  ],

  // Highlight current page in sidebar. Default: location.pathname.
  activePath: null,

  // Branding overrides
  logo: {
    href: "/",                         // where logo links to
    html: "<img src='/logo.png' class='h-8'>",  // raw HTML content
  },
  favicon: "/path/to/icon.png",        // override favicon
  badge: {
    text: "BETA",                      // text shown in badge
    class: "badge-warning",            // DaisyUI badge class
  },

  // Chrome visibility
  showSearch: false,      // default: false (subdomains can't use main site search)
  showAppsGrid: true,     // default: true
  showThemeToggle: true,  // default: true
};

Config options

OptionTypeDefaultDescription
mode"full" | "navbar""full"Full drawer layout or navbar-only (for SPAs)
navArrayMain site navHeader navigation items
sidebarNavArrayFalls back to navSidebar items with optional nested children
activePathstringlocation.pathnamePath to highlight as active in sidebar
logo{ href, html }Main site logoOverride logo link and content
faviconstringMain site faviconPath to custom favicon
badge{ text, class }NoneBadge shown next to logo (e.g. "BETA", "DOCS")
showSearchbooleanfalseShow search bar (requires main site search index)
showAppsGridbooleantrueShow the apps grid dropdown
showThemeTogglebooleantrueShow the theme toggle button

Nav item shapes

PropertyTypeDescription
namestringDisplay text
urlstringLink target
iconstring?FontAwesome class, e.g. "fa-solid fa-book"
childrenNavItem[]?Nested items (sidebar only, creates collapsible sections)
type"dropdown"?Header-only dropdown menu
membersNavItem[]?Dropdown items (when type: "dropdown")

Example Configurations

Subdomain with custom nav + badge

<script>
  window.SiteNavConfig = {
    nav: [
      { name: "Dashboard", url: "/", icon: "fa-solid fa-gauge" },
      { name: "Users", url: "/users/", icon: "fa-solid fa-users" },
      { name: "Settings", url: "/settings/", icon: "fa-solid fa-gear" },
    ],
    badge: { text: "ADMIN", class: "badge-error" },
    favicon: "/admin-icon.png",
  };
</script>
<script src="https://dhanur.me/js/shell.js" defer></script>

React SPA (navbar only)

<!-- In public/index.html -->
<script>
  window.SiteNavConfig = {
    mode: "navbar",
    nav: [
      { name: "Home", url: "/", icon: "fa-solid fa-house" },
      { name: "About", url: "/about", icon: "fa-solid fa-user" },
    ],
    logo: { href: "/", html: "<span class='text-lg font-bold'>MyApp</span>" },
    showAppsGrid: false,
  };
</script>
<script src="https://dhanur.me/js/shell.js" defer></script>

Documentation site with nested sidebar

<script>
  window.SiteNavConfig = {
    nav: [
      { name: "Docs", url: "/docs/", icon: "fa-solid fa-book" },
      { name: "API", url: "/api/", icon: "fa-solid fa-code" },
    ],
    sidebarNav: [
      {
        name: "Getting Started",
        url: "/docs/start/",
        icon: "fa-solid fa-rocket",
        children: [
          { name: "Installation", url: "/docs/start/install/" },
          { name: "Quick Start", url: "/docs/start/quickstart/" },
        ],
      },
      {
        name: "Guides",
        url: "/docs/guides/",
        icon: "fa-solid fa-map",
        children: [
          { name: "Authentication", url: "/docs/guides/auth/" },
          { name: "Deployment", url: "/docs/guides/deploy/" },
        ],
      },
    ],
    badge: { text: "DOCS", class: "badge-info" },
  };
</script>
<script src="https://dhanur.me/js/shell.js" defer></script>

No config (uses dhanur.me's nav)

<!-- Simplest possible usage — zero config -->
<script src="https://dhanur.me/js/shell.js" defer></script>

Notes

  • Logo defaults to ~/dhanur linking to dhanur.me — override with logo: { href, html }
  • Favicon defaults to main site — override with favicon: "/path/to/icon.png"
  • Theme cookie is shared across all *.dhanur.me subdomains
  • CSS (compiled Tailwind + DaisyUI) is auto-injected unless data-no-css is set on the script tag
  • Search is off by default on subdomains (needs main site search index)
  • The layout shell is fetched from /navbar/ on the main site — any template changes propagate automatically
  • Font Awesome 6 icons are available via the auto-injected CSS