Files
micronomicon/docs/framework-design-v3.md
2026-04-01 00:53:55 +02:00

33 KiB
Raw Blame History

µFrame — A DSL for Rich Terminal UIs rendered as ASCII and Micron

Overview

µFrame is a declarative DSL that compiles to rich terminal interfaces built from Unicode box-drawing, block elements, braille patterns, and careful spatial layout. It produces two outputs from the same source:

  1. Plain ASCII — the raw visual layout, viewable in any terminal
  2. Micron .mu — the same visual layout enhanced with Micron's color, styling, links, and interactive form fields

Both outputs share the same rich character art. Micron doesn't degrade the visuals — it elevates them. The ASCII art passes through verbatim into the .mu file, and Micron tags wrap it with color, emphasis, alignment, and interactivity that plain text cannot express.

                              ┌──────────────────────────────────┐
                         ┌───▶│  Plain ASCII                     │
                         │    │  Box drawing, braille, blocks     │
                         │    │  No color, no links, no forms     │
  .uf ──▶ Parser ──▶ IR ─┤    └──────────────────────────────────┘
                         │    ┌──────────────────────────────────┐
                         └───▶│  Micron .mu                      │
                              │  Same visual base                │
                              │  + `Fhex color`f                 │
                              │  + `!bold`! `*italic`*           │
                              │  + `[links`/dest]                │
                              │  + `<form fields`>               │
                              │  + `c alignment`a                │
                              └──────────────────────────────────┘

The relationship is additive:

  Plain ASCII  =  layout + structure + data viz
  Micron       =  layout + structure + data viz + color + style + interaction

1. Design Philosophy

The terminal is the canvas — in both modes

A NomadNet node browser is a terminal. A local shell is a terminal. The character grid is the shared substrate. Unicode box-drawing, block elements, and braille dots render identically in both contexts. µFrame exploits this fully:

  • Box drawing (┌─┐│└┘) creates bordered panels, tables, nested layouts — same characters in ASCII and Micron
  • Block elements (█▉▊▋▌▍▎▏░▒▓) build bar charts, gauges, heatmaps — passed through as literal text in Micron
  • Braille (, 256 patterns) gives 2×4 sub-cell resolution for sparklines and dot plots — just text, works everywhere
  • Micron then paints on top: colored bars, highlighted thresholds, bold headers, clickable links, interactive form fields

What Micron adds beyond ASCII

Micron's tag system maps perfectly onto the styling layer that plain ASCII lacks:

