ApricityUI
Build UIs with HTML + CSS + JS. The syntax follows Web standards as closely as possible.

Overview
ApricityUI was built around one goal: a UI framework that is low-friction, convenient, and broadly capable. That is why it takes the classic HTML + CSS + JS trio as its core.
The JS side currently depends on KubeJS (optional), which means modpack authors can draw whatever UI they like with an extremely low learning curve.
How low? You can have AI generate everything ApricityUI-related for you. Web frameworks are popular enough that AI knows them well — the result may even look better than what you would draw yourself, and you can still read it.
Mods that need custom UI can also depend on ApricityUI to build highly extensible interfaces; the JS and Java APIs are broadly equivalent.
Where does that extensibility show? Nested masks, smooth scrolling, rounded borders, frosted-glass backgrounds, custom animations, custom fonts, GIF playback — even filters, masks, and shadows nested inside one another. Features that take hundreds or thousands of lines elsewhere are a few lines here.
ApricityUI's syntax is essentially fixed and stays as close to Web standards as possible, so you can upgrade freely and use it across game versions without worrying about compatibility breaks.
From 1.2.5 onward, ApricityUI can also call the WebView built into your operating system, letting you embed a real website or web page inside the game that accepts only hardware input (video playback included).
If you are not sure what a Web framework is, at least remember its three well-known advantages:
- Rich functionality, from simple shape drawing to nested rendering effects — ApricityUI can even render onto a block in the world.
- Easy to use: most crash courses I have seen are under three hours (the shortest is ten minutes), and AI knows the stack inside out.
- Easy to debug: almost everything hot-reloads instantly, and convenient developer tools provide visual debugging. ApricityUI has both.
Note: ApricityUI does not bundle a Chrome runtime. It is built entirely from scratch in Java; as of 1.2.4 the jar is only 2.5 MB, it downloads nothing extra, and it is safe to use.
Showcase
Built-in pure-CSS themes
The Ore and AE themes are built in, and more MC-flavored (or deliberately un-MC) general-purpose themes will follow. They all share the same CSS naming scheme, so switching between them is seamless.
-
Limitless Vehicle 3D printer

-
Auto Seam Blend editor

Draw whenever you like
It integrates fully with Minecraft's rendering — draw wherever you want. KubeJS alone is enough to customize item tooltips and radial menus.
-
东方足道屿 item tooltip

-
Simple radial menu (by SurpTalent)

Canvas
Canvas support that is good enough for charts, SVG drawing, complex nested effects, doodle boards, and similar everyday work.
- Building Shop stock market

- Auto Seam Blend drawing board

World windows
HTML can render at a position inside the world, with configurable angle, block pass-through, interaction distance, view distance, camera follow, LOD, and other details.
-
东方足道屿 maid foot massage

-
Mob health bars and item display (by ୧⍤⃝无月)

Native Minecraft elements
Manage container slots, items, fluids, textures, models, sprite animations, translation keys, and other native elements the HTML way.
-
Building Shop building materials shop

-
Cobblemon Skin Manager (by 卡杨巴)

Rich text editor
Rich text editors can be built in a data-driven way.
- Built-in rich text editor example

WebView
So that different mods' UIs can stay independent while still interacting with each other, ApricityUI uses a multi-document architecture. That removes most of the point of the iframe tag, and Minecraft rarely needs nested interfaces anyway — so today ApricityUI's iframe tag is used entirely to embed WebView.
Put simply, creating a document with an iframe tag actually opens a WebView and draws it off-screen into the iframe's area.
WebView's drawbacks are obvious: from either Java or KubeJS it is hard to find an elegant way to interact with it logically, so ApricityUI currently only forwards hardware input to it.
Its high memory use also makes WebView a poor fit for overlays and world windows.
A small number of environments do not ship a WebView at all (Linux, for example), but this mod will never embed one.
The upside is that WebView partly compensates for ApricityUI's incomplete coverage of browser standards. It can draw complex pages that have little to do with the game, or open external sites directly — live documentation, changelogs, mod tutorial videos — and it supports building an in-world cinema.

For developers
Note: All documents and skills are built into the module file, and AI is ready to use.
Using ApricityUI requires no knowledge of the source code. If you need it, the official Maven is available:
repositories {
maven {
url "https://maven.sighs.cc/repository/maven-public/"
}
}
dependencies {
implementation 'com.sighs:ApricityUI-forge-1.20.1:1.2.7'
}
Developing Web apps with AI is very easy — you do not even need a SKILL, and the same goes for ApricityUI.
A simple example: one sentence generates an interface.

Generating random designs until you like one, then adapting the static template, is a high-efficiency workflow.
A freshly generated static template can be imported and previewed directly in the resource manager; images, audio, fonts, and other static assets can be previewed too, and the context menu offers quick reference.
To avoid key conflicts, starting with 1.2.4 the resource manager shortcuts are unbound by default — bind them yourself before debugging.

Since 1.2.4 the jar bundles the complete documentation, and the config file has options for automatic screenshots (up to 20 kept) and for reloading the matching interface as soon as a file changes. All of these are designed for AI.
Inside an AI coding agent you can phrase it this way to keep iterating on a design:
The task is to create or modify a UI; only HTML/CSS/JS may be changed.
Follow the guidance in the bundled documentation.
Known: the folder run/screenshots/aui outputs a game screenshot every second; static assets are watched automatically and trigger a reload on change.
Test loop: edit the html/css/js files -> watch the log for the reload message -> wait three seconds, then check the newest screenshot in the screenshots folder -> judge whether it matches the requirement; if not, keep editing, if yes, stop.
Target HTML file: run/apricity/test/quest.html
Required result: an in-game quest list, modern flat style, red and white palette
Reference image: run/screenshots/image_614748742442633.png
The full SKILL is documented in the official docs and is bundled in the jar with the full docs.
Complex UI needs are rare in Minecraft. In general, letting AI read the bundled documentation is enough to finish most design work in one pass, and with a built-in theme the result already looks good.
Once the interface is roughly done, you can bring up debugging tools similar to a browser's — also unbound by default since 1.2.4.
In DevTools you can locate and pick elements on the page and edit styles and content directly, with undo and redo, then save the styles or the full DOM content.
Logs about unsupported features, syntax errors, internal exceptions, and similar problems are mirrored into the DevTools console.

