CR-2026-03-24: adoc Script UI Parity with Domus Antora

Change Summary

Field Value

Change ID

CR-2026-03-24-ADOC-UI-PARITY

Script

~/.local/bin/adoc (dotfiles-optimus)

Current State

Gray badges, double borders, no theme switching, Tridactyl incompatible

Target State

Cyan badges matching domus-antora-ui, single border, theme switcher, Tridactyl compatible

Requestor

Evan Rosado

Implemented

2026-03-24

Risk Level

Low

Context

Personal tooling - MDN AsciiDoc batch conversion requires matching UI

Business Justification

Why This Change?

  1. MDN Conversion Project - Converting 10,872 MDN JavaScript reference pages to AsciiDoc requires consistent, professional HTML output

  2. Brand Consistency - Standalone documents should match docs.domusdigitalis.dev visual identity

  3. Offline Reading - HTML files must be usable without Antora build pipeline

  4. Accessibility - Theme switcher supports user preference (dark/light/catppuccin)

  5. Tridactyl Workflow - Copy buttons must work with keyboard-driven browsing

Visual Issues Identified

Issue Description Status

Double border on code blocks

Both .listingblock .content and pre had cyan borders

FIXED

Gray badges instead of cyan

Source language badges were rgba(0,0,0,0.6) background

FIXED

Missing theme switcher

No way to toggle between dark/light/catppuccin themes

FIXED

Tridactyl pointer-events

Copy buttons not clickable with Tridactyl hints

FIXED

Badge positioning

Badges floated outside code block boundary

FIXED

Implementation

CSS Changes

Code Block Structure (Remove Double Border)

/* Remove border from inner pre - only .content has border */
.doc .listingblock .content pre {
  border: none !important;
  border-radius: 0 !important;
  padding-top: 2.5rem !important;
  margin: 0 !important;
  background: transparent !important;
}

/* Container has the border */
.doc .listingblock .content {
  display: flex;
  flex-direction: column;
  border: 1px solid #0077b6;
  border-radius: 8px;
}

Cyan Badges (Matching Domus UI)

/* Language badge - cyan background, white text */
.doc .source-toolbox .source-lang {
  background: #0077b6;
  border-radius: 3px;
  padding: 0.25rem 0.5rem;
  color: #fff;
  font-family: Roboto, sans-serif;
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  pointer-events: auto;
}

/* Copy button - matching cyan */
.doc .source-toolbox .copy-button {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0077b6;
  border: none;
  border-radius: 3px;
  padding: 0.25rem 0.35rem;
  color: #fff;
  cursor: pointer;
  transition: background 0.15s;
  pointer-events: auto;
}

Tridactyl Compatibility

/* Ensure pointer-events work for Tridactyl hints */
.doc .source-toolbox {
  pointer-events: auto;
  z-index: 10;
}

.doc .source-toolbox .copy-button {
  pointer-events: auto;
}

Round 2 Fixes (Evening)

/* Badge: Dark grey (not cyan) to match Domus */
.doc .source-toolbox .source-lang {
  background: #333 !important;
  color: #cdd6f4 !important;
  border-radius: 4px;
  padding: 0.35rem 0.6rem;
}

/* Copy button: Cyan filled square with !important */
.doc .source-toolbox .copy-button {
  background: #0077b6 !important;
  padding: 0.35rem !important;
  border-radius: 4px;
}

JavaScript Changes

Theme Switcher

// Theme cycling: dark β†’ light β†’ catppuccin β†’ dark
var themes = ["dark", "light", "catppuccin"];
var icons = {dark: "πŸŒ™", light: "β˜€οΈ", catppuccin: "🐱"};
var labels = {dark: "Dark", light: "Light", catppuccin: "Mocha"};

var current = localStorage.getItem("theme") || "dark";
document.documentElement.setAttribute("data-theme", current);

// Theme toggle button in bottom-right
var btn = document.createElement("button");
btn.id = "theme-toggle";
btn.onclick = function() {
  var idx = (themes.indexOf(current) + 1) % themes.length;
  current = themes[idx];
  document.documentElement.setAttribute("data-theme", current);
  localStorage.setItem("theme", current);
  btn.textContent = icons[current] + " " + labels[current];
};

Copy Button with Embedded SVG

// SVG icon embedded inline (no external dependency)
var svgIcon = '<svg viewBox="0 0 16 16" width="16" height="16">'
  + '<path fill="currentColor" d="M0 6.75C0 5.784..."/>'
  + '</svg>';

// execCommand fallback for file:// protocol
function copyToClipboard(text) {
  if (navigator.clipboard && window.isSecureContext) {
    navigator.clipboard.writeText(text);
  } else {
    var ta = document.createElement("textarea");
    ta.value = text;
    document.body.appendChild(ta);
    ta.select();
    document.execCommand("copy");
    document.body.removeChild(ta);
  }
}

Verification

Visual Comparison

Before and after screenshots confirmed:

  • Cyan badges matching docs.domusdigitalis.dev

  • Single border on code blocks

  • Theme switcher functional

  • Copy buttons clickable via Tridactyl

Test Commands

# Generate test HTML
adoc /tmp/test-copy.adoc

# Open in browser
firefox /tmp/test-copy.html

# Test Tridactyl: press 'f' and verify copy button gets hint

Batch Conversion

With UI parity achieved, MDN conversion proceeded:

# Convert 10,872 MDN AsciiDoc files
find /home/evanusmodestus/atelier/_bibliotheca/mdn-asciidoc \
  -name "*.adoc" -print0 | \
  xargs -0 -P 8 -I {} adoc {}

MDN Macro Cleanup

Problem

MDN AsciiDoc files contained 33,653 MDN-specific macros that render as garbage in standalone HTML:

