CUI Interactive Tutorial
Learn CUI by building up concepts one at a time. Each lesson shows you: what a feature does, the CUI code that uses it, a live demo, and the compiled output.
Start with Lesson 1 →
Lesson 1: The Text Property
The simplest thing: putting words on the page
Every element can have a text property. It sets the text content of that element. The compiler detects that this is static and bakes it directly into the HTML file. No runtime cost.
greeting {
text: "Hello, CUI!";
}
<div>Hello, CUI!</div>
/* No CSS needed — pure text content */
/* Wasm: none — static HTML only */
Next: Elements & Structure →
Lesson 2: Elements & Structure
Building hierarchy with nesting and styling
Elements in CUI are just names followed by braces. Nesting creates parent-child relationships in the DOM. CSS properties go directly on the element — just like CSS selectors, but inline.
card {
border-left: "4px solid #5865f2";
padding: "16px";
border-radius: "4px";
card_title {
text: "My Card";
font-weight: "700";
margin-bottom: "8px";
}
card_body {
text: "Content inside the card.";
opacity: "0.7";
}
}
<div style='border-left:4px solid #5865f2;
padding:16px;border-radius:4px;'>
<div style='font-weight:700;
margin-bottom:8px;'>My Card</div>
<div style='opacity:0.7;'>
Content inside the card.</div>
</div>
/* All inline styles — no classes needed */
/* Wasm: none — static HTML only */
Output:
My Card
Content inside the card.
← Text
Classes & Cascading →
Lesson 3: Classes & Cascading
Define once, reuse everywhere
A class (name starting with .) defines properties that cascade into all same-named instances. Instance properties override class properties. Classes can appear before or after instances — the compiler hoists them.
.tag {
padding: "6px 12px";
border-radius: "4px";
color: "white";
font-size: "0.9rem";
}
tag { text: "Default"; background: "#5865f2"; }
tag { text: "Custom"; background: "#ff6b6b"; }
tag { text: "Another"; background: "#ffa500"; }
<div style='background:#5865f2;'
class='o'>Default</div>
<div style='background:#ff6b6b;'
class='o'>Custom</div>
<div style='background:#ffa500;'
class='o'>Another</div>
/* CSS (from .tag class) */
.o { color:white; padding:6px 12px;
border-radius:4px; font-size:0.9rem; }
/* Instance backgrounds are inline */
/* Wasm: none — static HTML only */
← Structure
Events & Interactivity →
Lesson 4: Events & Interactivity
Making things respond to user actions
Listeners (?click, ?blur, ?focus, etc.) respond to browser events. Properties inside a listener cascade onto the parent element when the event fires. Everything compiles to WebAssembly.
button {
text: "Click me";
color: "white";
background: "#5865f2";
cursor: "pointer";
?click {
text: "Clicked!";
background: "#ff6b6b";
}
}
<div style='color:white;font-weight:500;
cursor:pointer;background:#5865f2;
border-radius:6px;border:none;
display:inline-block;
padding:10px 20px;'>
Click me</div>
/* All instance properties — inline */
/* Wasm: click updates text, background */
Lesson 5: Variables
Reactive state that connects elements
Variables (let $name: value) hold state. When a listener assigns a new value, every element reading that variable updates automatically. This is how one element's event can change another element's appearance.
let $color: "#888";
let $status: "Waiting...";
label {
text: $status;
color: $color;
font-style: "italic";
}
button {
text: "Activate";
cursor: "pointer";
?click {
$status: "Active!";
$color: "#5865f2";
}
}
<div style='font-style:italic;color:#888;
font-size:1.1rem;margin-bottom:12px;'>
Waiting...</div>
<div style='font-weight:500;
border-radius:6px;color:white;
display:inline-block;background:#5865f2;
padding:10px 20px;cursor:pointer;
border:none;'>Activate</div>
/* Wasm: click updates $status text */
/* and $color on the label element */
Output:
Waiting...
Activate
← Events
Putting It Together →
Lesson 6: Putting It All Together
Structure + classes + events + variables in one component
Now let's combine everything. This to-do list uses: nested elements for structure, a class for shared item styling, apply to toggle checkbox state, and a variable so checking a box changes a separate status element.
let $status: "nothing checked";
.item {
display: "flex";
align-items: "center";
padding: "12px";
border-left: "4px solid #5865f2";
margin-bottom: "8px";
}
.unchecked {
width: "20px"; height: "20px";
background: "#ddd";
border-radius: "3px";
cursor: "pointer";
margin-right: "12px";
?click {
$status: "making progress!";
apply: .checked;
}
}
.checked {
width: "20px"; height: "20px";
background: "#5865f2";
border-radius: "3px";
cursor: "pointer";
margin-right: "12px";
?click {
$status: "unchecked one";
apply: .unchecked;
}
}
status { text: $status; }
item {
unchecked {}
label { text: "Learn CUI"; }
}
item {
unchecked {}
label { text: "Build something"; }
}
<div style='color:#888;margin-bottom:12px;
font-style:italic;'>nothing checked</div>
<div class='s'>
<div class='t'></div>
<div>Learn CUI</div>
</div>
<div class='s'>
<div class='t'></div>
<div>Build something</div>
</div>
/* CSS (from .item and .unchecked) */
.s { display:flex; align-items:center;
padding:12px; margin-bottom:8px;
border-left:4px solid #5865f2; }
.t { background:#ddd; width:20px;
height:20px; cursor:pointer;
margin-right:12px; border-radius:3px; }
/* Wasm: click toggles class (apply),
updates $status text */
That's the core of CUI.
Four building blocks — instances, classes, listeners, and variables — plus properties. The compiler handles the rest: cascading, scoping, and splitting your code across HTML, CSS, and WebAssembly.
← Back to Home