OCRtermaUI (CSS)TermaTypePechaForgeDictionaryFonts
◈ termaUI

Playground

Type or paste Tibetan text. Pick a font, apply an effect, select specific words for mixed styling — then copy the generated code straight into your project.

checking… checking… checking…

Step 1 Add termaUI to your project

No build tools, no configuration, no fonts to download — everything comes from the CDN.

 
Safe to use alongside any framework. termaUI only activates when you use tr- classes together with lang="bo". It will never touch Bootstrap, Tailwind, or any other CSS you already have. 4 fonts are bundled with the npm package. For all 44 fonts, also load termaui-fonts from CDN — see the fonts library for details.
Step 2 Type or style your Tibetan text

Press ⌨ phonetic to type Tibetan from your keyboard. Select — system — font for English text. Writing a mix of English and Tibetan? Press the mixed button so termaUI scales and aligns both scripts. Use stack-safe for mantras or dharanis with complex stacked consonants.

Font
Size
whole block
Effect rainbow saffron fire shimmer aurora lapis emboss outline-gold ink
Step 3 Copy the generated code

Paste this straight into your website. The code updates live as you type and style above.

 
terma.js Checks

Tests 1 & 6 use your editor text. Tests 2–5 verify punctuation fixes. Test 7 verifies auto-clustering (requires terma-clusters.js).

ZWS after tsheg — enables line-breaking

using: editor text
— click "Run all 7 checks" above

Tsheg before shad → non-breaking (་། → ༌།)

using: fixed sample
སངས་རྒྱས་ཆོས་དང་ཚོགས་ཀྱི་མཆོག་རྣམས་ལ་།
— click "Run all 7 checks" above

Tsheg before nyis-shad → non-breaking (་༎ → ༌༎)

using: fixed sample
སངས་རྒྱས་ཆོས་དང་ཚོགས་ཀྱི་མཆོག་རྣམས་ལ་༎
— click "Run all 7 checks" above

Tsheg before gter-ma → non-breaking (་༔ → ༌༔)

using: fixed sample
ཨོཾ་ཨཱཿཧཱུྃ་བཛྲ་གུ་རུ་པདྨ་སིདྡྷི་ཧཱུྃ་༔
— click "Run all 7 checks" above

Double-shad protected (། །)

using: fixed sample
བཀྲ་ཤིས་བདེ་ལེགས། །
— click "Run all 7 checks" above

Editor content — terma.prepare() status

using: editor text
— click "Run all 7 checks" above

Ghost circles — combining marks auto-clustered

using: test element · requires terma-clusters.js
བོད་
— click "Run all 7 checks" above
Font Size Check

Canvas API measures each font's cap-height at 100px. All fonts should render within ±12% of Jomolhari's reference ascent.

Head-Mark Alignment

Mixed font-sizes scatter Tibetan head marks (མགོ་ཅན). Layer 1 (CSS) gets ~95% there instantly; Layer 2 (JS) snaps to 0.04px accuracy via Canvas measurement.

Without alignment (baseline)
བཀྲ་ཤིས་བདེ་ལེགས། སངས་རྒྱས།
vertical-align: baseline — head marks scattered vertically
With head-mark alignment
བཀྲ་ཤིས་བདེ་ལེགས། སངས་རྒྱས།
CSS fallback active — click "Run alignment" for pixel-perfect JS layer

Layer 1 — CSS fallback (instant, ~95% accurate)

 

Layer 2 — JS pixel-perfect (Canvas TextMetrics, 0.04px accuracy)

 
The math: vertical-align = parentRatio × parentSize − spanRatio × spanSize
Each span's head mark ends up at parentBaseline + parentRatio × parentSize — constant for all spans, regardless of their individual font-size. Ratio is measured via Canvas TextMetrics.actualBoundingBoxAscent / fontSize. Jomolhari ratio ≈ 0.740 (head mark sits 74% of font-size above the baseline).
What's New
v0.2.0 current
  • CSS: [lang="bo"] now includes ligatures + padding-block by default — .tr-guard and .tr-ligatures no longer required on every element
  • CSS: size-adjust added to all 44 @font-face declarations — fonts now render at comparable visual sizes out of the box; no manual font-size fiddling needed
  • CSS: .tr-mixed — inline Tibetan inside English text: scales up 1.15× and adjusts baseline alignment automatically
  • CSS: [contenteditable][lang="bo"] gets white-space: pre-wrap automatically — prevents ZWS from collapsing as users type
  • JS: terma.prepareEditable(el) / terma.prepareAllEditables() — live ZWS maintenance for contenteditable Tibetan inputs; re-applies on each keystroke (debounced 150 ms)
  • JS: terma-clusters.js module — isTibetanCombining(code) and tibetanClusters(str) grapheme clustering utilities
  • JS: terma.prepare() auto-clusters combining marks into .tr-cluster spans when terma-clusters.js is loaded — prevents dotted-circle artifacts with no extra code
  • JS: terma.cluster(el) / terma.clusterAll() — explicit clustering API
  • CSS: .tr-cluster — inline-block cluster container; .tr-render-safe — full rendering checklist for JS-generated containers
  • CSS: Head-mark alignment (Layer 1) — sized spans inside [lang="bo"] get vertical-align: text-top automatically; Latin spans classified as .tt-latin revert to baseline
  • JS: Head-mark alignment (Layer 2) — terma.prepare() now auto-aligns head marks (མགོ་ཅན) across mixed font-sizes using Canvas TextMetrics; pixel-perfect to 0.04px
  • JS: terma.alignHeadMarks(el) / terma.alignHeadMarksAll() — explicit alignment API for dynamic size changes after prepare()
  • JS: terma.measureAscentRatio(fontFamily) — exposed Canvas ascent measurement for advanced use; cached per font family
  • JS: Automatic re-alignment on document.fonts.ready — ascent cache clears and all aligned containers re-measure after webfont swap
