Style Guide

Live reference for every UI component used across this site. Each section shows a rendered example followed by the canonical HTML pattern. For rules and validation guidance, see CODE-BIBLE.md in the repository root.

Callouts

Use callouts to surface important information inline. Choose the variant that matches the intent. Do not pick one purely for colour.

Info: supplementary context, prerequisites, neutral notes

This is an info callout. Use it for supplementary context, prerequisites, or neutral notes.

<div class="callout callout-info">
  <div class="callout-icon">
    <svg class="drm-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
      <path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
    </svg>
  </div>
  <div class="callout-body"><p>Message text here.</p></div>
</div>

Warning: potential data loss, configuration pitfalls, version restrictions

This is a warning callout. Use it for potential data loss, configuration pitfalls, or version restrictions.

<div class="callout callout-warning">
  <div class="callout-icon"><svg class="drm-icon" ... /></div>
  <div class="callout-body"><p>Warning message here.</p></div>
</div>

Error: security risk, unsupported action, known breakage

This is an error callout. Use it for security risks, unsupported actions, or known breakage.

<div class="callout callout-error">
  <div class="callout-icon"><svg class="drm-icon" ... /></div>
  <div class="callout-body"><p>Error/danger message here.</p></div>
</div>

Tip: best practice, shortcut, recommended approach

This is a tip callout. Use it for best practices, shortcuts, or recommended approaches.

<div class="callout callout-tip">
  <div class="callout-icon"><svg class="drm-icon" ... /></div>
  <div class="callout-body"><p>Tip text here.</p></div>
</div>

Note: important detail the reader must be aware of

This is a note callout. Use it for important details the reader must be aware of.

<div class="callout callout-note">
  <div class="callout-icon"><svg class="drm-icon" ... /></div>
  <div class="callout-body"><p>Note text here.</p></div>
</div>

All SVGs must use class="drm-icon", stroke-width="2", and aria-hidden="true". Do not use stroke-width="1.5" or data-slot="icon".


Cards

Four card variants serve different purposes. Do not mix them or use one in place of another.

Link card: navigates to another page (card card--interactive)

<div class="drm-cards" style="--cols:2">
  <a class="card card--interactive" href="/docs/section/page/">
    <div class="card-head">
      <div class="card-icon"><svg class="drm-icon" ...>...</svg></div>
      <span class="card-title">Card Title</span>
    </div>
    <p class="card-subtitle">Short description.</p>
    <svg class="card-arrow" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
      <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"/>
    </svg>
  </a>
</div>

Use --cols:2 or --cols:3 on .drm-cards to control column count. Always use an <a> tag for link cards, not a <div>.

Static info card: non-navigating callout panel (card card--accent)

Info Panel

Use this variant to surface a key fact or context note. It is not clickable and does not navigate anywhere.

Another Panel

A second static card. No arrow, no hover lift. Purely informational.

<div class="drm-cards" style="--cols:2">
  <div class="card card--accent">
    <div class="card-head">
      <div class="card-icon"><svg class="drm-icon" ...>...</svg></div>
      <span class="card-title">Info Panel</span>
    </div>
    <p class="card-subtitle">Context or fact to surface.</p>
  </div>
</div>

Use a <div>, not an <a>. No card-arrow. No href. Purple fill is intentional: only use for static information, not for navigation.

Step card: clickable card that switches a tab (used on Get Started)

1. Step One

This card is currently selected: it carries the step-active class.

2. Step Two

This card is unselected. Clicking it removes step-active from siblings and adds it here.

3. Step Three

A third step card. The group uses a hidden tab-nav below to drive the tab panels.