You can also borrow ready-made styles from Codepen. If you hit a CSS property you need that is missing, open an issue on Github.
Asset distribution
ApricityUI supports HTML, CSS, Javascript, TTF/OTF fonts, and most image formats including GIF as static assets; audio and video are planned.
Assets live in the apricity folder of the version instance and in resource packs. Resource packs have lower priority, but the default global styles and built-in fonts ship in the mod's own resources.
For modpack developers, the apricity folder is the recommended location. Hot reload is bound to END by default and usually takes under a second.
See the Resource Manager chapter of the official docs for details.
If you want to package and share, either a resource pack or a plain archive works. Since a resource pack also requires reloading the game, a simple archive is recommended.
For mods that use ApricityUI as a dependency, the resource-pack form is better: the default load paths include the development resource-pack path with the highest priority, which is very convenient.
Another option is network assets, such as image hosts or open-source static hosting sites. ApricityUI supports loading network assets asynchronously — just do not do anything bad with it.
ApricityUI also offers a retro "server sends HTML to the client to render" workflow, which lets you manage the client UI entirely from the server.
Want to know more?
- ApricityUI also implements browser-style zoom: hold CTRL and scroll on a page to zoom in and out, so players can adapt to any window size.
- KubeJS is an optional dependency. Without it you cannot run the JavaScript written inside HTML, and the console is unavailable — but for mod developers that rarely matters, since DOM work can be done in Java.
- Hot reload is fast: twenty different QQ avatars plus three custom fonts, including inline JS, reload a whole document in about one second. If you write KubeJS client scripts you might even use it to cut corners — though the resource paths offer no PJS completion. Note that this reload does not reload resource packs.
- ApricityUI has no obvious performance bottleneck in normal use, and on 26.1 and above there is almost nothing to worry about. But the author cannot test every case — if you happen to hit a sudden stutter, please report it immediately.
- Lightweight ports of modern front-end frameworks such as Vue and Svelte are in active development. A simple Vue already has a PR from kltyton, and Svelte will be built in later. Join the group if you are interested!
Gallery
-
Machine-Max vehicle settings

-
FindMe companion management