v0.1.1
  • Fix: corrected GitHub repository URL in package.json
v0.1.0
  • Initial release — CSS framework with 44 Tibetan fonts, utility classes (.tr-guard, .tr-ligatures, size, effects), and terma.js line-breaking utilities (prepare(), prepareAll(), normalize())
Font Gallery — 44 Fonts

.tr-jomolhari

བཀྲ་ཤིས་བདེ་ལེགས།
Jomolhari · Traditional manuscript

.tr-noto

བཀྲ་ཤིས་བདེ་ལེགས།
Noto Serif Tibetan · Modern screen serif

.tr-machine-uni

བཀྲ་ཤིས་བདེ་ལེགས།
Tibetan Machine Uni · Bold headline

.tr-babelstone

བཀྲ་ཤིས་བདེ་ལེགས།
BabelStone · Max Unicode coverage

.tr-babelstone-slim

བཀྲ་ཤིས་བདེ་ལེགས།
BabelStone Slim · Compact variant

.tr-ddc-uchen

བཀྲ་ཤིས་བདེ་ལེགས།
DDC Uchen · Official Bhutanese

.tr-ddc-rinzin

བཀྲ་ཤིས་བདེ་ལེགས།
DDC Rinzin · Decorative calligraphic

.tr-gangjie

བཀྲ་ཤིས་བདེ་ལེགས།
GangJie Uchen · Clean modern

.tr-jamyang

བཀྲ་ཤིས་བདེ་ལེགས།
Jamyang Monlam · Calligraphic stroke

.tr-monlam

བཀྲ་ཤིས་བདེ་ལེགས།
Monlam Bodyig · Thin-stroke elegant

.tr-panchen

བཀྲ་ཤིས་བདེ་ལེགས།
Panchen Tsukring · Extended ascenders

.tr-riwoche

བཀྲ་ཤིས་བདེ་ལེགས།
Riwoche Dhodri · Woodblock-inspired

.tr-sadri

བཀྲ་ཤིས་བདེ་ལེགས།
Sadri Yigchen · Clean formal

.tr-monlam-ouchan1

བཀྲ་ཤིས་བདེ་ལེགས།
OuChan 1 · Reference weight

.tr-monlam-ouchan2

བཀྲ་ཤིས་བདེ་ལེགས།

.tr-monlam-ouchan3

བཀྲ་ཤིས་བདེ་ལེགས།

.tr-monlam-ouchan4

བཀྲ་ཤིས་བདེ་ལེགས།

.tr-monlam-ouchan5

བཀྲ་ཤིས་བདེ་ལེགས།

.tr-monlam-paytsik

བཀྲ་ཤིས་བདེ་ལེགས།
PayTsik · Display / seal

.tr-monlam-tikrang

བཀྲ་ཤིས་བདེ་ལེགས།
Tikrang · Ornamental long-stroke

.tr-monlam-tiktong

བཀྲ་ཤིས་བདེ་ལེགས།
TikTong · Ornamental short-stroke

.tr-qomolangma-sarchen

བཀྲ་ཤིས་བདེ་ལེགས།
Sarchen · Large formal

.tr-qomolangma-betsu

བཀྲ་ཤིས་བདེ་ལེགས།
Betsu · Compact abbreviated

.tr-qomolangma-tsutong

བཀྲ་ཤིས་བདེ་ལེགས།
Tsutong · Short-headed display

.tr-noto-sans

བཀྲ་ཤིས་བདེ་ལེགས།
Noto Sans Tibetan

.tr-misans

བཀྲ་ཤིས་བདེ་ལེགས།
MiSans Tibetan · Geometric

.tr-monlam-sans

བཀྲ་ཤིས་བདེ་ལེགས།
Monlam Uni Sans

.tr-drutsa