<style>.step-card.step-active{background:var(--card-active-bg,#ede9fe);border-color:var(--color-accent,#7c3aed)}</style>
<div class="drm-cards" style="--cols:3">
  <div class="card card--interactive step-card step-active" style="cursor:pointer"
    onclick="document.querySelectorAll('.step-card').forEach(c=>c.classList.remove('step-active'));
             this.classList.add('step-active');
             document.querySelectorAll('.tab-btn')[0].click()">
    <div class="card-head">...</div>
    <p class="card-subtitle">...</p>
    <svg class="card-arrow" ...>...</svg>
  </div>
</div>

Pair step cards with a .tab-nav (see Tabs section). The first card carries step-active by default. The onclick index on querySelectorAll('.tab-btn')[N] is 0-based: card 1 clicks [0], card 2 clicks [1], and so on.

Tagged card: external resource with a View or Download badge (card card--interactive has-tag)

<div class="drm-cards" style="--cols:2">
  <a class="card card--interactive has-tag" href="https://example.com" target="_blank" rel="noopener">
    <span class="card-tag">View</span>
    <div class="card-head">
      <div class="card-icon"><svg class="drm-icon" ...>...</svg></div>
      <span class="card-title">Resource Title</span>
    </div>
    <p class="card-subtitle">Short description of the resource.</p>
  </a>
</div>

Use has-tag for external links to videos, reports, or downloadable files. The card-tag span replaces the card-arrow used on standard link cards: do not include both. Always use target="_blank" rel="noopener" since these cards point off-site. Use View for web pages and videos, Download for files (PDFs, spreadsheets, installers).


Tabs

Two tab variants exist: standard folder tabs for content switching, and card-nav tabs for organisation-type selectors. Do not substitute one for the other.

Standard tabs: first tab active by default

First tab

Content for the first tab.

Second tab

Content for the second tab.

Third tab

Content for the third tab.

<div class="drm-tabs">
  <div class="tab-nav" data-pagefind-ignore>
    <button class="tab-btn active" data-tab="0">First tab</button>
    <button class="tab-btn" data-tab="1">Second tab</button>
  </div>
  <div class="tab-panels">
    <div class="tab-panel active" data-tab="0">
      <h3 id="first-tab">First tab<a class="hanchor" data-pagefind-ignore href="#first-tab">&para;</a></h3>
      <!-- content -->
    </div>
    <div class="tab-panel" data-tab="1">
      <h3 id="second-tab">Second tab<a class="hanchor" data-pagefind-ignore href="#second-tab">&para;</a></h3>
      <!-- content -->
    </div>
  </div>
</div>

The first tab button and panel always carry active. No hidden default button or blank default panel. data-tab values must match between buttons and panels. Tab switching is handled by app.js: no inline onclick needed.

Search requirement: Every tab panel must begin with an <h3> (or <h2> for top-level sections) with a unique id matching the tab label. This is required for search results to link directly to the correct tab. See the Headings section for the correct hanchor pattern.

Card-nav tabs: organisation-type selector (request-licence pages)

Altra & Microsoft Partners

Content for Altra & Microsoft Partners.

End Clients

Content for End Clients.

<div class="drm-tabs">
  <div class="tab-nav card-nav" data-pagefind-ignore>
    <button class="tab-btn active" data-tab="0">
      <div class="card-head">
        <div class="card-icon"><svg class="drm-icon" ...>...</svg></div>
        <span class="card-title">Organisation Type</span>
      </div>
      <p class="card-subtitle">Short description.</p>
      <svg class="card-arrow" ...>...</svg>
    </button>
    <button class="tab-btn" data-tab="1">...</button>
  </div>
  <div class="tab-panels">
    <div class="tab-panel active" data-tab="0">
      <h2 id="organisation-type-slug">Organisation Type<a class="hanchor" data-pagefind-ignore href="#organisation-type-slug">&para;</a></h2>
      <!-- content -->
    </div>
    <div class="tab-panel" data-tab="1">
      <h2 id="second-type-slug">Second Type<a class="hanchor" data-pagefind-ignore href="#second-type-slug">&para;</a></h2>
      <!-- content -->
    </div>
  </div>
</div>

Only used on request-licence pages for org-type selection. First card button and panel carry active. Every panel must begin with an <h2> with a unique id and hanchor, required for search to surface and deep-link into the correct panel.


Tables

Always wrap tables for horizontal scroll on narrow viewports.

FeatureSaaS (Cloud)Marketplace
Hosted byAltraYour Azure tenant
Infrastructure managed byAltraYou
Setup timeMinutesHours
<div class="table-wrap">
  <table>
    <thead>
      <tr><th>Column A</th><th>Column B</th></tr>
    </thead>
    <tbody>
      <tr><td>Value 1</td><td>Value 2</td></tr>
    </tbody>
  </table>
</div>

Always wrap in <div class="table-wrap">. Always include <thead> with <th> cells. Do not add a class to <table>.


Numbered steps

Use for sequential procedures with headings or multi-paragraph content. Use a plain <ol> only for short numbered lists with no sub-headings.

Open the application

Navigate to the application and sign in with your Altra credentials.

Configure the settings

Open the Settings panel and select your preferred data collection method.

Run the scan

Click Run Scan to begin collecting environment data.

<div class="steps">
  <div class="step">
    <h3 id="step-slug-one">Step Label<a class="hanchor" data-pagefind-ignore href="#step-slug-one">&para;</a></h3>
    <p>Step description and body content.</p>
  </div>
  <div class="step">
    <h3 id="step-slug-two">Another Step<a class="hanchor" data-pagefind-ignore href="#step-slug-two">&para;</a></h3>
    <p>Content.</p>
  </div>
</div>

Each .step must contain an <h3> with an id and hanchor link. Do not nest .steps inside .steps.


Unverified steps

Use this pattern when procedure steps have not been validated against the actual product UI, for example placeholder steps for a scan mode nobody on the team has run yet. The amber outline flags the block during code review; the red callout is what surfaces the issue to anyone reading the page normally. Both elements are required together.

Unverified steps: callout-error above, amber outline on .steps

Needs validation: action required before publishing
The steps below are a placeholder structure and have not been verified against the actual UI. Before this page goes to production, someone must confirm or correct:

  • The exact button or mode name to select
  • Whether there is a licence key step at the start
  • The exact fields shown on the credentials screen

Select the scan mode

Launch the application and select the relevant scan mode from the main screen.

Enter credentials

Provide the required credentials. The application will validate connectivity before proceeding.

Run the scan and export results

Start the scan. When complete, export the results file.

<!-- 1. Red callout ABOVE the steps block — list every specific thing that needs verifying -->
<div class="callout callout-error">
  <div class="callout-icon"><svg class="drm-icon" ...>...</svg></div>
  <div class="callout-body">
    <p><strong>Needs validation — action required before publishing</strong><br>
    The steps below are a placeholder. Before this page goes to production, confirm:</p>
    <ul>
      <li>The exact button / mode name to select in the UI</li>
      <li>Whether there is a licence key step at the start</li>
      <li>The exact fields on the credentials screen</li>
    </ul>
  </div>
</div>

<!-- 2. Steps block with amber outline -->
<div class="steps" style="outline: 3px solid #f59e0b; outline-offset: 4px; border-radius: .7rem;">
  <div class="step">
    <h3 id="step-slug">Step label<a class="hanchor" data-pagefind-ignore href="#step-slug">&para;</a></h3>
    <p>Placeholder step content.</p>
  </div>
</div>

Do not use callout-error for any other purpose on docs pages: a reader seeing red in production will assume something is broken, not that the page is a draft.

When steps are validated: remove the style attribute from .steps and delete the callout-error block. Replace placeholder text with confirmed UI labels.


Code

Inline code

Run python -m http.server 8000 from the docs/ directory to start the local server.

Run <code>python -m http.server 8000</code> from the <code>docs/</code> directory.

Never use backticks in HTML source. Do not add classes to inline <code>.

Multi-line code block

python -m http.server 8000
# Visit http://localhost:8000
<div class="codehilite"><pre><span></span><code>your code here
</code></pre></div>

The empty <span></span> before <code> is required. Do not use bare <pre><code> without the .codehilite wrapper.


Headings

Section heading (h2)

Sub-section heading (h3)

<h2 id="section-slug">Section Heading<a class="hanchor" data-pagefind-ignore href="#section-slug">&para;</a></h2>

<h3 id="sub-section-slug">Sub-section<a class="hanchor" data-pagefind-ignore href="#sub-section-slug">&para;</a></h3>

Slug = lowercase, hyphens only, derived from heading text. Heading text must be plain text: no inline wrappers inside <h2> or <h3>. <h4> and below do not need id or hanchor unless linked from the TOC.


<!-- Internal -->
<a href="/docs/section/page/">Page Title</a>

<!-- External -->
<a href="https://example.com" target="_blank" rel="noopener">External Site ↗</a>

Internal links always use root-relative paths starting with /. External links always include target="_blank" rel="noopener" and the suffix. Do not append to internal links.


Lists

Unordered

  • VMware vSphere environments
  • Hyper-V clusters
  • Nutanix AHV
  • Physical servers
<ul>
  <li>Item one</li>
  <li>Item two</li>
</ul>

Ordered (short, no headings)

  1. Download the DMC installer.
  2. Run the installer as administrator.
  3. Follow the on-screen prompts.
<ol>
  <li>First step.</li>
  <li>Second step.</li>
</ol>

Use .steps > .step for numbered procedures that have headings or multi-paragraph content. Use <ol> only for short inline lists.

© 2025 Altra Technologies