How to Install ApricityUI (Mod)
ApricityUI by MerrySnow is verified for Fabric, Forge, Neoforge across Minecraft versions 1.18.2, 1.19.2, 1.19.3, 1.19.4, 1.20.1, 1.20.2, 1.20.3, 1.20.4 (latest release: 1.2.8, file size: 2.4 MB). Follow the steps below to install it safely from ModCraft.tv:
- Click the Download button above and select your Minecraft version (1.18.2, 1.19.2, 1.19.3, 1.19.4, 1.20.1, 1.20.2, 1.20.3, 1.20.4) and platform (Fabric, Forge, Neoforge).
- Make sure you have the compatible loader or environment installed for Fabric, Forge, Neoforge.
- Move the downloaded ApricityUI file into your Minecraft
.minecraft/modsfolder and launch the game.
All Versions
+ Add Version| Name | Game version | Platforms | Published | Downloads | Actions |
|---|---|---|---|---|---|
| 10d ago | 1 | ||||
| 10d ago | 1 | ||||
| 10d ago | 1 | ||||
| 10d ago | 1 | ||||
| 10d ago | 1 | ||||
| 10d ago | 1 | ||||
| 10d ago | 1 | ||||
| 10d ago | 1 | ||||
| 24d ago | 1 | ||||
| 24d ago | 1 | ||||
| 24d ago | 1 | ||||
| 24d ago | 1 | ||||
| 24d ago | 1 | ||||
| 24d ago | 1 | ||||
| 24d ago | 1 | ||||
| 24d ago | 1 | ||||
| 27d ago | 1 | ||||
| 27d ago | 1 | ||||
| 27d ago | 1 | ||||
| 27d ago | 1 | ||||
| 27d ago | 1 | ||||
| 27d ago | 1 | ||||
| 27d ago | 1 | ||||
| 27d ago | 1 | ||||
| 1mo ago | 1 | ||||
| 1mo ago | 1 | ||||
| 1mo ago | 1 | ||||
| 1mo ago | 1 | ||||
| 1mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 3mo ago | 1 | ||||
| 5mo ago | 1 | ||||
| 5mo ago | 1 | ||||
| 5mo ago | 1 | ||||
| 5mo ago | 1 | ||||
| 5mo ago | 1 | ||||
| 5mo ago | 1 | ||||
| 6mo ago | 1 | ||||
| 7mo ago | 1 | ||||
| 7mo ago | 1 | ||||
| 7mo ago | 1 | ||||
| 7mo ago | 1 | ||||
| 7mo ago | 1 | ||||
| 8mo ago | 1 | ||||
| 8mo ago | 1 | ||||
| 8mo ago | 1 | ||||
| 8mo ago | 1 | ||||
| 8mo ago | 1 | ||||
| 8mo ago | 1 |
- Added 14 standardized, switchable CSS themes: Ore, Claude Square/Round, CurseForge, Modrinth Light/Dark, Arwes and Arwes Transparent, Neobrutalist, Hand-Drawn Doodle, Retro Vintage, Vaporwave, Impressionist Oil, and Mecha.
apricityui/theme/t00-example.htmlpreviews the same component markup across themes and loads theme stylesheets on demand. - Added the self-contained
<theme-switcher>floating control, with runtime stylesheet loading, theme scope management, andaui-theme-changenotifications. - Added
IntersectionObserversupport and documentation. - Added CSS
outline, its width/style/color/offset longhands, browser-style paint ordering, rounded geometry, visual bounds, and clipping behavior. Outlines do not affect layout; unsupported line patterns still fall back to solid and outline transitions are not yet supported. - Added
perspective()transform parsing and projective geometry for perspective backgrounds, with matching visual bounds and pointer-coordinate mapping.
### Changed
- Standardized theme tokens and component conventions, expanded the theme documentation, and replaced individual demo pages with the shared theme preview.
- Removed the old bundled McUI theme. Pages using its resource paths need to migrate; the new Ore theme is available at
apricityui/theme/t01-ore/t01-ore.css. The existing legacy Ore resources are separate from the new standardized theme. - Reduced packaged resource overhead and redundant bundled assets, and updated the embedded English documentation.
### Performance
- Reworked custom-font rendering around reusable glyph caches instead of whole-line bitmaps, reducing repeated rasterization and texture work.
- Reduced redundant layout invalidation: ancestor changes no longer repeatedly clear overlapping descendant trees, position caches validate their geometry dependencies, and refresh-time full-tree clearing handles each node locally.
- Reused compiled selector token patterns, removed exception-based handling of unsupported CSS properties, and avoided repeated font-name-table reads when looking up derived fonts.
- Skipped the redundant final style pass for documents with no applicable NeoForge 1.21.1 expansion work; unknown or changing expanders retain the complete style pass.
- Improved DevTools DOM-tree expansion and scrolling for large child lists, including cached subtree counts and reduced rebuilding.
- Improved repeated-gradient geometry generation and bounded repeat work while retaining color-stop coverage. Added physical-pixel coverage for thin perspective grid bands.
### Fixed
- Corrected browser-parity issues across theme layouts: flex wrapping and anonymous text, positioned flex sizing, absolute static positions and shrink-to-fit text, max-width inline wrapping, input stretching, text transforms, border rendering, rounded zero-blur shadows, and variable-backed background shorthands.
- Fixed repeating-gradient image sizing and phase, clipped gradient
- Added 14 standardized, switchable CSS themes: Ore, Claude Square/Round, CurseForge, Modrinth Light/Dark, Arwes and Arwes Transparent, Neobrutalist, Hand-Drawn Doodle, Retro Vintage, Vaporwave, Impressionist Oil, and Mecha.
apricityui/theme/t00-example.htmlpreviews the same component markup across themes and loads theme stylesheets on demand. - Added the self-contained
<theme-switcher>floating control, with runtime stylesheet loading, theme scope management, andaui-theme-changenotifications. - Added
IntersectionObserversupport and documentation. - Added CSS
outline, its width/style/color/offset longhands, browser-style paint ordering, rounded geometry, visual bounds, and clipping behavior. Outlines do not affect layout; unsupported line patterns still fall back to solid and outline transitions are not yet supported. - Added
perspective()transform parsing and projective geometry for perspective backgrounds, with matching visual bounds and pointer-coordinate mapping.
### Changed
- Standardized theme tokens and component conventions, expanded the theme documentation, and replaced individual demo pages with the shared theme preview.
- Removed the old bundled McUI theme. Pages using its resource paths need to migrate; the new Ore theme is available at
apricityui/theme/t01-ore/t01-ore.css. The existing legacy Ore resources are separate from the new standardized theme. - Reduced packaged resource overhead and redundant bundled assets, and updated the embedded English documentation.
### Performance
- Reworked custom-font rendering around reusable glyph caches instead of whole-line bitmaps, reducing repeated rasterization and texture work.
- Reduced redundant layout invalidation: ancestor changes no longer repeatedly clear overlapping descendant trees, position caches validate their geometry dependencies, and refresh-time full-tree clearing handles each node locally.
- Reused compiled selector token patterns, removed exception-based handling of unsupported CSS properties, and avoided repeated font-name-table reads when looking up derived fonts.
- Skipped the redundant final style pass for documents with no applicable NeoForge 1.21.1 expansion work; unknown or changing expanders retain the complete style pass.
- Improved DevTools DOM-tree expansion and scrolling for large child lists, including cached subtree counts and reduced rebuilding.
- Improved repeated-gradient geometry generation and bounded repeat work while retaining color-stop coverage. Added physical-pixel coverage for thin perspective grid bands.
### Fixed
- Corrected browser-parity issues across theme layouts: flex wrapping and anonymous text, positioned flex sizing, absolute static positions and shrink-to-fit text, max-width inline wrapping, input stretching, text transforms, border rendering, rounded zero-blur shadows, and variable-backed background shorthands.
- Fixed repeating-gradient image sizing and phase, clipped gradient
- Added 14 standardized, switchable CSS themes: Ore, Claude Square/Round, CurseForge, Modrinth Light/Dark, Arwes and Arwes Transparent, Neobrutalist, Hand-Drawn Doodle, Retro Vintage, Vaporwave, Impressionist Oil, and Mecha.
apricityui/theme/t00-example.htmlpreviews the same component markup across themes and loads theme stylesheets on demand. - Added the self-contained
<theme-switcher>floating control, with runtime stylesheet loading, theme scope management, andaui-theme-changenotifications. - Added
IntersectionObserversupport and documentation. - Added CSS
outline, its width/style/color/offset longhands, browser-style paint ordering, rounded geometry, visual bounds, and clipping behavior. Outlines do not affect layout; unsupported line patterns still fall back to solid and outline transitions are not yet supported. - Added
perspective()transform parsing and projective geometry for perspective backgrounds, with matching visual bounds and pointer-coordinate mapping.
### Changed
- Standardized theme tokens and component conventions, expanded the theme documentation, and replaced individual demo pages with the shared theme preview.
- Removed the old bundled McUI theme. Pages using its resource paths need to migrate; the new Ore theme is available at
apricityui/theme/t01-ore/t01-ore.css. The existing legacy Ore resources are separate from the new standardized theme. - Reduced packaged resource overhead and redundant bundled assets, and updated the embedded English documentation.
### Performance
- Reworked custom-font rendering around reusable glyph caches instead of whole-line bitmaps, reducing repeated rasterization and texture work.
- Reduced redundant layout invalidation: ancestor changes no longer repeatedly clear overlapping descendant trees, position caches validate their geometry dependencies, and refresh-time full-tree clearing handles each node locally.
- Reused compiled selector token patterns, removed exception-based handling of unsupported CSS properties, and avoided repeated font-name-table reads when looking up derived fonts.
- Skipped the redundant final style pass for documents with no applicable NeoForge 1.21.1 expansion work; unknown or changing expanders retain the complete style pass.
- Improved DevTools DOM-tree expansion and scrolling for large child lists, including cached subtree counts and reduced rebuilding.
- Improved repeated-gradient geometry generation and bounded repeat work while retaining color-stop coverage. Added physical-pixel coverage for thin perspective grid bands.
### Fixed
- Corrected browser-parity issues across theme layouts: flex wrapping and anonymous text, positioned flex sizing, absolute static positions and shrink-to-fit text, max-width inline wrapping, input stretching, text transforms, border rendering, rounded zero-blur shadows, and variable-backed background shorthands.
- Fixed repeating-gradient image sizing and phase, clipped gradient
- Added 14 standardized, switchable CSS themes: Ore, Claude Square/Round, CurseForge, Modrinth Light/Dark, Arwes and Arwes Transparent, Neobrutalist, Hand-Drawn Doodle, Retro Vintage, Vaporwave, Impressionist Oil, and Mecha.
apricityui/theme/t00-example.htmlpreviews the same component markup across themes and loads theme stylesheets on demand. - Added the self-contained
<theme-switcher>floating control, with runtime stylesheet loading, theme scope management, andaui-theme-changenotifications. - Added
IntersectionObserversupport and documentation. - Added CSS
outline, its width/style/color/offset longhands, browser-style paint ordering, rounded geometry, visual bounds, and clipping behavior. Outlines do not affect layout; unsupported line patterns still fall back to solid and outline transitions are not yet supported. - Added
perspective()transform parsing and projective geometry for perspective backgrounds, with matching visual bounds and pointer-coordinate mapping.
### Changed
- Standardized theme tokens and component conventions, expanded the theme documentation, and replaced individual demo pages with the shared theme preview.
- Removed the old bundled McUI theme. Pages using its resource paths need to migrate; the new Ore theme is available at
apricityui/theme/t01-ore/t01-ore.css. The existing legacy Ore resources are separate from the new standardized theme. - Reduced packaged resource overhead and redundant bundled assets, and updated the embedded English documentation.
### Performance
- Reworked custom-font rendering around reusable glyph caches instead of whole-line bitmaps, reducing repeated rasterization and texture work.
- Reduced redundant layout invalidation: ancestor changes no longer repeatedly clear overlapping descendant trees, position caches validate their geometry dependencies, and refresh-time full-tree clearing handles each node locally.
- Reused compiled selector token patterns, removed exception-based handling of unsupported CSS properties, and avoided repeated font-name-table reads when looking up derived fonts.
- Skipped the redundant final style pass for documents with no applicable NeoForge 1.21.1 expansion work; unknown or changing expanders retain the complete style pass.
- Improved DevTools DOM-tree expansion and scrolling for large child lists, including cached subtree counts and reduced rebuilding.
- Improved repeated-gradient geometry generation and bounded repeat work while retaining color-stop coverage. Added physical-pixel coverage for thin perspective grid bands.
### Fixed
- Corrected browser-parity issues across theme layouts: flex wrapping and anonymous text, positioned flex sizing, absolute static positions and shrink-to-fit text, max-width inline wrapping, input stretching, text transforms, border rendering, rounded zero-blur shadows, and variable-backed background shorthands.
- Fixed repeating-gradient image sizing and phase, clipped gradient
- Added 14 standardized, switchable CSS themes: Ore, Claude Square/Round, CurseForge, Modrinth Light/Dark, Arwes and Arwes Transparent, Neobrutalist, Hand-Drawn Doodle, Retro Vintage, Vaporwave, Impressionist Oil, and Mecha.
apricityui/theme/t00-example.htmlpreviews the same component markup across themes and loads theme stylesheets on demand. - Added the self-contained
<theme-switcher>floating control, with runtime stylesheet loading, theme scope management, andaui-theme-changenotifications. - Added
IntersectionObserversupport and documentation. - Added CSS
outline, its width/style/color/offset longhands, browser-style paint ordering, rounded geometry, visual bounds, and clipping behavior. Outlines do not affect layout; unsupported line patterns still fall back to solid and outline transitions are not yet supported. - Added
perspective()transform parsing and projective geometry for perspective backgrounds, with matching visual bounds and pointer-coordinate mapping.
### Changed
- Standardized theme tokens and component conventions, expanded the theme documentation, and replaced individual demo pages with the shared theme preview.
- Removed the old bundled McUI theme. Pages using its resource paths need to migrate; the new Ore theme is available at
apricityui/theme/t01-ore/t01-ore.css. The existing legacy Ore resources are separate from the new standardized theme. - Reduced packaged resource overhead and redundant bundled assets, and updated the embedded English documentation.
### Performance
- Reworked custom-font rendering around reusable glyph caches instead of whole-line bitmaps, reducing repeated rasterization and texture work.
- Reduced redundant layout invalidation: ancestor changes no longer repeatedly clear overlapping descendant trees, position caches validate their geometry dependencies, and refresh-time full-tree clearing handles each node locally.
- Reused compiled selector token patterns, removed exception-based handling of unsupported CSS properties, and avoided repeated font-name-table reads when looking up derived fonts.
- Skipped the redundant final style pass for documents with no applicable NeoForge 1.21.1 expansion work; unknown or changing expanders retain the complete style pass.
- Improved DevTools DOM-tree expansion and scrolling for large child lists, including cached subtree counts and reduced rebuilding.
- Improved repeated-gradient geometry generation and bounded repeat work while retaining color-stop coverage. Added physical-pixel coverage for thin perspective grid bands.
### Fixed
- Corrected browser-parity issues across theme layouts: flex wrapping and anonymous text, positioned flex sizing, absolute static positions and shrink-to-fit text, max-width inline wrapping, input stretching, text transforms, border rendering, rounded zero-blur shadows, and variable-backed background shorthands.
- Fixed repeating-gradient image sizing and phase, clipped gradient
- Added 14 standardized, switchable CSS themes: Ore, Claude Square/Round, CurseForge, Modrinth Light/Dark, Arwes and Arwes Transparent, Neobrutalist, Hand-Drawn Doodle, Retro Vintage, Vaporwave, Impressionist Oil, and Mecha.
apricityui/theme/t00-example.htmlpreviews the same component markup across themes and loads theme stylesheets on demand. - Added the self-contained
<theme-switcher>floating control, with runtime stylesheet loading, theme scope management, andaui-theme-changenotifications. - Added
IntersectionObserversupport and documentation. - Added CSS
outline, its width/style/color/offset longhands, browser-style paint ordering, rounded geometry, visual bounds, and clipping behavior. Outlines do not affect layout; unsupported line patterns still fall back to solid and outline transitions are not yet supported. - Added
perspective()transform parsing and projective geometry for perspective backgrounds, with matching visual bounds and pointer-coordinate mapping.
### Changed
- Standardized theme tokens and component conventions, expanded the theme documentation, and replaced individual demo pages with the shared theme preview.
- Removed the old bundled McUI theme. Pages using its resource paths need to migrate; the new Ore theme is available at
apricityui/theme/t01-ore/t01-ore.css. The existing legacy Ore resources are separate from the new standardized theme. - Reduced packaged resource overhead and redundant bundled assets, and updated the embedded English documentation.
### Performance
- Reworked custom-font rendering around reusable glyph caches instead of whole-line bitmaps, reducing repeated rasterization and texture work.
- Reduced redundant layout invalidation: ancestor changes no longer repeatedly clear overlapping descendant trees, position caches validate their geometry dependencies, and refresh-time full-tree clearing handles each node locally.
- Reused compiled selector token patterns, removed exception-based handling of unsupported CSS properties, and avoided repeated font-name-table reads when looking up derived fonts.
- Skipped the redundant final style pass for documents with no applicable NeoForge 1.21.1 expansion work; unknown or changing expanders retain the complete style pass.
- Improved DevTools DOM-tree expansion and scrolling for large child lists, including cached subtree counts and reduced rebuilding.
- Improved repeated-gradient geometry generation and bounded repeat work while retaining color-stop coverage. Added physical-pixel coverage for thin perspective grid bands.
### Fixed
- Corrected browser-parity issues across theme layouts: flex wrapping and anonymous text, positioned flex sizing, absolute static positions and shrink-to-fit text, max-width inline wrapping, input stretching, text transforms, border rendering, rounded zero-blur shadows, and variable-backed background shorthands.
- Fixed repeating-gradient image sizing and phase, clipped gradient
- Added 14 standardized, switchable CSS themes: Ore, Claude Square/Round, CurseForge, Modrinth Light/Dark, Arwes and Arwes Transparent, Neobrutalist, Hand-Drawn Doodle, Retro Vintage, Vaporwave, Impressionist Oil, and Mecha.
apricityui/theme/t00-example.htmlpreviews the same component markup across themes and loads theme stylesheets on demand. - Added the self-contained
<theme-switcher>floating control, with runtime stylesheet loading, theme scope management, andaui-theme-changenotifications. - Added
IntersectionObserversupport and documentation. - Added CSS
outline, its width/style/color/offset longhands, browser-style paint ordering, rounded geometry, visual bounds, and clipping behavior. Outlines do not affect layout; unsupported line patterns still fall back to solid and outline transitions are not yet supported. - Added
perspective()transform parsing and projective geometry for perspective backgrounds, with matching visual bounds and pointer-coordinate mapping.
### Changed
- Standardized theme tokens and component conventions, expanded the theme documentation, and replaced individual demo pages with the shared theme preview.
- Removed the old bundled McUI theme. Pages using its resource paths need to migrate; the new Ore theme is available at
apricityui/theme/t01-ore/t01-ore.css. The existing legacy Ore resources are separate from the new standardized theme. - Reduced packaged resource overhead and redundant bundled assets, and updated the embedded English documentation.
### Performance
- Reworked custom-font rendering around reusable glyph caches instead of whole-line bitmaps, reducing repeated rasterization and texture work.
- Reduced redundant layout invalidation: ancestor changes no longer repeatedly clear overlapping descendant trees, position caches validate their geometry dependencies, and refresh-time full-tree clearing handles each node locally.
- Reused compiled selector token patterns, removed exception-based handling of unsupported CSS properties, and avoided repeated font-name-table reads when looking up derived fonts.
- Skipped the redundant final style pass for documents with no applicable NeoForge 1.21.1 expansion work; unknown or changing expanders retain the complete style pass.
- Improved DevTools DOM-tree expansion and scrolling for large child lists, including cached subtree counts and reduced rebuilding.
- Improved repeated-gradient geometry generation and bounded repeat work while retaining color-stop coverage. Added physical-pixel coverage for thin perspective grid bands.
### Fixed
- Corrected browser-parity issues across theme layouts: flex wrapping and anonymous text, positioned flex sizing, absolute static positions and shrink-to-fit text, max-width inline wrapping, input stretching, text transforms, border rendering, rounded zero-blur shadows, and variable-backed background shorthands.
- Fixed repeating-gradient image sizing and phase, clipped gradient
- Added 14 standardized, switchable CSS themes: Ore, Claude Square/Round, CurseForge, Modrinth Light/Dark, Arwes and Arwes Transparent, Neobrutalist, Hand-Drawn Doodle, Retro Vintage, Vaporwave, Impressionist Oil, and Mecha.
apricityui/theme/t00-example.htmlpreviews the same component markup across themes and loads theme stylesheets on demand. - Added the self-contained
<theme-switcher>floating control, with runtime stylesheet loading, theme scope management, andaui-theme-changenotifications. - Added
IntersectionObserversupport and documentation. - Added CSS
outline, its width/style/color/offset longhands, browser-style paint ordering, rounded geometry, visual bounds, and clipping behavior. Outlines do not affect layout; unsupported line patterns still fall back to solid and outline transitions are not yet supported. - Added
perspective()transform parsing and projective geometry for perspective backgrounds, with matching visual bounds and pointer-coordinate mapping.
### Changed
- Standardized theme tokens and component conventions, expanded the theme documentation, and replaced individual demo pages with the shared theme preview.
- Removed the old bundled McUI theme. Pages using its resource paths need to migrate; the new Ore theme is available at
apricityui/theme/t01-ore/t01-ore.css. The existing legacy Ore resources are separate from the new standardized theme. - Reduced packaged resource overhead and redundant bundled assets, and updated the embedded English documentation.
### Performance
- Reworked custom-font rendering around reusable glyph caches instead of whole-line bitmaps, reducing repeated rasterization and texture work.
- Reduced redundant layout invalidation: ancestor changes no longer repeatedly clear overlapping descendant trees, position caches validate their geometry dependencies, and refresh-time full-tree clearing handles each node locally.
- Reused compiled selector token patterns, removed exception-based handling of unsupported CSS properties, and avoided repeated font-name-table reads when looking up derived fonts.
- Skipped the redundant final style pass for documents with no applicable NeoForge 1.21.1 expansion work; unknown or changing expanders retain the complete style pass.
- Improved DevTools DOM-tree expansion and scrolling for large child lists, including cached subtree counts and reduced rebuilding.
- Improved repeated-gradient geometry generation and bounded repeat work while retaining color-stop coverage. Added physical-pixel coverage for thin perspective grid bands.
### Fixed
- Corrected browser-parity issues across theme layouts: flex wrapping and anonymous text, positioned flex sizing, absolute static positions and shrink-to-fit text, max-width inline wrapping, input stretching, text transforms, border rendering, rounded zero-blur shadows, and variable-backed background shorthands.
- Fixed repeating-gradient image sizing and phase, clipped gradient
### Added
- Layout metrics are typed values now, not strings.
layout/CssLengthparses a CSS length once (leading-number scan,calc()/min()/max()/clamp(), unit conversion) and resolves it on demand, so the layout pass no longer re-parseswidth/height/min-*/max-*/flex-basisor thebox-sizingkeyword on every visit;Stylegains lazy accessors (widthLength(),isBorderBox(), …) that compile at computed-style time and are invalidated onclone()/copyFrom()so animation buffers cannot read the previous frame's geometry.Size's public API now delegates toCssLength, which keeps the two implementations from drifting apart. overflowandvisibilitynormalize to theInteraction.Overflow/Interaction.Visibilityenums, anddisplay/overflowquestions are answered by memoizedStyleaccessors (isFlexDisplay(),isGridDisplay(),isInFlow(),clipsOverflow(), …) instead oftrim()+toLowerCase()on every call. Only the memoized form changed:Layout.isInFlowandInteraction.isDisplayedkeep their exact-match semantics, whileisFlexDisplay/isGridDisplaystay case-insensitive, as before.- The first full geometry commit of a document can be sliced across frames. A page whose initial commit would block one frame for hundreds of milliseconds now pays a per-frame budget instead (
initialCommitSliceEnabled,initialCommitSliceMs, default 16 ms), and the document is not painted until its geometry is complete.-Dapricityui.layout.sliceInitialCommit=falserestores the single-shot commit. Small documents and non-render callers (the tick path, hit testing) keep committing synchronously, because they rely oncommit()returning with complete geometry. ApricityUI.ensureDocument(path)returns the existing document for a path or creates one, so callers no longer have to testDocument.get(path)themselves.
### Changed
ApricityUI.createDocument(path)now marks the document reload-persistent, which is what lets a document created from a screen survive a resource reload and open as an overlay.Document.create(path)is unchanged.- Debug log volume is down substantially. The per-draw font warnings ("blank text draw", which fired once per line that had not been rasterized yet) are capped at 8 per process instead of 1200, and no longer embed the full raster cache key.
CanvasImageSupport's per-draw warnings are de-duplicated per resource, so a broken image logs once rather than every frame. Leftover commented-out log blocks, a deadImage.loadTextureoverload, the unreachableQwenHtmlOverlayDebugclass and one repeated failure log in each ofStyleAsyncHandlerandNetworkAsyncHandlerare gone; a number of per-eventINFOlines ([AUI Screen],[AUI Viewport],NetworkUtilchunking, Fabric network registration) moved toDEBUG.
### Fixed
- Buttons in the Ore and McUI themes no longer grow taller while pressed.
.button:activecarried hardcoded `padding-top: 9px; pa
### Added
- Layout metrics are typed values now, not strings.
layout/CssLengthparses a CSS length once (leading-number scan,calc()/min()/max()/clamp(), unit conversion) and resolves it on demand, so the layout pass no longer re-parseswidth/height/min-*/max-*/flex-basisor thebox-sizingkeyword on every visit;Stylegains lazy accessors (widthLength(),isBorderBox(), …) that compile at computed-style time and are invalidated onclone()/copyFrom()so animation buffers cannot read the previous frame's geometry.Size's public API now delegates toCssLength, which keeps the two implementations from drifting apart. overflowandvisibilitynormalize to theInteraction.Overflow/Interaction.Visibilityenums, anddisplay/overflowquestions are answered by memoizedStyleaccessors (isFlexDisplay(),isGridDisplay(),isInFlow(),clipsOverflow(), …) instead oftrim()+toLowerCase()on every call. Only the memoized form changed:Layout.isInFlowandInteraction.isDisplayedkeep their exact-match semantics, whileisFlexDisplay/isGridDisplaystay case-insensitive, as before.- The first full geometry commit of a document can be sliced across frames. A page whose initial commit would block one frame for hundreds of milliseconds now pays a per-frame budget instead (
initialCommitSliceEnabled,initialCommitSliceMs, default 16 ms), and the document is not painted until its geometry is complete.-Dapricityui.layout.sliceInitialCommit=falserestores the single-shot commit. Small documents and non-render callers (the tick path, hit testing) keep committing synchronously, because they rely oncommit()returning with complete geometry. ApricityUI.ensureDocument(path)returns the existing document for a path or creates one, so callers no longer have to testDocument.get(path)themselves.
### Changed
ApricityUI.createDocument(path)now marks the document reload-persistent, which is what lets a document created from a screen survive a resource reload and open as an overlay.Document.create(path)is unchanged.- Debug log volume is down substantially. The per-draw font warnings ("blank text draw", which fired once per line that had not been rasterized yet) are capped at 8 per process instead of 1200, and no longer embed the full raster cache key.
CanvasImageSupport's per-draw warnings are de-duplicated per resource, so a broken image logs once rather than every frame. Leftover commented-out log blocks, a deadImage.loadTextureoverload, the unreachableQwenHtmlOverlayDebugclass and one repeated failure log in each ofStyleAsyncHandlerandNetworkAsyncHandlerare gone; a number of per-eventINFOlines ([AUI Screen],[AUI Viewport],NetworkUtilchunking, Fabric network registration) moved toDEBUG.
### Fixed
- Buttons in the Ore and McUI themes no longer grow taller while pressed.
.button:activecarried hardcoded `padding-top: 9px; pa
### Added
- Layout metrics are typed values now, not strings.
layout/CssLengthparses a CSS length once (leading-number scan,calc()/min()/max()/clamp(), unit conversion) and resolves it on demand, so the layout pass no longer re-parseswidth/height/min-*/max-*/flex-basisor thebox-sizingkeyword on every visit;Stylegains lazy accessors (widthLength(),isBorderBox(), …) that compile at computed-style time and are invalidated onclone()/copyFrom()so animation buffers cannot read the previous frame's geometry.Size's public API now delegates toCssLength, which keeps the two implementations from drifting apart. overflowandvisibilitynormalize to theInteraction.Overflow/Interaction.Visibilityenums, anddisplay/overflowquestions are answered by memoizedStyleaccessors (isFlexDisplay(),isGridDisplay(),isInFlow(),clipsOverflow(), …) instead oftrim()+toLowerCase()on every call. Only the memoized form changed:Layout.isInFlowandInteraction.isDisplayedkeep their exact-match semantics, whileisFlexDisplay/isGridDisplaystay case-insensitive, as before.- The first full geometry commit of a document can be sliced across frames. A page whose initial commit would block one frame for hundreds of milliseconds now pays a per-frame budget instead (
initialCommitSliceEnabled,initialCommitSliceMs, default 16 ms), and the document is not painted until its geometry is complete.-Dapricityui.layout.sliceInitialCommit=falserestores the single-shot commit. Small documents and non-render callers (the tick path, hit testing) keep committing synchronously, because they rely oncommit()returning with complete geometry. ApricityUI.ensureDocument(path)returns the existing document for a path or creates one, so callers no longer have to testDocument.get(path)themselves.
### Changed
ApricityUI.createDocument(path)now marks the document reload-persistent, which is what lets a document created from a screen survive a resource reload and open as an overlay.Document.create(path)is unchanged.- Debug log volume is down substantially. The per-draw font warnings ("blank text draw", which fired once per line that had not been rasterized yet) are capped at 8 per process instead of 1200, and no longer embed the full raster cache key.
CanvasImageSupport's per-draw warnings are de-duplicated per resource, so a broken image logs once rather than every frame. Leftover commented-out log blocks, a deadImage.loadTextureoverload, the unreachableQwenHtmlOverlayDebugclass and one repeated failure log in each ofStyleAsyncHandlerandNetworkAsyncHandlerare gone; a number of per-eventINFOlines ([AUI Screen],[AUI Viewport],NetworkUtilchunking, Fabric network registration) moved toDEBUG.
### Fixed
- Buttons in the Ore and McUI themes no longer grow taller while pressed.
.button:activecarried hardcoded `padding-top: 9px; pa
### Added
- Layout metrics are typed values now, not strings.
layout/CssLengthparses a CSS length once (leading-number scan,calc()/min()/max()/clamp(), unit conversion) and resolves it on demand, so the layout pass no longer re-parseswidth/height/min-*/max-*/flex-basisor thebox-sizingkeyword on every visit;Stylegains lazy accessors (widthLength(),isBorderBox(), …) that compile at computed-style time and are invalidated onclone()/copyFrom()so animation buffers cannot read the previous frame's geometry.Size's public API now delegates toCssLength, which keeps the two implementations from drifting apart. overflowandvisibilitynormalize to theInteraction.Overflow/Interaction.Visibilityenums, anddisplay/overflowquestions are answered by memoizedStyleaccessors (isFlexDisplay(),isGridDisplay(),isInFlow(),clipsOverflow(), …) instead oftrim()+toLowerCase()on every call. Only the memoized form changed:Layout.isInFlowandInteraction.isDisplayedkeep their exact-match semantics, whileisFlexDisplay/isGridDisplaystay case-insensitive, as before.- The first full geometry commit of a document can be sliced across frames. A page whose initial commit would block one frame for hundreds of milliseconds now pays a per-frame budget instead (
initialCommitSliceEnabled,initialCommitSliceMs, default 16 ms), and the document is not painted until its geometry is complete.-Dapricityui.layout.sliceInitialCommit=falserestores the single-shot commit. Small documents and non-render callers (the tick path, hit testing) keep committing synchronously, because they rely oncommit()returning with complete geometry. ApricityUI.ensureDocument(path)returns the existing document for a path or creates one, so callers no longer have to testDocument.get(path)themselves.
### Changed
ApricityUI.createDocument(path)now marks the document reload-persistent, which is what lets a document created from a screen survive a resource reload and open as an overlay.Document.create(path)is unchanged.- Debug log volume is down substantially. The per-draw font warnings ("blank text draw", which fired once per line that had not been rasterized yet) are capped at 8 per process instead of 1200, and no longer embed the full raster cache key.
CanvasImageSupport's per-draw warnings are de-duplicated per resource, so a broken image logs once rather than every frame. Leftover commented-out log blocks, a deadImage.loadTextureoverload, the unreachableQwenHtmlOverlayDebugclass and one repeated failure log in each ofStyleAsyncHandlerandNetworkAsyncHandlerare gone; a number of per-eventINFOlines ([AUI Screen],[AUI Viewport],NetworkUtilchunking, Fabric network registration) moved toDEBUG.
### Fixed
- Buttons in the Ore and McUI themes no longer grow taller while pressed.
.button:activecarried hardcoded `padding-top: 9px; pa
### Added
- Layout metrics are typed values now, not strings.
layout/CssLengthparses a CSS length once (leading-number scan,calc()/min()/max()/clamp(), unit conversion) and resolves it on demand, so the layout pass no longer re-parseswidth/height/min-*/max-*/flex-basisor thebox-sizingkeyword on every visit;Stylegains lazy accessors (widthLength(),isBorderBox(), …) that compile at computed-style time and are invalidated onclone()/copyFrom()so animation buffers cannot read the previous frame's geometry.Size's public API now delegates toCssLength, which keeps the two implementations from drifting apart. overflowandvisibilitynormalize to theInteraction.Overflow/Interaction.Visibilityenums, anddisplay/overflowquestions are answered by memoizedStyleaccessors (isFlexDisplay(),isGridDisplay(),isInFlow(),clipsOverflow(), …) instead oftrim()+toLowerCase()on every call. Only the memoized form changed:Layout.isInFlowandInteraction.isDisplayedkeep their exact-match semantics, whileisFlexDisplay/isGridDisplaystay case-insensitive, as before.- The first full geometry commit of a document can be sliced across frames. A page whose initial commit would block one frame for hundreds of milliseconds now pays a per-frame budget instead (
initialCommitSliceEnabled,initialCommitSliceMs, default 16 ms), and the document is not painted until its geometry is complete.-Dapricityui.layout.sliceInitialCommit=falserestores the single-shot commit. Small documents and non-render callers (the tick path, hit testing) keep committing synchronously, because they rely oncommit()returning with complete geometry. ApricityUI.ensureDocument(path)returns the existing document for a path or creates one, so callers no longer have to testDocument.get(path)themselves.
### Changed
ApricityUI.createDocument(path)now marks the document reload-persistent, which is what lets a document created from a screen survive a resource reload and open as an overlay.Document.create(path)is unchanged.- Debug log volume is down substantially. The per-draw font warnings ("blank text draw", which fired once per line that had not been rasterized yet) are capped at 8 per process instead of 1200, and no longer embed the full raster cache key.
CanvasImageSupport's per-draw warnings are de-duplicated per resource, so a broken image logs once rather than every frame. Leftover commented-out log blocks, a deadImage.loadTextureoverload, the unreachableQwenHtmlOverlayDebugclass and one repeated failure log in each ofStyleAsyncHandlerandNetworkAsyncHandlerare gone; a number of per-eventINFOlines ([AUI Screen],[AUI Viewport],NetworkUtilchunking, Fabric network registration) moved toDEBUG.
### Fixed
- Buttons in the Ore and McUI themes no longer grow taller while pressed.
.button:activecarried hardcoded `padding-top: 9px; pa
### Added
- Layout metrics are typed values now, not strings.
layout/CssLengthparses a CSS length once (leading-number scan,calc()/min()/max()/clamp(), unit conversion) and resolves it on demand, so the layout pass no longer re-parseswidth/height/min-*/max-*/flex-basisor thebox-sizingkeyword on every visit;Stylegains lazy accessors (widthLength(),isBorderBox(), …) that compile at computed-style time and are invalidated onclone()/copyFrom()so animation buffers cannot read the previous frame's geometry.Size's public API now delegates toCssLength, which keeps the two implementations from drifting apart. overflowandvisibilitynormalize to theInteraction.Overflow/Interaction.Visibilityenums, anddisplay/overflowquestions are answered by memoizedStyleaccessors (isFlexDisplay(),isGridDisplay(),isInFlow(),clipsOverflow(), …) instead oftrim()+toLowerCase()on every call. Only the memoized form changed:Layout.isInFlowandInteraction.isDisplayedkeep their exact-match semantics, whileisFlexDisplay/isGridDisplaystay case-insensitive, as before.- The first full geometry commit of a document can be sliced across frames. A page whose initial commit would block one frame for hundreds of milliseconds now pays a per-frame budget instead (
initialCommitSliceEnabled,initialCommitSliceMs, default 16 ms), and the document is not painted until its geometry is complete.-Dapricityui.layout.sliceInitialCommit=falserestores the single-shot commit. Small documents and non-render callers (the tick path, hit testing) keep committing synchronously, because they rely oncommit()returning with complete geometry. ApricityUI.ensureDocument(path)returns the existing document for a path or creates one, so callers no longer have to testDocument.get(path)themselves.
### Changed
ApricityUI.createDocument(path)now marks the document reload-persistent, which is what lets a document created from a screen survive a resource reload and open as an overlay.Document.create(path)is unchanged.- Debug log volume is down substantially. The per-draw font warnings ("blank text draw", which fired once per line that had not been rasterized yet) are capped at 8 per process instead of 1200, and no longer embed the full raster cache key.
CanvasImageSupport's per-draw warnings are de-duplicated per resource, so a broken image logs once rather than every frame. Leftover commented-out log blocks, a deadImage.loadTextureoverload, the unreachableQwenHtmlOverlayDebugclass and one repeated failure log in each ofStyleAsyncHandlerandNetworkAsyncHandlerare gone; a number of per-eventINFOlines ([AUI Screen],[AUI Viewport],NetworkUtilchunking, Fabric network registration) moved toDEBUG.
### Fixed
- Buttons in the Ore and McUI themes no longer grow taller while pressed.
.button:activecarried hardcoded `padding-top: 9px; pa