Capability Plain ASCII Micron
Borders & boxes ✓ box-drawing chars ✓ same chars + colored with Fhex
Bar charts ✓ block elements ✓ same blocks + colored thresholds
Sparklines ✓ braille dots ✓ same braille + colored
Status indicators ✓ ● ○ ◐ chars ✓ same chars + F0f0 green/red
Table data ✓ monospace align ✓ same alignment + bold headers
Emphasis ✗ (no mechanism) !bold! *italic* _underline_
Color ✗ (no mechanism)* Fhex textf / Bhex textb
Alignment manual spacing c centera / r righta
Links ✗ display only [click here/page.mu]
Text input ✗ display only <nameplaceholder>
Radio / checkbox ✗ visual only ✓ `<^
Headings manual styling > / >> / >>> with styling

*ASCII mode can optionally emit ANSI escape codes with --ansi, but the default is pure text.


2. The Rendering Model

Both renderers share a common CharGrid — a 2D matrix of characters that represents the visual layout. They diverge only in the final emission step.

                   ┌──────────┐
  .uf ──▶ Parse ──▶│  IR Tree  │
                   └────┬─────┘
                        │
                   ┌────▼─────┐
                   │  Layout   │  ◀── width resolution, row splits,
                   │  Engine   │      border merging, chart rendering
                   └────┬─────┘
                        │
                   ┌────▼─────┐
                   │ CharGrid  │  ◀── 2D array of (char, style) pairs
                   │ + Styles  │      style = {fg, bg, bold, italic,
                   └──┬────┬──┘       underline, link, field_meta}
                      │    │
              ┌───────▼┐  ┌▼─────────┐
              │ ASCII   │  │ Micron    │
              │ Emitter │  │ Emitter   │
              └─────────┘  └──────────┘
              chars only    chars + tags

The CharGrid

Every cell in the grid stores:

Cell:
  char      : string       # the visible character (e.g. "█", "┌", "⣿")
  fg        : string|null  # foreground color, 3-digit hex
  bg        : string|null  # background color, 3-digit hex
  bold      : bool
  italic    : bool
  underline : bool
  link      : string|null  # destination path for clickable cells
  field     : FieldMeta|null  # form field metadata for interactive cells

ASCII Emitter

Reads only cell.char from each cell. Produces a plain text file. With --ansi, reads fg, bg, bold, italic, underline and emits ANSI escape codes.

Micron Emitter

Reads every cell property. Scans each line left-to-right, tracks style state, and opens/closes Micron tags at style transitions:

Line scan:  ┌── gauge "CPU" ──────────┐
Chars:      C  P  U     █  █  █  ░  ░    6  2  %
Styles:     bold         fg:0f0          fg:f00
                         ↓               ↓
Micron:     `!CPU`!     `F0f0███`f`Ff00░░`f   `Ff0062%`f

This means the exact same box-drawing layout appears in both outputs. The Micron version simply has color and emphasis tags woven between the same characters.


3. Visual Primitives — The Shared Toolkit

Everything below renders identically in both ASCII and Micron. The Micron output adds color/style annotations on top.

3.1 Box Drawing

Four border weights:

Light          Heavy          Double         Rounded
┌──────┐      ┏━━━━━━┓      ╔══════╗      ╭──────╮
│      │      ┃      ┃      ║      ║      │      │
└──────┘      ┗━━━━━━┛      ╚══════╝      ╰──────╯

Nested boxes with automatic junction merging:

┌─────────────────┬──────────┐
│ Left Panel      │ Right    │
│                 │          │
├─────────────────┴──────────┤
│ Footer spans full width    │
└────────────────────────────┘

Titled boxes (title inlined in top border):

┌─ System Health ─────────────────────────┐
│                                         │
└─────────────────────────────────────────┘

┏━ ALERT ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                         ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

In Micron, the border characters are plain text. The title can be wrapped in !bold! and Fhex colorf tags.

3.2 Data Visualization

Horizontal bars — block elements with optional color thresholds:

  ASCII:   CPU  ████████████████████░░░░░░░░░░  62%

  Micron:  CPU  `F0f0████████████████████`f`F333░░░░░░░░░░`f  62%
                 ↑ green fill                ↑ dim empty

Gauges with thresholds — color shifts at warn/crit boundaries:

  ASCII:   MEM  █████████████████████████████░  93%  ⚠

  Micron:  MEM  `Ff00█████████████████████████████`f░  `Ff00 93%  ⚠`f
                 ↑ red because value > crit threshold

Vertical bar charts:

  ASCII:              Micron adds color per bar:

       █                    `F08f█`f
       █       █            `F08f█`f       `F0f0█`f
       █ █     █   █        `F08f█`f `Fff0█`f     `F0f0█`f   `Fff0█`f
       █ █   █ █ █ █        `F08f█`f `Fff0█`f   █ `F0f0█`f █ `Fff0█`f
       █ █ █ █ █ █ █ █      ...
       ─────────────────
       0  3  6  9 12 15

Sparklines — braille characters for inline time series:

  ASCII:   NET  ⣀⣤⣶⣿⣿⣷⣶⣤⣀⣀⣤⣶⣿⣷⣤⣀  avg 31%

  Micron:  NET  `F0ff⣀⣤⣶⣿⣿⣷⣶⣤⣀⣀⣤⣶⣿⣷⣤⣀`f  avg 31%
                 ↑ cyan sparkline

Heatmap — using shade blocks with per-cell color:

  Mon  `F0f0░`f`F0f0░`f`F4f0▒`f`F8f0▓`f`Fff0█`f`F8f0▓`f`F4f0▒`f
  Tue  `F4f0▒`f`F8f0▓`f`Fff0█`f`Fff0█`f`Fff0█`f`F8f0▓`f`F4f0▒`f
  Wed  `F0f0░`f`F0f0░`f`F0f0░`f`F4f0▒`f`F4f0▒`f`F0f0░`f`F0f0░`f
         0    4    8   12   16   20   24

In plain ASCII, same characters, no color — the shade density still communicates intensity.

Status indicators — colored in Micron, shape-coded in ASCII:

  ASCII:    ● Online    ○ Offline    ◐ Degraded    ◌ Unknown

  Micron:   `F0f0●`f Online    `Ff00○`f Offline    `Fff0◐`f Degraded

Both modes are readable — color adds clarity but shape carries the information alone.

3.3 Tables

Tables use box-drawing for structure. Identical in both outputs. Micron adds bold headers and colored status cells:

  ASCII:
  ┌──────────────────────┬──────┬─────────┬──────────┐
  │ Destination          │ Hops │ Latency │ Status   │
  ├──────────────────────┼──────┼─────────┼──────────┤
  │ a7f2::relay-east     │ 2    │ 34ms    │ ● alive  │
  │ c4e1::bridge-south   │ 4    │ 112ms   │ ● alive  │
  │ 01ab::node-gamma     │ 7    │ 580ms   │ ○ stale  │
  └──────────────────────┴──────┴─────────┴──────────┘

  Micron:
  ┌──────────────────────┬──────┬─────────┬──────────┐
  │ `!Destination`!      │`!Hops`!│`!Latency`!│`!Status`!│
  ├──────────────────────┼──────┼─────────┼──────────┤
  │ a7f2::relay-east     │ 2    │ 34ms    │ `F0f0●`f alive  │
  │ c4e1::bridge-south   │ 4    │ 112ms   │ `F0f0●`f alive  │
  │ 01ab::node-gamma     │ 7    │ 580ms   │ `Ff00○`f stale  │
  └──────────────────────┴──────┴─────────┴──────────┘

3.4 Form Elements

In ASCII, forms are visual representations. In Micron, the same characters appear but the input areas become live interactive fields.

  ASCII (visual only):
  ┌─ Search ──────────────────────────────┐
  │                                       │
  │  Query: [ _________________________ ] │
  │                                       │
  │  Scope:  (•) Local  ( ) Network       │
  │          [ ] Include offline nodes     │
  │                                       │
  │              ┌──────────┐             │
  │              │  Search  │             │
  │              └──────────┘             │
  └───────────────────────────────────────┘

  Micron (interactive):
  ┌─ `!Search`! ──────────────────────────┐
  │                                       │
  │  Query: `<32|query`Enter search...>   │
  │                                       │
  │  Scope:  `<^|scope|local|*`Local>  `<^|scope|net`Network>
  │          `<?|offline|yes`Include offline nodes>
  │                                       │
  │              `[`!Search`!`:/action/search]
  │                                       │
  └───────────────────────────────────────┘

The border characters are identical. Micron replaces the placeholder bracket notation with live form tags and turns the button into a clickable link.


4. The DSL — .uf Files

4.1 Syntax

  • Indentation defines nesting (2-space)
  • Keywords lead each line
  • Strings in double quotes
  • Pipe | separates inline list items
  • $ references variables
  • # starts comments

4.2 Layout Primitives

page "Title" [width]
  # Root container. Default width: 64.

box [weight] "Title"
  # Bordered region. weight: light|heavy|double|rounded
  # Title is inset in the top border.
  # In Micron: title gets `!bold`!, border chars are literal.

row [gap]
  # Horizontal layout. Children split available width.
  # gap: chars between children (default: 1)

col [width]
  # Explicit column in a row. Width in chars or percentage.

spacer [lines]
  # Vertical whitespace. Default: 1

pad [top] [right] [bottom] [left]
  # Inner margin for a container.

4.3 Content Primitives

heading [1|2|3] "Text"
  # Rendered with underline/box in ASCII.
  # In Micron: > / >> / >>> plus `!bold`!

text "Content with @bold{inline} @color{0f0}{modifiers}"
  # @bold{...}        → Micron `!...`!
  # @italic{...}      → Micron `*...*`
  # @under{...}       → Micron `_..._`
  # @color{hex}{...}  → Micron `Fhex...`f
  # @bg{hex}{...}     → Micron `Bhex...`b
  # In ASCII: modifiers stripped (or ANSI with --ansi)

label "Key" "Value"
  # Aligned key-value pair.

list [bullet|number|dash|arrow]
  item "First"
  item "Second"

link "Display text" "/destination.mu"
  # ASCII:  [Display text]
  # Micron: `[Display text`/destination.mu]

divider [light|heavy|double|dash|dot]
  # Full-width horizontal rule using appropriate chars.

4.4 Data Visualization Primitives

gauge "Label" [value] [max] [width]
  # Horizontal progress bar.
  # Thresholds: warn=[n] crit=[n]
  # ASCII:  Label ████████████░░░░  62%
  # Micron: same, with color shifts at thresholds

meter "Label" [value] [max]
  # Compact inline gauge (no border, just bar + %)

bar_h "Label" [value] [max] [width]
  # Single horizontal bar in a chart context.

bar_v [height]
  # Vertical bar chart container.
  bar "Label" [value]
  bar "Label" [value]
  # Uses ▁▂▃▄▅▆▇█ stacked vertically.

sparkline "Label" [values] [width]
  # Braille-dot inline chart.
  # values: comma-separated or $variable

heatmap [rows] [cols]
  # Grid of colored shade blocks.
  # Uses ░▒▓█ for intensity.
  # Micron adds per-cell `Fhex` color.

status "Label" [online|offline|degraded|unknown|alert]
  # Shape-coded indicator + label.
  # Micron adds color to the indicator.

table "Title"
  columns "Name" [width] | "Name" [width] | ...
  row "val" | "val" | ...
  # Box-drawn table with header separator.
  # Micron: bold headers, colored cells via @modifiers in values.

4.5 Form Primitives

form "name"
  field "name" [width] "placeholder"
  password "name" [width] "placeholder"
  radio "group" "Opt A" | "Opt B" | "Opt C"
  checkbox "name" "Label"
  toggle "name" "Label" [on|off]
  dropdown "name" "Opt A" | "Opt B" | "Opt C"
  button "Label" ["/action/path"]

  # ASCII: visual placeholders (brackets, radio dots, etc.)
  # Micron: live interactive fields using native form tags

4.6 Style Modifiers

Applied as indented children of any node:

align [left|center|right]
color [3-digit hex]
bg [3-digit hex]
border [light|heavy|double|rounded|none]
bold
italic
underline

4.7 Variables & Components

# Variables
let name = "Relay Alpha-7"
let cpu_data = 42, 67, 55, 78, 91, 63, 48

# Component definition
component stat(label, value, max, trend)
  box light "$label"
    gauge "$label" $value $max 20
    text "@italic{$trend}"

# Component usage
row 2
  stat "CPU" 62 100 "▲ +5%"
  stat "MEM" 84 100 "▼ -2%"

5. Complete Example

5.1 Source

let node = "Relay Alpha-7"
let uptime = "14d 3h 22m"

page "$node" 66

  box double "$node"
    align center
    text "Reticulum Network Node"
    text "Online $uptime"

  spacer

  heading 1 "Resources"

  row 2
    col
      gauge "CPU" 62 100 28 warn=75 crit=90
      gauge "GPU" 21 100 28
    col
      gauge "MEM" 84 100 28 warn=80 crit=95
      gauge "SWP" 3 100 28

  spacer

  heading 1 "Network"

  row 2
    col 40
      text "Traffic (60s)"
      sparkline "IN" 1,3,5,8,7,5,3,2,1,3,6,8,7,4 20
      sparkline "OUT" 2,2,3,5,8,7,5,3,2,1,1,3,5,8 20
    col
      label "Peers" "7 / 12"
      status "East Relay" online
      status "South Bridge" online
      status "Node Gamma" degraded

  spacer

  heading 1 "Routing"

  table "Routes"
    columns "Destination" 22 | "Hops" 6 | "RTT" 8 | "State" 10
    row "a7f2::relay-east" | "2" | "34ms" | "@color{0f0}{● alive}"
    row "c4e1::bridge-south" | "4" | "112ms" | "@color{0f0}{● alive}"
    row "01ab::node-gamma" | "7" | "580ms" | "@color{f00}{○ stale}"
    row "f390::hub-north" | "1" | "8ms" | "@color{0f0}{● alive}"

  spacer

  heading 1 "Actions"

  box rounded "Quick Command"
    form "cmd"
      field "target" 30 "Destination hash..."
      radio "mode" "Ping" | "Trace" | "Page"
      checkbox "verbose" "Verbose output"
      button "Execute" "/action/exec"

  divider heavy

  text "@center{© 2026 $node · Reticulum Network}"

5.2 ASCII Output

╔══ Relay Alpha-7 ═════════════════════════════════════════════════╗
║                     Reticulum Network Node                       ║
║                      Online 14d 3h 22m                           ║
╚══════════════════════════════════════════════════════════════════╝

 ── Resources ─────────────────────────────────────────────────────

  CPU ████████████████████░░░░░░░░  62%     MEM █████████████████████████░░  84% ⚠
  GPU ██████░░░░░░░░░░░░░░░░░░░░░  21%     SWP █░░░░░░░░░░░░░░░░░░░░░░░░░   3%

 ── Network ───────────────────────────────────────────────────────

  Traffic (60s)                          Peers: 7 / 12
  IN   ⣀⣤⣶⣿⣷⣶⣤⣀⣀⣤⣶⣿⣷⣤  4.2 KB/s      East Relay    ● online
  OUT  ⣀⣀⣠⣤⣶⣿⣷⣶⣤⣀⣀⣠⣤⣶⣿  2.1 KB/s      South Bridge  ● online
                                         Node Gamma    ◐ degraded

 ── Routing ───────────────────────────────────────────────────────

  ┌────────────────────────┬────────┬──────────┬────────────┐
  │ Destination            │ Hops   │ RTT      │ State      │
  ├────────────────────────┼────────┼──────────┼────────────┤
  │ a7f2::relay-east       │ 2      │ 34ms     │ ● alive    │
  │ c4e1::bridge-south     │ 4      │ 112ms    │ ● alive    │
  │ 01ab::node-gamma       │ 7      │ 580ms    │ ○ stale    │
  │ f390::hub-north        │ 1      │ 8ms      │ ● alive    │
  └────────────────────────┴────────┴──────────┴────────────┘

 ── Actions ───────────────────────────────────────────────────────

  ╭─ Quick Command ──────────────────────────────────────────────╮
  │                                                              │
  │  target: [ Destination hash...________________ ]             │
  │  mode:   (•) Ping   ( ) Trace   ( ) Page                    │
  │          [ ] Verbose output                                  │
  │                                     ┌───────────┐           │
  │                                     │  Execute  │           │
  │                                     └───────────┘           │
  ╰──────────────────────────────────────────────────────────────╯

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                  © 2026 Relay Alpha-7 · Reticulum Network

5.3 Micron Output

The same characters — every box corner, every bar segment, every braille dot — with Micron tags added for color and interactivity:

╔══ `!Relay Alpha-7`! ═════════════════════════════════════════════╗
║`c                 Reticulum Network Node`a                       ║
║`c                  Online 14d 3h 22m`a                           ║
╚══════════════════════════════════════════════════════════════════╝

>Resources

  `!CPU`! `F0f0████████████████████`f`F555░░░░░░░░`f  62%     `!MEM`! `Ff80█████████████████████████`f`F555░░`f  `Ff8084%`f ⚠
  `!GPU`! `F0f0██████`f`F555░░░░░░░░░░░░░░░░░░░░░`f  21%     `!SWP`! `F0f0█`f`F555░░░░░░░░░░░░░░░░░░░░░░░░░`f   3%

>Network

  `!Traffic (60s)`!                          `!Peers:`! 7 / 12
  IN   `F0cf⣀⣤⣶⣿⣷⣶⣤⣀⣀⣤⣶⣿⣷⣤`f  4.2 KB/s      East Relay    `F0f0●`f online
  OUT  `F0cf⣀⣀⣠⣤⣶⣿⣷⣶⣤⣀⣀⣠⣤⣶⣿`f  2.1 KB/s      South Bridge  `F0f0●`f online
                                         Node Gamma    `Fff0◐`f degraded

>Routing

  ┌────────────────────────┬────────┬──────────┬────────────┐
  │ `!Destination`!        │ `!Hops`! │ `!RTT`!    │ `!State`!    │
  ├────────────────────────┼────────┼──────────┼────────────┤
  │ a7f2::relay-east       │ 2      │ 34ms     │ `F0f0●`f alive    │
  │ c4e1::bridge-south     │ 4      │ 112ms    │ `F0f0●`f alive    │
  │ 01ab::node-gamma       │ 7      │ 580ms    │ `Ff00○`f stale    │
  │ f390::hub-north        │ 1      │ 8ms      │ `F0f0●`f alive    │
  └────────────────────────┴────────┴──────────┴────────────┘

>Actions

  ╭─ `!Quick Command`! ──────────────────────────────────────────╮
  │                                                              │
  │  target: `<30|target`Destination hash...>                    │
  │  mode:   `<^|mode|ping|*`Ping>   `<^|mode|trace`Trace>   `<^|mode|page`Page>
  │          `<?|verbose|yes`Verbose output>                     │
  │                                     `[`!Execute`!`:/action/exec]
  │                                                              │
  ╰──────────────────────────────────────────────────────────────╯

-━

`c© 2026 Relay Alpha-7 · Reticulum Network`a

Note how the table borders, box corners, and gauge characters are byte-for-byte identical in both outputs. Micron simply interleaves its backtick tags around the characters that need color or emphasis.


6. Intermediate Representation

IR Node

IRNode:
  type       : NodeType
  label      : string | null
  children   : IRNode[]
  styles     : {
    fg       : string | null       # 3-digit hex
    bg       : string | null
    bold     : bool
    italic   : bool
    underline: bool
    align    : left | center | right
    border   : light | heavy | double | rounded | none
  }
  layout     : {
    width    : int | pct | null
    height   : int | null
    gap      : int
    pad      : [top, right, bottom, left]
  }
  data       : {                   # type-specific
    value    : number | null
    max      : number | null
    warn     : number | null
    crit     : number | null
    values   : number[] | null     # sparkline, bar_v
    state    : enum | null         # status indicator
    options  : string[] | null     # radio, dropdown
    columns  : Column[] | null     # table
    rows     : Row[] | null        # table
    link     : string | null       # destination
    field    : FieldMeta | null    # form metadata
  }
  inline     : InlineSpan[]        # parsed @modifiers

The CharGrid

CharGrid:
  width   : int
  height  : int
  cells   : Cell[height][width]

Cell:
  char      : char          # visible character
  style     : CellStyle     # for Micron emission
  field     : FieldMeta?    # if this cell is part of a form field
  link      : string?       # if this cell is clickable

CellStyle:
  fg        : string?       # 3-digit hex
  bg        : string?
  bold      : bool
  italic    : bool
  underline : bool

The layout engine fills the CharGrid. Both emitters read it. The ASCII emitter ignores the style layer. The Micron emitter scans for style transitions and inserts tags.


7. Rendering Pipeline

Phase 1: Parse
  .uf source → token stream → IR tree
  Variables resolved, components expanded.

Phase 2: Measure
  Bottom-up pass: compute min/preferred width and height
  for each node. Leaf nodes (text, gauge, field) report
  their intrinsic sizes. Containers aggregate children.

Phase 3: Layout
  Top-down pass: assign (x, y, w, h) to every node.
  Row nodes divide width among columns.
  Box nodes reserve border characters (1 char each side).

Phase 4: Paint
  Depth-first traversal. Each node writes characters into
  the CharGrid at its assigned position:
  - Box: draw border chars, set title style
  - Gauge: compute bar length, write █ and ░, set fg color
           based on thresholds
  - Sparkline: convert values to braille patterns
  - Table: draw grid, write cell content, set header bold
  - Form: write visual placeholders, attach FieldMeta
  - Status: write indicator char, set color by state

Phase 5: Merge Borders
  Post-pass: scan for adjacent border characters and replace
  with correct junction characters (┬ ┴ ├ ┤ ┼ etc.).
  Weight priority: double > heavy > light > rounded.

Phase 6: Emit
  ASCII: read cell.char for every cell, join into lines.
  Micron: scan each line, diff style between adjacent cells,
          open/close Micron tags at transitions.

Border Merging Detail

Before:                    After:
┌────┐┌────┐              ┌────┬────┐
│    ││    │       ──▶     │    │    │
└────┘└────┘              └────┴────┘

┌────────┐                ┌────────┐
│┌──────┐│                ├──────┐ │       (nested box shares
││      ││       ──▶      │      │ │        parent left edge)
│└──────┘│                ├──────┘ │
└────────┘                └────────┘

The merging pass checks each cell against its 4 neighbors and selects from a lookup table of ~40 junction characters.


8. Character Reference

Boxes

Light:    ┌ ─ ┐ │ └ ┘ ├ ┤ ┬ ┴ ┼
Heavy:    ┏ ━ ┓ ┃ ┗ ┛ ┣ ┫ ┳ ┻ ╋
Double:   ╔ ═ ╗ ║ ╚ ╝ ╠ ╣ ╦ ╩ ╬
Rounded:  ╭ ╮ ╰ ╯
Mixed:    ╒ ╓ ╕ ╖ ╘ ╙ ╛ ╜   (light+double junctions)

Blocks

Horizontal fill: █ ▉ ▊ ▋ ▌ ▍ ▎ ▏  (full → 1/8)
Vertical fill:   ▁ ▂ ▃ ▄ ▅ ▆ ▇ █  (1/8 → full)
Shade:           ░ ▒ ▓ █           (25% → 100%)
Quadrants:       ▖ ▗ ▘ ▝ ▞ ▟ ▙ ▛ ▜ ▚

Braille (sparklines, dot plots)

Range: U+2800U+28FF (256 patterns)
Each char = 2×4 dot matrix (2 cols × 4 rows)
Smooth curves: ⠀⣀⣠⣤⣴⣶⣾⣿⣷⣶⣤⣀⠀

Indicators

Status:  ● ○ ◐ ◑ ◒ ◓ ◌ ◉
Arrows:  ▲ ▼ ◀ ▶ ← → ↑ ↓ ↗ ↘
Marks:   ✓ ✗ ◆ ◇ ★ ☆ ⚠ ⚡

9. CLI

uframe render <file.uf>              # emit ASCII (stdout) + .mu (file)
  --ascii                             # ASCII only
  --micron                            # .mu only
  --ansi                              # ANSI colors in ASCII output
  --width <int>                       # override page width
  --out <dir>                         # directory for .mu output

uframe preview <file.uf>             # live terminal preview
  --watch                             # re-render on file change

uframe check <file.uf>               # validate / lint

uframe deploy <file.uf> [dest]       # render + copy to NomadNet pages dir
  # default dest: ~/.nomadnetwork/storage/pages/

10. Standard Component Library

use std/dashboard
use std/filebrowser
use std/board

# Pre-built patterns:
dashboard.banner       node_name uptime
dashboard.resources    cpu mem gpu swap
dashboard.peers        peer_list
dashboard.traffic      in_data out_data

filebrowser.tree       root_path
filebrowser.listing    dir_path

board.recent           count
board.compose          action_path

nav.tabs               items active
nav.breadcrumb         path

chart.timeseries       label values width
chart.compare          items
chart.histogram        bins

11. Future Directions

  • Responsive reflow — breakpoints that stack row children vertically at narrow widths
  • Themes.uf-theme files defining color palettes and border preferences shared across pages
  • Animation — frame-by-frame for live dashboards using terminal cursor repositioning
  • Bidirectional — parse existing .mu into .uf for editing
  • HTML export — for web-based Reticulum browsers (rBrowser)
  • Shebang mode#!/usr/bin/env uframe --micron for executable dynamic NomadNet pages
  • LSP — editor support: highlighting, completion, live preview