བཀྲ་ཤིས་བདེ་ལེགས།
Qomolangma-Drutsa · Flowing cursive

.tr-gangjie-drutsa

བཀྲ་ཤིས་བདེ་ལེགས།

.tr-khampa-drutsa

བཀྲ་ཤིས་བདེ་ལེགས།
Khampa Dedri Drutsa

.tr-sadri-drutsa

བཀྲ་ཤིས་བདེ་ལེགས།

.tr-monlam-dutsa1

བཀྲ་ཤིས་བདེ་ལེགས།

.tr-monlam-dutsa2

བཀྲ་ཤིས་བདེ་ལེགས།

.tr-joyig

བཀྲ་ཤིས་བདེ་ལེགས།
Joyig · Semi-formal

.tr-chuyig

བཀྲ་ཤིས་བདེ་ལེགས།
Khampa Chuyig · Correspondence

.tr-bechu

བཀྲ་ཤིས་བདེ་ལེགས།
Khampa Bechu · Informal

.tr-noto-thin

བཀྲ་ཤིས་བདེ་ལེགས།
Thin 100

.tr-noto-extralight

བཀྲ་ཤིས་བདེ་ལེགས།
ExtraLight 200

.tr-noto-light

བཀྲ་ཤིས་བདེ་ལེགས།
Light 300

.tr-noto

བཀྲ་ཤིས་བདེ་ལེགས།
Regular 400

.tr-noto-medium

བཀྲ་ཤིས་བདེ་ལེགས།
Medium 500

.tr-noto-semibold

བཀྲ་ཤིས་བདེ་ལེགས།
SemiBold 600

.tr-noto-bold

བཀྲ་ཤིས་བདེ་ལེགས།
Bold 700

.tr-noto-extrabold

བཀྲ་ཤིས་བདེ་ལེགས།
ExtraBold 800

.tr-noto-black

བཀྲ་ཤིས་བདེ་ལེགས།
Black 900
Visual Effects Gallery

.tr-text-rainbow

བཀྲ་ཤིས།

.tr-text-saffron

བཀྲ་ཤིས།

.tr-text-fire

བཀྲ་ཤིས།

.tr-shimmer

བཀྲ་ཤིས།

.tr-glow-aurora

བཀྲ་ཤིས།

.tr-text-lapis

བཀྲ་ཤིས།

.tr-emboss

བཀྲ་ཤིས།

.tr-outline-gold

བཀྲ་ཤིས།

.tr-text-ink

བཀྲ་ཤིས།
DOM Utilities — Dynamic Content

Dynamic Content Container — .tr-render-safe

A single class that applies the complete Tibetan rendering checklist to any container whose text is inserted via JavaScript. Consolidates .tr-ligatures + .tr-guard + .tr-overflow-safe + font stack — no more missing one property and wondering why stacks are broken.

Without .tr-render-safe
With .tr-render-safe
<!-- Any container with JS-generated Tibetan text -->
<div class="tr-render-safe" lang="bo" id="output"></div>

<script>
  document.getElementById('output').textContent = myTibetanString;
</script>
Properties applied: Tibetan font stack · "blws" "abvs" consonant stacking · padding-block: 0.25em clipping guard · word-break: keep-all · overflow-wrap: anywhere · line-height: 1.8 · antialiased rendering

Live Editing — terma.prepareEditable(el)

Keeps ZWS (zero-width spaces) and non-breaking tshegs up to date as the user types. Without it, ZWS inserted by prepare() can be overwritten and line-breaking reverts. Pair with lang="bo" — termaUI automatically adds white-space: pre-wrap so ZWS characters are never collapsed.

Live editor — type Tibetan here
བཀྲ་ཤིས་བདེ་ལེགས།

ZWS re-applied 150 ms after each keystroke. Line-breaking stays correct.

<div contenteditable="true" lang="bo" class="tr-jomolhari" id="myEditor"></div>

<script>
  // One call handles everything — no input listener needed
  terma.prepareEditable(document.getElementById('myEditor'));
</script>

Mixed Content — .tr-mixed

Tibetan script is taller than Latin at the same font-size. Wrapping inline Tibetan in .tr-mixed scales it to 1.15em and shifts the baseline by -0.15em so both scripts sit on the same visual line without extra line-height or manual adjustments.

Without .tr-mixed

The Tibetan word for enlightenment is བྱང་ཆུབ། which is profound.

With .tr-mixed

The Tibetan word for enlightenment is བྱང་ཆུབ། which is profound.

<p>The Tibetan word for enlightenment is
  <span lang="bo" class="tr-jomolhari tr-mixed">བྱང་ཆུབ།</span>
  which is profound.
</p>
Properties applied by .tr-mixed: font-size: 1.15em · vertical-align: -0.15em · line-height: 1 · padding-block: 0 (overrides the container guard)