Macro Count Purpose (MDN only)

{{Compat}}

10,019

Browser compatibility tables (requires BCD backend)

{{Specifications}}

9,929

Spec tables (requires MDN backend)

{{ReadOnlyInline}}

3,437

Badge (requires MDN CSS)

{{AvailableInWorkers}}

1,517

Badge (requires MDN CSS)

{{optional_inline}}

2,563

Badge (requires MDN CSS)

Others

6,188

CSS syntax, inheritance diagrams, experimental/deprecated badges

Solution

Created cleanup script to remove macros while preserving document structure:

/tmp/mdn-cleanup-macros.sh /home/evanusmodestus/atelier/_bibliotheca/mdn-asciidoc

Results

Metric Value

Total Macros Found

52,879 (33,653 {\{…​}} + 19,226 {{…​}})

After Cleanup

0

Removed

52,879 macros

Backup Created

/tmp/mdn-asciidoc-backup-20260324-222501.tar.gz (160 MB)

Macro Types Cleaned

Macro Pattern Count Handling

{{Specifications}}

9,929

Removed entirely

{{Compat}}

10,019

Removed entirely

{{domxref("ref", "display")}}

~8,000

Extracted display text β†’ `display\`

{{jsxref("ref", "display")}}

~3,000

Extracted display text β†’ `display\`

{{cssxref("ref", "display")}}

~1,500

Extracted display text β†’ `display\`

{{HTMLElement("tag")}}

~800

Converted to `<tag>\`

{{glossary("term", "text")}}

~500

Extracted display text

{{EmbedLiveSample(…​)}}

~300

Removed entirely

{{InteractiveExample(…​)}}

~200

Removed entirely

Other badges/inline

~6,000

Removed entirely

Restore Plan (MDN AsciiDoc)

# Restore from backup if cleanup caused issues
tar -xzf /tmp/mdn-asciidoc-backup-20260324-222501.tar.gz \
  -C /home/evanusmodestus/atelier/_bibliotheca/

# Verify restoration
ls /home/evanusmodestus/atelier/_bibliotheca/mdn-asciidoc/api/abortcontroller/

Regenerate HTML (Pending)

# After cleanup verification, regenerate all HTML
find /home/evanusmodestus/atelier/_bibliotheca/mdn-asciidoc \
  -name "*.adoc" -print0 | \
  xargs -0 -P 8 -I {} ~/.local/bin/adoc {}

Rollback Plan

The adoc script is version-controlled in dotfiles-optimus:

# If needed, revert to previous version
git -C ~/atelier/_projects/personal/dotfiles-optimus log --oneline -5 -- base/bin/.local/bin/adoc
git -C ~/atelier/_projects/personal/dotfiles-optimus checkout HEAD~1 -- base/bin/.local/bin/adoc
stow -R bin

Risk Assessment

Risk Impact Mitigation Probability

Breaks existing HTML

Low - cosmetic only

Can revert via git

Very Low

Theme persistence fails

Low - defaults to dark

localStorage fallback

Very Low

Copy fails on some browsers

Medium - user inconvenience

execCommand fallback added

Low

MDN macro cleanup loses info

Medium - semantic badges removed

Backup created before cleanup; restore command documented

Very Low

Backup in /tmp gets deleted

High - no restore possible

Move to permanent location after verification

Medium

Implementation Log

Date Action Notes

2026-03-24

Issue identified

User compared adoc output to docs.domusdigitalis.dev

2026-03-24

Double border fixed

Removed border from inner pre

2026-03-24

Gray badges β†’ cyan

Changed from rgba(0,0,0,0.6) to #0077b6

2026-03-24

Theme switcher added

Dark/Light/Catppuccin with localStorage persistence

2026-03-24

Tridactyl fixed

Added pointer-events: auto, z-index: 10

2026-03-24

Committed to dotfiles-optimus

Multiple commits during iteration

2026-03-24

MDN batch conversion started

10,872 files, parallel processing

2026-03-24 (evening)

Round 2: Tridactyl hints still misaligned

User reported hints below/right of button

2026-03-24 (evening)

Root cause: CSS not applying, badge color wrong

Button had no visible background

2026-03-24 (evening)

Fix: !important flags, dark grey badge, cyan button

Matches Domus exactly now

2026-03-24 (evening)

Deferred: Copy toast styling

Different from Domus, P3 priority

2026-03-24 22:25

MDN macro issue identified

AbortController page showed {{Specifications}}, {{Compat}} garbage

2026-03-24 22:25

Backup created

/tmp/mdn-asciidoc-backup-20260324-222501.tar.gz (160 MB)

2026-03-24 22:30

Cleanup script created

/tmp/mdn-cleanup-macros.sh - parallel sed with xargs

2026-03-24 22:35

Macro cleanup executed

33,652 macros removed, 1 remaining (in code example)

2026-03-24 22:40

Verified cleanup (v1)

AbortController file clean, 33,652 macros removed

2026-03-24 22:45

Discovered additional macros

19,226 {{…​}} macros (not {\{…​}})

2026-03-24 22:50

Created v2, v3, v4, v5, v6, final scripts

Iterative cleanup with parallel sed/perl

2026-03-24 23:15

All macros cleaned

52,879 total macros removed, 0 remaining

PENDING

Regenerate all HTML

find …​ xargs -P 8 adoc

PENDING

Move backup to permanent location

Risk: /tmp gets cleaned on reboot

  • RCA: adoc UI Mismatch

  • dotfiles-optimus repository: base/bin/.local/bin/adoc

  • domus-antora-ui: source of truth for styling

Sign-Off

Role Name Date

Requestor

Evan Rosado

2026-03-24

Implementer

Claude Code

2026-03-24

Approver

Self-approved (personal tooling)

2026-03-24