@public-ui/mcp 4.5.0-rc.5 → 4.5.0-rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@public-ui/mcp",
3
- "version": "4.5.0-rc.5",
3
+ "version": "4.5.0-rc.6",
4
4
  "license": "EUPL-1.2",
5
5
  "homepage": "https://public-ui.github.io",
6
6
  "repository": {
@@ -48,7 +48,7 @@
48
48
  "glob": "13.0.6",
49
49
  "simple-git": "3.36.0",
50
50
  "zod": "4.6.5",
51
- "@public-ui/components": "4.5.0-rc.5"
51
+ "@public-ui/components": "4.5.0-rc.6"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@modelcontextprotocol/inspector": "2.9.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "metadata": {
3
- "generatedAt": "2026-10-06T13:52:06.167Z",
3
+ "generatedAt": "2026-10-07T08:09:41.785Z",
4
4
  "buildMode": "ci",
5
5
  "counts": {
6
6
  "total": 341,
@@ -10,7 +10,7 @@
10
10
  "totalScenarios": 20
11
11
  },
12
12
  "repo": {
13
- "commit": "c8c411be1b515cc1f67263845b66a987ce27b5d4",
13
+ "commit": "33f8ab49f2f0be6915e1eb90adea65766fec04f8",
14
14
  "branch": "develop",
15
15
  "repoUrl": "https://github.com/public-ui/kolibri"
16
16
  }
@@ -21,7 +21,7 @@
21
21
  "group": "docs",
22
22
  "name": "AGENTS",
23
23
  "path": "AGENTS.md",
24
- "code": "# Agent Instructions\n\nThis repository is a monorepo managed with **pnpm** and **Nx**. It contains multiple packages under `packages/` such as web components, themes, adapters, samples and tooling.\n\n## Handling hints\n\nWe have a monorepo structure with multiple packages, each with its own `package.json`. The root `package.json` contains shared dependencies and scripts. Use `pnpm` commands to manage dependencies and run scripts across packages.\n\n- To install dependencies, use `pnpm i` at the root level. This will install all dependencies for all packages.\n- If you change a dependency in a package:\n - Use only exact version numbers in `package.json`. Other peers will not be able to use the package if you can use a range version.\n - You need to run `pnpm i` at the root level. This updates the lockfile and ensures all packages are using the correct versions.\n- Never add a `packageManager` field to any `package.json` file.\n- Avoid that branch name may contain hidden characters.\n- Development workflow: `git pull` → `pnpm i` → `pnpm -r build` → `pnpm dev` only in the packages being changed → work on the code. No `dev` or `preview` script builds dependencies. Never run a build while a watcher is active, the components build clears the watcher's output. See [CONTRIBUTING.md](CONTRIBUTING.md#daily-workflow).\n- If something does not work, check in the event of an error whether all dependent submodules have been built.\n- To build a single package faster, run commands with downstream dependents using `pnpm --filter ...<package>` (e.g., `pnpm --filter ...@public-ui/sample-react build`). A package's build never builds another package: `pnpm -r build` builds each package exactly once in topological order. Build a package together with its dependencies using `pnpm --filter <package>... build` (e.g. components, which needs the kolicons font from `@public-ui/icons`).\n\n## 🚨 Format-first rule\n\n> **Stop before you commit:** run the formatter so CI never rejects your patch for style drift.\n\n1. Run `pnpm format` from the repo root whenever you change code, docs or configs.\n2. If you only touched one package, you may instead run `pnpm --filter <package> format` for a quicker pass.\n3. Re-stage the affected files (`git add -u`) so the formatted result is what lands in the commit.\n\nNo package scripts in this repo need extra flags such as `-- --write`; the scripts already know when to write changes versus just check.\n\n## Semantic Versioning\n\nThis repository follows **Semantic Versioning** (SemVer) for all packages. Each package version is defined in its own `package.json` file. The versioning scheme is as follows:\n\n- **Major version**: Incremented for incompatible API changes.\n- **Minor version**: Incremented for adding functionality in a backwards-compatible manner.\n- **Patch version**: Incremented for backwards-compatible bug fixes.\n\nThe public API of a component is its props, methods, events, slots and exported types, including their behaviour. Its internal DOM structure and the BEM classes on it are a **theming contract** instead: changing them is a **theming breaking change**, not a hard breaking change. It ships in at least a minor release, carries the label `release:theming` (changelog section _Theming_), lists the old and new classes in the pull request and adapts all themes of this repository in the same change. Theme authors adapt their themes through their own visual snapshots and the zero-visual-delta workflow. See [Theming Contract](packages/components/src/components/_skeleton/ARC42.md#theming-contract-shadow-dom-structure-and-bem-classes).\n\nIf we deprecate a feature, we will mark it as deprecated in the code and documentation, but we will not remove it immediately. Instead, we will provide a migration guide (migration\\*.md) for users to transition to the new feature. Also we provide a migration tool in the `packages/tools/kolibri-cli` package to help with the migration process. You have to add a migration task from the previous version to the new version in the `packages/tools/kolibri-cli/src/migrations` folder. In the migration package, are a lot of migration tasks already implemented, so you can use them as a reference.\n\n## Project Structure\n\n- `packages/components` – Stencil based web components\n - `packages/components/src/component` – components\n - `packages/components/src/schema` – schema definitions for all components\n- `packages/samples` – sample applications demonstrating usage\n - `packages/samples/angular` – Angular sample app; do not edit\n - `packages/samples/react` – React sample app; all samples; write component samples here\n- `packages/adapters/*` – generated framework integration packages; do not edit\n- `packages/themes` – style themes and assets\n - `packages/themes/default` – primary maintained standard theme\n - All other themes are not actively maintained\n- `packages/tools/kolibri-cli` – helper CLI for migration\n- Documentation lives in `docs/`.\n- `kol-tooltip-wc` (`packages/components/src/components/tooltip/component.tsx`) is the only `-wc` web component (`shadow: false`). It stays deprecated and is kept only for DESYBRI: do not remove, migrate or replace it, and do not use it in new code. Every other component that embeds another one renders that component's functional component through an item (see the skeleton ARC42, _Embedded Components (Items)_).\n- Do always ignore and do not edit all `assets` folders in all packages, as these are generated by the build process and should not be edited manually. If you need to change something in the assets, you have to change it in the source code and rebuild the package.\n\n## Theming\n\nThe theming is realized with adopted style sheets on web components and will be adopted at the mounted hook of the components. All following styling rules are only relevant for the `components` and `themes` packages.\n\n### The 5 styling layers\n\n1. **A11y Preset layer**: This layer comes out of the `adopted-style-sheets` package and contains the basic styles for accessibility. It is applied to all components.\n2. **Basis Global layer**: This layer contains the basis global styles for all components and comes out of the `@public-ui/components` package. It is applied only component specific layout styles without margins and paddings. Generally, the styling works without colors, as the colors should only be set through the custom Theme Layer. It never contains a color scheme (dark/light).\n3. **Basis Component layer**: This layer contains the basis styles for one component and comes out of the `@public-ui/components` package. It is applied only component specific layout styles without margins and paddings. Generally, the styling works without colors, as the colors should only be set through the custom Theme Layer. It never contains a color scheme (dark/light).\n4. **Theme Global layer**: This layer contains the global styles for all components of a theme and comes out of a own theme package, like `@public-ui/theme-default`. Color schemes (dark/light) are defined here via theme tokens.\n5. **Theme Component layer**: This layer contains the component specific styles for one component of a theme and comes out of a own theme package, like `@public-ui/theme-default`.\n\n> **Base styling vs. theming — dark/light lives in the theme.** The base styling of the components package (layers 1–3) is responsible for layout and structure only. It knows no dark/light color scheme: no `prefers-color-scheme`, no `color-scheme`, no `light-dark()`, no scheme tokens. Black and white in the base layers are a contrast fallback, not a color design. Dark/light theming is anchored and implemented exclusively in the theme packages (layers 4–5). See [`docs/BASE_STYLING_VS_THEMING_CONCEPT.md`](docs/BASE_STYLING_VS_THEMING_CONCEPT.md).\n\n### Global accessibility styles\n\n```css\n/*\n * This file contains all rules for accessibility.\n */\n@layer kol-global {\n\t:host {\n\t\t/*\n\t\t * Minimum size of interactive elements.\n\t\t */\n\t\t--a11y-min-size: #{rem(44)};\n\t\t/*\n\t\t * No element should be used without a background and font color whose contrast ratio has\n\t\t * not been checked. By initially setting the background color to white and the font color\n\t\t * to black, the contrast ratio is ensured and explicit adjustment is forced.\n\t\t */\n\t\tbackground-color: white;\n\t\tcolor: black;\n\t}\n\n\t* {\n\t\t/*\n\t\t * This rule enables the word dividing for all texts. That is important for high zoom levels.\n\t\t */\n\t\thyphens: auto;\n\t\t/*\n\t\t * Verdana is an accessible font that can be used without requiring additional loading time.\n\t\t */\n\t\tfont-family: Verdana;\n\t\t/*\n\t\t * Letter spacing is required for all texts.\n\t\t */\n\t\tletter-spacing: inherit;\n\t\t/*\n\t\t * This rule enables the word dividing for all texts. That is important for high zoom levels.\n\t\t */\n\t\tword-break: break-word;\n\t\t/*\n\t\t * Word spacing is required for all texts.\n\t\t */\n\t\tword-spacing: inherit;\n\t}\n\n\t/*\n\t * All interactive elements should have a minimum size of rem(44).\n\t */\n\t/* input:not([type='checkbox'], [type='radio'], [type='range']), */\n\t/* option, */\n\t/* select, */\n\t/* textarea, */\n\t[role='button'],\n\tbutton:not([role='link']),\n\t.kol-input .input {\n\t\tmin-height: var(--a11y-min-size);\n\t\tmin-width: var(--a11y-min-size);\n\t}\n\n\t/*\n\t * Some interactive elements should not inherit the font-family and font-size.\n\t */\n\ta,\n\tbutton,\n\th1,\n\th2,\n\th3,\n\th4,\n\th5,\n\th6,\n\tinput,\n\toption,\n\tselect,\n\ttextarea {\n\t\t/*\n\t\t * All elements should inherit the font family from his parent element.\n\t\t */\n\t\tfont-family: inherit;\n\t\t/*\n\t\t * All elements should inherit the font size from his parent element.\n\t\t */\n\t\tfont-size: inherit;\n\t}\n}\n\n/**\n * Sometimes we need the semantic element for accessibility reasons,\n * but we don't want to show it.\n *\n * - https://www.a11yproject.com/posts/how-to-hide-content/\n */\n.visually-hidden {\n\tclip: rect(0 0 0 0);\n\tclip-path: inset(50%);\n\theight: 1px;\n\toverflow: hidden;\n\tposition: absolute;\n\twhite-space: nowrap;\n\twidth: 1px;\n}\n```\n\n### Styling rules\n\nThe basis global layer set the default font-size and box-sizing for all components.\n\n```css\n@layer kol-global {\n\t:host {\n\t\tfont-size: rem(16);\n\t\t/*\n\t\t * The max-width is needed to prevent the table from overflowing the\n\t\t * parent node, if the table is wider than the parent node.\n\t\t */\n\t\tmax-width: 100%;\n\t}\n\n\t* {\n\t\t/*\n\t\t * We prefer to box-sizing: border-box for all elements.\n\t\t */\n\t\tbox-sizing: border-box;\n\t}\n ...\n}\n```\n\n### Custom Theming rules\n\nThe custom theme layer is used to set the colors and other theme specific styles. The custom theme layer should not contain any layout styles, as these are already set in the basis global and component layers.\n\nDark/light color schemes are implemented in the theme layers only. Define all colors that differ between light and dark as tokens on `:host` in the theme global layer and switch the scheme there (`color-scheme` + `light-dark()`, `@media (prefers-color-scheme: dark)`, or an opt-in attribute). The theme component layer only references those tokens and never contains its own scheme media queries. Alternatively, a theme may ship a separate dark export that is registered as an additional theme and switched via the `kol-theme` attribute. The base styling of the components package must never be involved in this.\n\nFor example, generally the font-family is set in the theme global layer, on the `:host` element, so that all components inherit the font-family from the theme. The font-size is set in the basis global layer, so that all components inherit the font-size from the basis global layer. But it is possible to set a other base font-size in the theme global layer, if needed.\n\n```css\n@layer kol-theme-global {\n\t:host {\n\t\t--font-family: var(--kolibri-font-family, Verdana, Arial, Calibri, Helvetica, sans-serif);\n\t\t--font-size: var(--kolibri-font-size, #{rem(16)});\n ...\n\t}\n\n\t:host {\n\t\tfont-size: var(--font-size);\n\n\t\t* {\n\t\t\tfont-family: var(--font-family);\n\t\t}\n\t}\n ...\n}\n```\n\nIn the theme component layer, you can set what ever you need to realize your own custom style guidelines. For example, you can set the colors, borders, shadows, etc. for the component.\n\n```css\n@layer kol-theme-component {\n ...\n}\n```\n\n### Color schemes\n\nA theme carries one palette per color scheme in a single declaration, resolved by the CSS\n`light-dark()` function:\n\n```scss\n@layer kol-theme-global {\n\t:host {\n\t\t--color-text: var(--kolibri-color-text, light-dark(#202020, #{$dark-color-text}));\n\t}\n}\n```\n\nRules that hold for every theme:\n\n- **Never declare `color-scheme` in a theme**, and never write `@media (prefers-color-scheme: …)`.\n `color-scheme` is an inherited property and inheritance follows the flat tree, so it crosses the\n shadow boundary on its own: each component resolves `light-dark()` against whatever the consuming\n application has in effect where the component sits. A declaration on `:host` would replace that\n inherited value, and the page and the components in it could then disagree — which is exactly the\n bug this rule exists to prevent.\n- The application owns the scheme, in plain CSS: `:root { color-scheme: light dark }` to follow the\n operating system, `color-scheme: dark` on any element to force a subtree. Consequently an\n application that declares nothing stays light, whatever the operating system says. Dark mode is\n opt-in; `color-scheme.css` in a theme package ships that one line plus the page colors.\n- Sass does not evaluate variables inside `var()`. Interpolate them (`#{$dark-color-text}`).\n- An application stylesheet that uses `light-dark()` must not be downlevelled. A CSS minifier\n targeting older browsers rewrites it into a `prefers-color-scheme` media query with space\n toggles, and that replacement ignores the `color-scheme` property. A theme's CSS is a string\n adopted into the shadow roots at runtime and is never processed by the application's CSS\n pipeline, so the page would follow the operating system while the components follow\n `color-scheme`. Both sample host apps therefore pin `build.cssTarget` in their Vite config.\n- The base layer hardcodes `black` and `white` in a few places. Where it routes them through a\n token, override the token (`--kol-a11y-font-color` / `--kol-a11y-background-color` in `a11y.scss`\n are the sanctioned hook for the host box of every component); elsewhere restate the declaration in\n a theme layer, which sits above `kol-a11y`, `kol-global` and `kol-component`. Keep the light\n branch byte identical to the base value so no light snapshot moves.\n- What a theme layer cannot reach are the color stops of a `@keyframes` rule declared in the base\n layer: an animation's own values win over any normal declaration, whatever the layer. Such a case\n needs a change in `packages/components`.\n- Depth is a surface scale, not a shadow: a lighter surface sits higher. A light palette collapses\n that scale onto white and draws depth with a shadow instead; a dark one carries it in the surfaces\n and replaces the shadow with a hard edge. Since `light-dark()` is a color function and cannot\n switch a `box-shadow` geometry, state both branches at once and switch them by their colors — the\n shadow token transparent in dark mode, the edge token transparent in light mode. A container that\n paints a surface of its own passes it down through `--kol-surface`, which reaches slotted\n components too, so their host box matches the surface they were placed on.\n\n### CSS Custom Properties and SASS Variables\n\nCSS custom properties remain part of the global cascade and are not isolated by the Shadow DOM.\nOverusing them (in theme files as well as in component styles) can collide with variables defined\non a host page, and every custom property you declare is implicitly overridable from outside,\nwhether you intended that or not.\n\n**Prefer plain CSS over a custom property.** Before adding a custom property, check whether the\nplatform already gives the consumer a way to control it — the standard box model (`width`,\n`height`), inherited properties (`color`, `font-size` via `em`), or relative units (`%`, container\nquery units). A component that simply fills its host (`width: 100%; height: 100%` inside, a sane\ndefault `width`/`height` on `:host`) can be resized with plain CSS, exactly like a native element —\nno bespoke API, no documentation burden, nothing to keep in sync. Only reach for a custom property\nwhen the value genuinely cannot be derived this way (e.g. a semantic color token that isn't just\n`currentColor`, or a value with no corresponding native CSS mechanism).\n\n**Rule:** only declare a CSS custom property when it is a deliberate, documented customization\npoint (a `--kol-<component>-<name>` design token). For anything else — internal aliases,\nintermediate values, ratios, or derived defaults — use a SASS `$variable` instead. SASS variables\nare resolved at build time, can't leak into the global cascade, and can't be overridden from a host\npage, so they can't accidentally become part of the public API.\n\nDo not introduce a second, internal custom property just to make the code more readable:\n\n```scss\n// ❌ Bad: `--color-bar` is an unintended, additional public custom property.\n// It reacts to overrides from a host page exactly like `--kol-progress-color-bar`,\n// even though only the latter was meant to be part of the API.\n.kol-progress {\n\t--color-bar: var(--kol-progress-color-bar, #0075ff);\n\n\t&__bar-progress {\n\t\tfill: var(--color-bar);\n\t}\n}\n```\n\n```scss\n// ✅ Good: the SASS variable holds the default value; the only custom property\n// is `--kol-progress-color-bar`, referenced directly wherever needed.\n$kol-progress-default-color-bar: #0075ff;\n\n.kol-progress {\n\t&__bar-progress {\n\t\tfill: var(--kol-progress-color-bar, #{$kol-progress-default-color-bar});\n\t}\n}\n```\n\nAny further unit conversion or math that doesn't depend on a runtime custom property (e.g. `to-rem()`,\nratios, breakpoints) belongs in SASS, not in an extra layer of `calc()`/custom-property indirection.\n\n`kol-avatar` is an example of preferring plain CSS: instead of a `--kol-avatar-size` custom property,\n`:host` gets a default `width` and an `aspect-ratio: 1`, and the inner element derives its size from the\nhost via container query units (`cqw`/`cqh`) instead of a separate ratio calculation. Consumers resize it\nthe same way they'd resize any block-level element — with plain `width`/`height`.\n\nThe avatar must always stay square, even if `width` and `height` end up different (e.g. both are set\nexplicitly to different values), so the inner element uses `max(100cqw, 100cqh)` for both its own `width`\nand `height` — the larger of the two wins, and `:host` centers it (`align-items`/`justify-content`), so it\nmay visually extend beyond the host on the smaller axis. Since CSS can't distinguish \"our default\" from\n\"an explicit author value\" on two independent properties, only setting `width` reliably resizes the avatar\nbelow its 100px default; setting only `height` below 100px does not shrink it, because our own default\n`width` is still in effect and wins the `max()`. This is a deliberate, documented trade-off, not a bug —\nachieving full symmetry would require either a custom property or JavaScript, both of which cost more\nthan the trade-off is worth.\n\n### SCSS Architecture Guidelines: BEM with Smart Nesting\n\nWhen writing component theme styles, follow these principles for clean, maintainable SCSS:\n\n#### 1. **Flat BEM Structure (Root Level)**\n\nAll BEM modifiers and independent elements belong at **root level** of the mixin. Never nest BEM class names:\n\n```scss\n@mixin kol-alert-theme {\n\t// ✅ All BEM selectors on root (flat)\n\t.kol-alert { ... }\n\t.kol-alert--variant-msg { ... }\n\t.kol-alert--variant-card { ... }\n\t.kol-alert--type-default { ... }\n\t.kol-alert__container { ... }\n\t.kol-alert__heading { ... }\n}\n```\n\n**Why?** BEM classnames are independent selectors. Each class should be predictable and flat.\n\n#### 2. **Contextual Nesting (When Variants Change Element Behavior)**\n\nNest **only when a modifier changes how a child element behaves**. Keep all rules for an element together:\n\n```scss\n.kol-alert__closer {\n\tplace-self: center;\n\n\t.kol-button {\n\t\tborder-radius: 50%;\n\t\twidth: var(--a11y-min-size);\n\t\theight: var(--a11y-min-size);\n\t\tcursor: pointer;\n\n\t\t// ✅ Variant changes button styling - nest here\n\t\t.kol-alert--variant-msg & {\n\t\t\t--text-color: var(--alert-accent-color);\n\t\t}\n\n\t\t.kol-alert--variant-card & {\n\t\t\t--text-color: var(--color-light);\n\t\t}\n\t}\n}\n```\n\n**Rule of thumb**: All rules for `.kol-button` in `.kol-alert__closer` stay in one place. This keeps related styles together and makes maintenance easier.\n\n#### 3. **Never Use `$root` or `@at-root`**\n\n❌ **Outdated pattern (removed):**\n\n```scss\n.kol-alert {\n\t$root: &;\n\t&__closer {\n\t\t@at-root #{$root}--variant-msg & { ... }\n\t}\n}\n```\n\n✅ **Modern pattern (direct nesting):**\n\n```scss\n.kol-alert__closer {\n\t.kol-button {\n\t\t.kol-alert--variant-msg & { ... }\n\t}\n}\n```\n\nThis is clearer and doesn't require Sass variable gymnastics.\n\n#### 4. **Structure Template**\n\n```scss\n@mixin kol-component-theme {\n\t// 1. Base component (no children)\n\t.kol-component {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t}\n\n\t// 2. All BEM modifiers at root (flat)\n\t.kol-component--variant-a {\n\t\t...\n\t}\n\n\t.kol-component--type-default {\n\t\t...\n\t}\n\n\t// 3. Elements with contextual nesting for variants\n\t.kol-component__heading {\n\t\tfont-weight: bold;\n\n\t\t.kol-component--variant-a & {\n\t\t\tcolor: red;\n\t\t}\n\t}\n\n\t.kol-component__content {\n\t\tpadding: 1rem;\n\n\t\t.kol-component--variant-a & {\n\t\t\tbackground: white;\n\t\t}\n\t}\n\n\t// 4. Child components with variant context\n\t.kol-component__button {\n\t\t.kol-button {\n\t\t\tcursor: pointer;\n\n\t\t\t.kol-component--variant-a & {\n\t\t\t\t--text-color: var(--accent);\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n### General rules for custom themes\n\n- Do not use `!important` in your styles, as this will override the styles of the basis global and component layers.\n- Do only overwrite styling definitions you will really customize. Do not set styling definitions that are already set (redundant) in the basis global and component layers, as this will override the styles of the basis global and component layers.\n- Do not `inherit` styles over the `:host` element, as this will override the styles of the basis global and component layers. This makes your component less robust from outside environment styles. Only the `kol-icon` inherits some specific styles, like `color`, `font-size`, `font-family` and `line-height`, as these are needed for the icon to be displayed correctly inline to this neighbored elements.\n- Do not set the default `font-family`, `font-size` or `box-sizing` in the basis or theme component layer (redundant), as these are already set in the basis global layers. If you need to set a different font-family or font-size, you can do this in the theme global layer.\n- Do not set `margin` or `padding` in the basis global and component layers. If you need to set a different margin or padding, you can do this in the theme global or component layers.\n- Do not use `@media (prefers-color-scheme: …)`, the `color-scheme` property or the `light-dark()` function in the basis global and component layers. Dark/light color schemes are a theme concern and belong exclusively in the theme global layer (see [`docs/BASE_STYLING_VS_THEMING_CONCEPT.md`](docs/BASE_STYLING_VS_THEMING_CONCEPT.md)). `forced-colors` (high contrast) is a separate accessibility mechanism and stays in the basis `kol-forced-colors` layer.\n- Do not use `overflow: hidden` in styling or theming, as it often causes issues for reuse and should be avoided.\n- **Do not use `@layer` declarations in utility files**: Helper files, mixin files, and partial files (starting with `_`) should not contain `@layer` declarations. These files are utilities and should be layer-agnostic. This is enforced by the custom Stylelint rule `kolibri/no-layer-in-utility-files`.\n- **Never use `$root` variables or `@at-root` in component mixins**: All selectors should be explicit. Use direct child/descendant nesting only when a modifier changes element behavior within a specific context.\n\n## Samples\n\nThe samples are located in `packages/samples/react` and demonstrate how to use the components in react. Each component has its own folder and the basic sample are in `basic.tsx`. Other stories can be added in the same folder. All samples of a component are registered in the `routes.ts` file.\n\n## Coding Conventions\n\n- Formatting is enforced via **Prettier** with settings defined in `prettier.config.js` (print width 160, single quotes, tabs).\n- `.editorconfig` sets `indent_style = tab` and `max_line_length = 160` for code files. Markdown and YAML files use spaces.\n- ESLint and Stylelint are run using `pnpm lint`. Lint rules should **not** be disabled via inline comments. Instead, describe the problem and work towards a clean solution.\n- Lists and enumerations in code should be kept in alphanumeric order. This also applies to import specifiers and union type literals.\n- Do not disable ESLint, Stylelint or TypeScript rules inline. Fix the code instead of turning such rules off.\n- ESLint and Stylelint are run using `pnpm lint`.\n- Lists and enumerations in code should be kept in alphabetical order (see `docs/tutorials/NEW_COMPONENT.md`).\n- Commit messages follow the **Conventional Commits** specification.\n- See also the [Contributing Guide](CONTRIBUTING.md) for more details on coding conventions and best practices.\n- Spell \"KoliBri\" with this casing in all documentation and code. The only exception is the component named KolKolibri.\n- Use ESM import syntax in browser code and scripts whenever supported, instead of `require` imports.\n- Do not create barrel files (e.g. `index.ts` that re-export modules). Import modules directly instead.\n- Do not place constant declarations before import statements; imports must always be at the very top of the file.\n- **Scripts must be platform-independent**: All scripts in the `scripts/` folder must work on Windows, macOS, and Linux without requiring external tools or platform-specific dependencies. Use Node.js built-in modules instead of external command-line tools like `rg`, `grep`, `find`, etc.\n- Inline code documentation follows [Inline code documentation](#inline-code-documentation).\n\n### Inline code documentation\n\nWe encourage inline code documentation (JSDoc in TypeScript/TSX, comments in SCSS and scripts), but only as much as necessary and as little as possible. This rule applies to every new or changed comment; when you touch code, bring the comments of the touched code in line with it.\n\n- **Document what the code cannot say itself**: the purpose of public API (`@Prop`, `@Method`, `@Event`, exported functions and types), constraints, a non-obvious reason (the \"why\") and known limitations.\n- **Do not repeat the code**: no comment that restates a name, a type or the next line. The TypeScript signature is the source of truth, so no `@param {string}` or `@returns {void}` type annotations.\n- **Describe the present and the future, never the past**: state what the code is and does and, where relevant, where it is heading (`@deprecated` with its replacement, a `TODO` with an issue link). Do not write history such as \"previously\", \"changed to\", \"fixed\", \"new:\", and do not refer to the diff, the pull request or a predecessor implementation. History belongs in the commit message, the pull request and the changelog. If an earlier state still matters, state the constraint that follows from it today.\n- **Write for human and AI readers alike**: clear, easy to follow and free of contradictions. One statement per fact, terms named exactly as in the code, no vague wording (\"maybe\", \"somehow\", \"for now\"). A comment never contradicts the code, another comment or the documentation. Update or delete a comment together with the code it describes, and link the authoritative document instead of copying it.\n- **Published API documentation stays stable**: the JSDoc of public `@Prop`, `@Method` and `@Event` members is published (`custom-elements.json`, `docs-vscode`, adapter IntelliSense). Refactorings and migrations keep it unchanged (see [Public API Contract](packages/components/src/components/_skeleton/ARC42.md#public-api-contract-migration-parity)); rewording it is a change of its own.\n\n```ts\n// ❌ Bad: repeats the signature and tells history.\n/**\n * Sets the label.\n * @param {string} value - the label\n * Previously this was handled by the controller; changed in the skeleton migration.\n */\nprivate setLabel(value: string): void {}\n\n// ✅ Good: states the constraint the code cannot express.\n/**\n * Runs before the first render, because the behaviors read the normalized label in `componentWillLoad`.\n */\nprivate setLabel(value: string): void {}\n```\n\n## Linting and Formatting\n\n- Run `pnpm lint` to check for linting errors across all packages. This script runs ESLint, Stylelint and TypeScript checks.\n - ⚠️ **Note**: TypeScript type checking in the lint script can require built artifacts. If you've made source code changes, lint will handle any necessary compilation. Explicit pre-build is typically unnecessary.\n - You can try to automatically fix linting issues with `pnpm lint:eslint --fix`, but this may not resolve all issues.\n- Run `pnpm format` to format all code files using Prettier. You can try to automatically fix linting issues with `pnpm format -w`, but this may not resolve all issues.\n- If your pull request only modifies Markdown files, skip `pnpm build`, `pnpm lint` and `pnpm test`. Just format the Markdown using `pnpm format` or Prettier.\n\n### Pre-commit checklist\n\n- **Always run `pnpm format` (or `pnpm --filter <package> format` for a single workspace) right before committing.** Formatting failures are one of the most common reasons for blocked quality gates, so make this the last step before `git commit` even for documentation-only changes.\n- **For SCSS changes**: Always run `pnpm lint:stylelint --fix` (or `pnpm --filter <package> lint:stylelint --fix`) to automatically correct formatting, property order, and selector structure rules before committing. This ensures compliance with BEM structure and style consistency.\n- After formatting, re-stage affected files with `git add -u` so the formatted content is what gets committed.\n\n## Testing\n\n- Run `pnpm test` from the repository root to execute all unit and integration tests.\n - ⚠️ **Note**: Test runners (Vitest, Jest, Playwright, etc.) execute an implicit build automatically before running tests. **Do NOT run a separate `pnpm build` beforehand** — this wastes time. The test scripts handle compilation and type checking internally.\n- Text snapshots of the unit tests can be updated with `pnpm test:update:unit` or via the `update-snapshots.yml` GitHub workflow. Visual screenshots are **not** committed: differences are approved on the review page of the pull request (see `docs/visual-review.md`); `pnpm snapshots:pull` fetches the current baseline for local runs.\n- Individual packages provide their own test scripts (e.g. `pnpm --filter @public-ui/components test:unit`).\n - These also perform implicit builds, so explicit pre-build is unnecessary.\n\n## Pull Request Guidelines\n\n- PR titles should be meaningful as they appear in the release notes.\n- Every PR must link to its issue and contain only changes related to that issue.\n- Ensure automated tests pass and manual testing is completed when required.\n- Update documentation or migration guides if your changes affect them.\n",
24
+ "code": "# Agent Instructions\n\nThis repository is a monorepo managed with **pnpm** and **Nx**. It contains multiple packages under `packages/` such as web components, themes, adapters, samples and tooling.\n\n## Handling hints\n\nWe have a monorepo structure with multiple packages, each with its own `package.json`. The root `package.json` contains shared dependencies and scripts. Use `pnpm` commands to manage dependencies and run scripts across packages.\n\n- To install dependencies, use `pnpm i` at the root level. This will install all dependencies for all packages.\n- If you change a dependency in a package:\n - Use only exact version numbers in `package.json`. Other peers will not be able to use the package if you can use a range version.\n - You need to run `pnpm i` at the root level. This updates the lockfile and ensures all packages are using the correct versions.\n- Never add a `packageManager` field to any `package.json` file.\n- Avoid that branch name may contain hidden characters.\n- Development workflow: `git pull` → `pnpm i` → `pnpm -r build` → `pnpm dev` only in the packages being changed → work on the code. No `dev` or `preview` script builds dependencies. Never run a build while a watcher is active, the components build clears the watcher's output. See [CONTRIBUTING.md](CONTRIBUTING.md#daily-workflow).\n- If something does not work, check in the event of an error whether all dependent submodules have been built.\n- To build a single package faster, run commands with downstream dependents using `pnpm --filter ...<package>` (e.g., `pnpm --filter ...@public-ui/sample-react build`). A package's build never builds another package: `pnpm -r build` builds each package exactly once in topological order. Build a package together with its dependencies using `pnpm --filter <package>... build` (e.g. components, which needs the kolicons font from `@public-ui/icons`).\n\n## 🚨 Format-first rule\n\n> **Stop before you commit:** run the formatter so CI never rejects your patch for style drift.\n\n1. Run `pnpm format` from the repo root whenever you change code, docs or configs.\n2. If you only touched one package, you may instead run `pnpm --filter <package> format` for a quicker pass.\n3. Re-stage the affected files (`git add -u`) so the formatted result is what lands in the commit.\n\nNo package scripts in this repo need extra flags such as `-- --write`; the scripts already know when to write changes versus just check.\n\n## Semantic Versioning\n\nThis repository follows **Semantic Versioning** (SemVer) for all packages. Each package version is defined in its own `package.json` file. The versioning scheme is as follows:\n\n- **Major version**: Incremented for incompatible API changes.\n- **Minor version**: Incremented for adding functionality in a backwards-compatible manner.\n- **Patch version**: Incremented for backwards-compatible bug fixes.\n\nThe public API of a component is its props, methods, events, slots and exported types, including their behaviour. Its internal DOM structure and the BEM classes on it are a **theming contract** instead: changing them is a **theming breaking change**, not a hard breaking change. It ships in at least a minor release, carries the label `release:theming` (changelog section _Theming_), lists the old and new classes in the pull request and adapts all themes of this repository in the same change. Theme authors adapt their themes through their own visual snapshots and the zero-visual-delta workflow. See [Theming Contract](packages/components/src/components/_skeleton/ARC42.md#theming-contract-shadow-dom-structure-and-bem-classes).\n\nIf we deprecate a feature, we will mark it as deprecated in the code and documentation, but we will not remove it immediately. Instead, we will provide a migration guide (migration\\*.md) for users to transition to the new feature. Also we provide a migration tool in the `packages/tools/kolibri-cli` package to help with the migration process. You have to add a migration task from the previous version to the new version in the `packages/tools/kolibri-cli/src/migrations` folder. In the migration package, are a lot of migration tasks already implemented, so you can use them as a reference.\n\n## Project Structure\n\n- `packages/components` – Stencil based web components\n - `packages/components/src/component` – components\n - `packages/components/src/schema` – schema definitions for all components\n- `packages/samples` – sample applications demonstrating usage\n - `packages/samples/angular` – Angular sample app; do not edit\n - `packages/samples/react` – React sample app; all samples; write component samples here\n- `packages/adapters/*` – generated framework integration packages; do not edit\n- `packages/themes` – style themes and assets\n - `packages/themes/default` – primary maintained standard theme\n - All other themes are not actively maintained\n- `packages/tools/kolibri-cli` – helper CLI for migration\n- Documentation lives in `docs/`.\n- `kol-tooltip-wc` (`packages/components/src/components/tooltip/component.tsx`) is the only `-wc` web component (`shadow: false`). It stays deprecated and is kept only for DESYBRI: do not remove, migrate or replace it, and do not use it in new code. Every other component that embeds another one renders that component's functional component through an item (see the skeleton ARC42, _Embedded Components (Items)_).\n- Do always ignore and do not edit all `assets` folders in all packages, as these are generated by the build process and should not be edited manually. If you need to change something in the assets, you have to change it in the source code and rebuild the package.\n\n## Theming\n\nThe theming is realized with adopted style sheets on web components and will be adopted at the mounted hook of the components. All following styling rules are only relevant for the `components` and `themes` packages.\n\n### The 5 styling layers\n\n1. **A11y Preset layer**: This layer comes out of the `adopted-style-sheets` package and contains the basic styles for accessibility. It is applied to all components.\n2. **Basis Global layer**: This layer contains the basis global styles for all components and comes out of the `@public-ui/components` package. It is applied only component specific layout styles without margins and paddings. Generally, the styling works without colors, as the colors should only be set through the custom Theme Layer. It never contains a color scheme (dark/light).\n3. **Basis Component layer**: This layer contains the basis styles for one component and comes out of the `@public-ui/components` package. It is applied only component specific layout styles without margins and paddings. Generally, the styling works without colors, as the colors should only be set through the custom Theme Layer. It never contains a color scheme (dark/light).\n4. **Theme Global layer**: This layer contains the global styles for all components of a theme and comes out of a own theme package, like `@public-ui/theme-default`. Color schemes (dark/light) are defined here via theme tokens.\n5. **Theme Component layer**: This layer contains the component specific styles for one component of a theme and comes out of a own theme package, like `@public-ui/theme-default`.\n\n> **Base styling vs. theming — dark/light lives in the theme.** The base styling of the components package (layers 1–3) is responsible for layout and structure only. It knows no dark/light color scheme: no `prefers-color-scheme`, no `color-scheme`, no `light-dark()`, no scheme tokens. Black and white in the base layers are a contrast fallback, not a color design. Dark/light theming is anchored and implemented exclusively in the theme packages (layers 4–5). See [`docs/BASE_STYLING_VS_THEMING_CONCEPT.md`](docs/BASE_STYLING_VS_THEMING_CONCEPT.md).\n\n### Global accessibility styles\n\n```css\n/*\n * This file contains all rules for accessibility.\n */\n@layer kol-global {\n\t:host {\n\t\t/*\n\t\t * Minimum size of interactive elements.\n\t\t */\n\t\t--a11y-min-size: #{rem(44)};\n\t\t/*\n\t\t * No element should be used without a background and font color whose contrast ratio has\n\t\t * not been checked. By initially setting the background color to white and the font color\n\t\t * to black, the contrast ratio is ensured and explicit adjustment is forced.\n\t\t */\n\t\tbackground-color: white;\n\t\tcolor: black;\n\t}\n\n\t* {\n\t\t/*\n\t\t * This rule enables the word dividing for all texts. That is important for high zoom levels.\n\t\t */\n\t\thyphens: auto;\n\t\t/*\n\t\t * Verdana is an accessible font that can be used without requiring additional loading time.\n\t\t */\n\t\tfont-family: Verdana;\n\t\t/*\n\t\t * Letter spacing is required for all texts.\n\t\t */\n\t\tletter-spacing: inherit;\n\t\t/*\n\t\t * This rule enables the word dividing for all texts. That is important for high zoom levels.\n\t\t */\n\t\tword-break: break-word;\n\t\t/*\n\t\t * Word spacing is required for all texts.\n\t\t */\n\t\tword-spacing: inherit;\n\t}\n\n\t/*\n\t * All interactive elements should have a minimum size of rem(44).\n\t */\n\t/* input:not([type='checkbox'], [type='radio'], [type='range']), */\n\t/* option, */\n\t/* select, */\n\t/* textarea, */\n\t[role='button'],\n\tbutton:not([role='link']),\n\t.kol-input .input {\n\t\tmin-height: var(--a11y-min-size);\n\t\tmin-width: var(--a11y-min-size);\n\t}\n\n\t/*\n\t * Some interactive elements should not inherit the font-family and font-size.\n\t */\n\ta,\n\tbutton,\n\th1,\n\th2,\n\th3,\n\th4,\n\th5,\n\th6,\n\tinput,\n\toption,\n\tselect,\n\ttextarea {\n\t\t/*\n\t\t * All elements should inherit the font family from his parent element.\n\t\t */\n\t\tfont-family: inherit;\n\t\t/*\n\t\t * All elements should inherit the font size from his parent element.\n\t\t */\n\t\tfont-size: inherit;\n\t}\n}\n\n/**\n * Sometimes we need the semantic element for accessibility reasons,\n * but we don't want to show it.\n *\n * - https://www.a11yproject.com/posts/how-to-hide-content/\n */\n.visually-hidden {\n\tclip: rect(0 0 0 0);\n\tclip-path: inset(50%);\n\theight: 1px;\n\toverflow: hidden;\n\tposition: absolute;\n\twhite-space: nowrap;\n\twidth: 1px;\n}\n```\n\n### Styling rules\n\nThe basis global layer set the default font-size and box-sizing for all components.\n\n```css\n@layer kol-global {\n\t:host {\n\t\tfont-size: rem(16);\n\t\t/*\n\t\t * The max-width is needed to prevent the table from overflowing the\n\t\t * parent node, if the table is wider than the parent node.\n\t\t */\n\t\tmax-width: 100%;\n\t}\n\n\t* {\n\t\t/*\n\t\t * We prefer to box-sizing: border-box for all elements.\n\t\t */\n\t\tbox-sizing: border-box;\n\t}\n ...\n}\n```\n\n### Custom Theming rules\n\nThe custom theme layer is used to set the colors and other theme specific styles. The custom theme layer should not contain any layout styles, as these are already set in the basis global and component layers.\n\nDark/light color schemes are implemented in the theme layers only. Define all colors that differ between light and dark as tokens on `:host` in the theme global layer and switch the scheme there (`color-scheme` + `light-dark()`, `@media (prefers-color-scheme: dark)`, or an opt-in attribute). The theme component layer only references those tokens and never contains its own scheme media queries. Alternatively, a theme may ship a separate dark export that is registered as an additional theme and switched via the `kol-theme` attribute. The base styling of the components package must never be involved in this.\n\nFor example, generally the font-family is set in the theme global layer, on the `:host` element, so that all components inherit the font-family from the theme. The font-size is set in the basis global layer, so that all components inherit the font-size from the basis global layer. But it is possible to set a other base font-size in the theme global layer, if needed.\n\n```css\n@layer kol-theme-global {\n\t:host {\n\t\t--font-family: var(--kolibri-font-family, Verdana, Arial, Calibri, Helvetica, sans-serif);\n\t\t--font-size: var(--kolibri-font-size, #{rem(16)});\n ...\n\t}\n\n\t:host {\n\t\tfont-size: var(--font-size);\n\n\t\t* {\n\t\t\tfont-family: var(--font-family);\n\t\t}\n\t}\n ...\n}\n```\n\nIn the theme component layer, you can set what ever you need to realize your own custom style guidelines. For example, you can set the colors, borders, shadows, etc. for the component.\n\n```css\n@layer kol-theme-component {\n ...\n}\n```\n\n### Color schemes\n\nA theme carries one palette per color scheme in a single declaration, resolved by the CSS\n`light-dark()` function:\n\n```scss\n@layer kol-theme-global {\n\t:host {\n\t\t--color-text: var(--kolibri-color-text, light-dark(#202020, #{$dark-color-text}));\n\t}\n}\n```\n\nRules that hold for every theme:\n\n- **Never declare `color-scheme` in a theme**, and never write `@media (prefers-color-scheme: …)`.\n `color-scheme` is an inherited property and inheritance follows the flat tree, so it crosses the\n shadow boundary on its own: each component resolves `light-dark()` against whatever the consuming\n application has in effect where the component sits. A declaration on `:host` would replace that\n inherited value, and the page and the components in it could then disagree — which is exactly the\n bug this rule exists to prevent.\n- The application owns the scheme, in plain CSS: `:root { color-scheme: light dark }` to follow the\n operating system, `color-scheme: dark` on any element to force a subtree. Consequently an\n application that declares nothing stays light, whatever the operating system says. Dark mode is\n opt-in; `color-scheme.css` in a theme package ships that one line plus the page colors.\n- Sass does not evaluate variables inside `var()`. Interpolate them (`#{$dark-color-text}`).\n- An application stylesheet that uses `light-dark()` must not be downlevelled. A CSS minifier\n targeting older browsers rewrites it into a `prefers-color-scheme` media query with space\n toggles, and that replacement ignores the `color-scheme` property. A theme's CSS is a string\n adopted into the shadow roots at runtime and is never processed by the application's CSS\n pipeline, so the page would follow the operating system while the components follow\n `color-scheme`. Both sample host apps therefore pin `build.cssTarget` in their Vite config.\n- The base layer hardcodes `black` and `white` in a few places. Where it routes them through a\n token, override the token (`--kol-a11y-font-color` / `--kol-a11y-background-color` in `a11y.scss`\n are the sanctioned hook for the host box of every component); elsewhere restate the declaration in\n a theme layer, which sits above `kol-a11y`, `kol-global` and `kol-component`. Keep the light\n branch byte identical to the base value so no light snapshot moves.\n- What a theme layer cannot reach are the color stops of a `@keyframes` rule declared in the base\n layer: an animation's own values win over any normal declaration, whatever the layer. Such a case\n needs a change in `packages/components`.\n- Depth is a surface scale, not a shadow: a lighter surface sits higher. A light palette collapses\n that scale onto white and draws depth with a shadow instead; a dark one carries it in the surfaces\n and replaces the shadow with a hard edge. Since `light-dark()` is a color function and cannot\n switch a `box-shadow` geometry, state both branches at once and switch them by their colors — the\n shadow token transparent in dark mode, the edge token transparent in light mode. A container that\n paints a surface of its own passes it down through `--kol-surface`, which reaches slotted\n components too, so their host box matches the surface they were placed on.\n\n### CSS Custom Properties and SASS Variables\n\nCSS custom properties remain part of the global cascade and are not isolated by the Shadow DOM.\nOverusing them (in theme files as well as in component styles) can collide with variables defined\non a host page, and every custom property you declare is implicitly overridable from outside,\nwhether you intended that or not.\n\n**Prefer plain CSS over a custom property.** Before adding a custom property, check whether the\nplatform already gives the consumer a way to control it — the standard box model (`width`,\n`height`), inherited properties (`color`, `font-size` via `em`), or relative units (`%`, container\nquery units). A component that simply fills its host (`width: 100%; height: 100%` inside, a sane\ndefault `width`/`height` on `:host`) can be resized with plain CSS, exactly like a native element —\nno bespoke API, no documentation burden, nothing to keep in sync. Only reach for a custom property\nwhen the value genuinely cannot be derived this way (e.g. a semantic color token that isn't just\n`currentColor`, or a value with no corresponding native CSS mechanism).\n\n**Rule:** only declare a CSS custom property when it is a deliberate, documented customization\npoint (a `--kol-<component>-<name>` design token). For anything else — internal aliases,\nintermediate values, ratios, or derived defaults — use a SASS `$variable` instead. SASS variables\nare resolved at build time, can't leak into the global cascade, and can't be overridden from a host\npage, so they can't accidentally become part of the public API.\n\nDo not introduce a second, internal custom property just to make the code more readable:\n\n```scss\n// ❌ Bad: `--color-bar` is an unintended, additional public custom property.\n// It reacts to overrides from a host page exactly like `--kol-progress-color-bar`,\n// even though only the latter was meant to be part of the API.\n.kol-progress {\n\t--color-bar: var(--kol-progress-color-bar, #0075ff);\n\n\t&__bar-progress {\n\t\tfill: var(--color-bar);\n\t}\n}\n```\n\n```scss\n// ✅ Good: the SASS variable holds the default value; the only custom property\n// is `--kol-progress-color-bar`, referenced directly wherever needed.\n$kol-progress-default-color-bar: #0075ff;\n\n.kol-progress {\n\t&__bar-progress {\n\t\tfill: var(--kol-progress-color-bar, #{$kol-progress-default-color-bar});\n\t}\n}\n```\n\nAny further unit conversion or math that doesn't depend on a runtime custom property (e.g. `to-rem()`,\nratios, breakpoints) belongs in SASS, not in an extra layer of `calc()`/custom-property indirection.\n\n`kol-avatar` is an example of preferring plain CSS: instead of a `--kol-avatar-size` custom property,\n`:host` gets a default `width` and an `aspect-ratio: 1`, and the inner element derives its size from the\nhost via container query units (`cqw`/`cqh`) instead of a separate ratio calculation. Consumers resize it\nthe same way they'd resize any block-level element — with plain `width`/`height`.\n\nThe avatar must always stay square, even if `width` and `height` end up different (e.g. both are set\nexplicitly to different values), so the inner element uses `max(100cqw, 100cqh)` for both its own `width`\nand `height` — the larger of the two wins, and `:host` centers it (`align-items`/`justify-content`), so it\nmay visually extend beyond the host on the smaller axis. Since CSS can't distinguish \"our default\" from\n\"an explicit author value\" on two independent properties, only setting `width` reliably resizes the avatar\nbelow its 100px default; setting only `height` below 100px does not shrink it, because our own default\n`width` is still in effect and wins the `max()`. This is a deliberate, documented trade-off, not a bug —\nachieving full symmetry would require either a custom property or JavaScript, both of which cost more\nthan the trade-off is worth.\n\n### SCSS Architecture Guidelines: BEM with Smart Nesting\n\nWhen writing component theme styles, follow these principles for clean, maintainable SCSS:\n\n#### 1. **Flat BEM Structure (Root Level)**\n\nAll BEM modifiers and independent elements belong at **root level** of the mixin. Never nest BEM class names:\n\n```scss\n@mixin kol-alert-theme {\n\t// ✅ All BEM selectors on root (flat)\n\t.kol-alert { ... }\n\t.kol-alert--variant-msg { ... }\n\t.kol-alert--variant-card { ... }\n\t.kol-alert--type-default { ... }\n\t.kol-alert__container { ... }\n\t.kol-alert__heading { ... }\n}\n```\n\n**Why?** BEM classnames are independent selectors. Each class should be predictable and flat.\n\n#### 2. **Contextual Nesting (When Variants Change Element Behavior)**\n\nNest **only when a modifier changes how a child element behaves**. Keep all rules for an element together:\n\n```scss\n.kol-alert__closer {\n\tplace-self: center;\n\n\t.kol-button {\n\t\tborder-radius: 50%;\n\t\twidth: var(--a11y-min-size);\n\t\theight: var(--a11y-min-size);\n\t\tcursor: pointer;\n\n\t\t// ✅ Variant changes button styling - nest here\n\t\t.kol-alert--variant-msg & {\n\t\t\t--text-color: var(--alert-accent-color);\n\t\t}\n\n\t\t.kol-alert--variant-card & {\n\t\t\t--text-color: var(--color-light);\n\t\t}\n\t}\n}\n```\n\n**Rule of thumb**: All rules for `.kol-button` in `.kol-alert__closer` stay in one place. This keeps related styles together and makes maintenance easier.\n\n#### 3. **Never Use `$root` or `@at-root`**\n\n❌ **Outdated pattern (removed):**\n\n```scss\n.kol-alert {\n\t$root: &;\n\t&__closer {\n\t\t@at-root #{$root}--variant-msg & { ... }\n\t}\n}\n```\n\n✅ **Modern pattern (direct nesting):**\n\n```scss\n.kol-alert__closer {\n\t.kol-button {\n\t\t.kol-alert--variant-msg & { ... }\n\t}\n}\n```\n\nThis is clearer and doesn't require Sass variable gymnastics.\n\n#### 4. **Structure Template**\n\n```scss\n@mixin kol-component-theme {\n\t// 1. Base component (no children)\n\t.kol-component {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t}\n\n\t// 2. All BEM modifiers at root (flat)\n\t.kol-component--variant-a {\n\t\t...\n\t}\n\n\t.kol-component--type-default {\n\t\t...\n\t}\n\n\t// 3. Elements with contextual nesting for variants\n\t.kol-component__heading {\n\t\tfont-weight: bold;\n\n\t\t.kol-component--variant-a & {\n\t\t\tcolor: red;\n\t\t}\n\t}\n\n\t.kol-component__content {\n\t\tpadding: 1rem;\n\n\t\t.kol-component--variant-a & {\n\t\t\tbackground: white;\n\t\t}\n\t}\n\n\t// 4. Child components with variant context\n\t.kol-component__button {\n\t\t.kol-button {\n\t\t\tcursor: pointer;\n\n\t\t\t.kol-component--variant-a & {\n\t\t\t\t--text-color: var(--accent);\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n### General rules for custom themes\n\n- Do not use `!important` in your styles, as this will override the styles of the basis global and component layers.\n- Do only overwrite styling definitions you will really customize. Do not set styling definitions that are already set (redundant) in the basis global and component layers, as this will override the styles of the basis global and component layers.\n- Do not `inherit` styles over the `:host` element, as this will override the styles of the basis global and component layers. This makes your component less robust from outside environment styles. Only the `kol-icon` inherits some specific styles, like `color`, `font-size`, `font-family` and `line-height`, as these are needed for the icon to be displayed correctly inline to this neighbored elements.\n- Do not set the default `font-family`, `font-size` or `box-sizing` in the basis or theme component layer (redundant), as these are already set in the basis global layers. If you need to set a different font-family or font-size, you can do this in the theme global layer.\n- Do not set `margin` or `padding` in the basis global and component layers. If you need to set a different margin or padding, you can do this in the theme global or component layers.\n- Do not use `@media (prefers-color-scheme: …)`, the `color-scheme` property or the `light-dark()` function in the basis global and component layers. Dark/light color schemes are a theme concern and belong exclusively in the theme global layer (see [`docs/BASE_STYLING_VS_THEMING_CONCEPT.md`](docs/BASE_STYLING_VS_THEMING_CONCEPT.md)). `forced-colors` (high contrast) is a separate accessibility mechanism and stays in the basis `kol-forced-colors` layer.\n- Do not use `overflow: hidden` in styling or theming, as it often causes issues for reuse and should be avoided.\n- **Do not use `@layer` declarations in utility files**: Helper files, mixin files, and partial files (starting with `_`) should not contain `@layer` declarations. These files are utilities and should be layer-agnostic. This is enforced by the custom Stylelint rule `kolibri/no-layer-in-utility-files`.\n- **Never use `$root` variables or `@at-root` in component mixins**: All selectors should be explicit. Use direct child/descendant nesting only when a modifier changes element behavior within a specific context.\n\n## Samples\n\nThe samples are located in `packages/samples/react` and demonstrate how to use the components in react. Each component has its own folder and the basic sample are in `basic.tsx`. Other stories can be added in the same folder. All samples of a component are registered in the `routes.ts` file.\n\n## Coding Conventions\n\n- Formatting is enforced via **Prettier** with settings defined in `prettier.config.js` (print width 160, single quotes, tabs).\n- `.editorconfig` sets `indent_style = tab` and `max_line_length = 160` for code files. Markdown and YAML files use spaces.\n- ESLint and Stylelint are run using `pnpm lint`. Lint rules should **not** be disabled via inline comments. Instead, describe the problem and work towards a clean solution.\n- Lists and enumerations in code should be kept in alphanumeric order. This also applies to import specifiers and union type literals.\n- Do not disable ESLint, Stylelint or TypeScript rules inline. Fix the code instead of turning such rules off.\n- ESLint and Stylelint are run using `pnpm lint`.\n- Lists and enumerations in code should be kept in alphabetical order (see `docs/tutorials/NEW_COMPONENT.md`).\n- Commit messages follow the **Conventional Commits** specification.\n- See also the [Contributing Guide](CONTRIBUTING.md) for more details on coding conventions and best practices.\n- Spell \"KoliBri\" with this casing in all documentation and code. The only exception is the component named KolKolibri.\n- Use ESM import syntax in browser code and scripts whenever supported, instead of `require` imports.\n- Do not create barrel files (e.g. `index.ts` that re-export modules). Import modules directly instead.\n- Stencil component classes follow one member order: statics, `@Element`, `@State`, fields, constructor, each `@Prop`, `@Event`, `@Method`, lifecycle methods, `@Listen`, helpers, `render`; a `@Watch` directly follows the `@Prop` or `@State` it observes (see the skeleton ARC42, _Member order_; pinned by `component-structure.spec.ts`).\n- Reuse the prop definition of `internal/props` for a public prop name (e.g. `disabledProp` for every `_disabled`). Add a variant for the same render key only where it differs functionally, where a shared factory types it per component (callbacks, links, options) or where its meaning differs (`paginationLabelProp`), and document it in `internal/props/prop-keys.spec.ts`.\n- Do not place constant declarations before import statements; imports must always be at the very top of the file.\n- **Scripts must be platform-independent**: All scripts in the `scripts/` folder must work on Windows, macOS, and Linux without requiring external tools or platform-specific dependencies. Use Node.js built-in modules instead of external command-line tools like `rg`, `grep`, `find`, etc.\n- Inline code documentation follows [Inline code documentation](#inline-code-documentation).\n\n### Inline code documentation\n\nWe encourage inline code documentation (JSDoc in TypeScript/TSX, comments in SCSS and scripts), but only as much as necessary and as little as possible. This rule applies to every new or changed comment; when you touch code, bring the comments of the touched code in line with it.\n\n- **Document what the code cannot say itself**: the purpose of public API (`@Prop`, `@Method`, `@Event`, exported functions and types), constraints, a non-obvious reason (the \"why\") and known limitations.\n- **Do not repeat the code**: no comment that restates a name, a type or the next line. The TypeScript signature is the source of truth, so no `@param {string}` or `@returns {void}` type annotations.\n- **Describe the present and the future, never the past**: state what the code is and does and, where relevant, where it is heading (`@deprecated` with its replacement, a `TODO` with an issue link). Do not write history such as \"previously\", \"changed to\", \"fixed\", \"new:\", and do not refer to the diff, the pull request or a predecessor implementation. History belongs in the commit message, the pull request and the changelog. If an earlier state still matters, state the constraint that follows from it today.\n- **Write for human and AI readers alike**: clear, easy to follow and free of contradictions. One statement per fact, terms named exactly as in the code, no vague wording (\"maybe\", \"somehow\", \"for now\"). A comment never contradicts the code, another comment or the documentation. Update or delete a comment together with the code it describes, and link the authoritative document instead of copying it.\n- **Published API documentation stays stable**: the JSDoc of public `@Prop`, `@Method` and `@Event` members is published (`custom-elements.json`, `docs-vscode`, adapter IntelliSense). Refactorings and migrations keep it unchanged (see [Public API Contract](packages/components/src/components/_skeleton/ARC42.md#public-api-contract-migration-parity)); rewording it is a change of its own.\n\n```ts\n// ❌ Bad: repeats the signature and tells history.\n/**\n * Sets the label.\n * @param {string} value - the label\n * Previously this was handled by the controller; changed in the skeleton migration.\n */\nprivate setLabel(value: string): void {}\n\n// ✅ Good: states the constraint the code cannot express.\n/**\n * Runs before the first render, because the behaviors read the normalized label in `componentWillLoad`.\n */\nprivate setLabel(value: string): void {}\n```\n\n## Linting and Formatting\n\n- Run `pnpm lint` to check for linting errors across all packages. This script runs ESLint, Stylelint and TypeScript checks.\n - ⚠️ **Note**: TypeScript type checking in the lint script can require built artifacts. If you've made source code changes, lint will handle any necessary compilation. Explicit pre-build is typically unnecessary.\n - You can try to automatically fix linting issues with `pnpm lint:eslint --fix`, but this may not resolve all issues.\n- Run `pnpm format` to format all code files using Prettier. You can try to automatically fix linting issues with `pnpm format -w`, but this may not resolve all issues.\n- If your pull request only modifies Markdown files, skip `pnpm build`, `pnpm lint` and `pnpm test`. Just format the Markdown using `pnpm format` or Prettier.\n\n### Pre-commit checklist\n\n- **Always run `pnpm format` (or `pnpm --filter <package> format` for a single workspace) right before committing.** Formatting failures are one of the most common reasons for blocked quality gates, so make this the last step before `git commit` even for documentation-only changes.\n- **For SCSS changes**: Always run `pnpm lint:stylelint --fix` (or `pnpm --filter <package> lint:stylelint --fix`) to automatically correct formatting, property order, and selector structure rules before committing. This ensures compliance with BEM structure and style consistency.\n- After formatting, re-stage affected files with `git add -u` so the formatted content is what gets committed.\n\n## Testing\n\n- Run `pnpm test` from the repository root to execute all unit and integration tests.\n - ⚠️ **Note**: Test runners (Vitest, Jest, Playwright, etc.) execute an implicit build automatically before running tests. **Do NOT run a separate `pnpm build` beforehand** — this wastes time. The test scripts handle compilation and type checking internally.\n- Text snapshots of the unit tests can be updated with `pnpm test:update:unit` or via the `update-snapshots.yml` GitHub workflow. Visual screenshots are **not** committed: differences are approved on the review page of the pull request (see `docs/visual-review.md`); `pnpm snapshots:pull` fetches the current baseline for local runs.\n- Individual packages provide their own test scripts (e.g. `pnpm --filter @public-ui/components test:unit`).\n - These also perform implicit builds, so explicit pre-build is unnecessary.\n\n## Pull Request Guidelines\n\n- PR titles should be meaningful as they appear in the release notes.\n- Every PR must link to its issue and contain only changes related to that issue.\n- Ensure automated tests pass and manual testing is completed when required.\n- Update documentation or migration guides if your changes affect them.\n",
25
25
  "kind": "doc"
26
26
  },
27
27
  {
@@ -18,7 +18,7 @@
18
18
  "stats": {
19
19
  "size": 9600,
20
20
  "lines": 246,
21
- "lastModified": "2026-10-06T13:52:07.662Z"
21
+ "lastModified": "2026-10-07T08:09:43.160Z"
22
22
  }
23
23
  },
24
24
  {
@@ -40,7 +40,7 @@
40
40
  "stats": {
41
41
  "size": 3486,
42
42
  "lines": 75,
43
- "lastModified": "2026-10-06T13:52:07.662Z"
43
+ "lastModified": "2026-10-07T08:09:43.160Z"
44
44
  }
45
45
  },
46
46
  {
@@ -62,29 +62,7 @@
62
62
  "stats": {
63
63
  "size": 2425,
64
64
  "lines": 98,
65
- "lastModified": "2026-10-06T13:52:07.701Z"
66
- }
67
- },
68
- {
69
- "id": "public-ui-templates:svg2font:svg:README.md",
70
- "repoId": "public-ui-templates",
71
- "path": "svg2font/svg/README.md",
72
- "type": "markdown",
73
- "content": "# SVG folder\n\nThis folder contains the SVG files.\n",
74
- "metadata": {
75
- "name": "README.md",
76
- "tags": [
77
- "template",
78
- "generic",
79
- "kolibri",
80
- "starter"
81
- ],
82
- "templateType": "generic"
83
- },
84
- "stats": {
85
- "size": 50,
86
- "lines": 4,
87
- "lastModified": "2026-10-06T13:52:07.701Z"
65
+ "lastModified": "2026-10-07T08:09:43.187Z"
88
66
  }
89
67
  },
90
68
  {
@@ -106,7 +84,7 @@
106
84
  "stats": {
107
85
  "size": 1549,
108
86
  "lines": 35,
109
- "lastModified": "2026-10-06T13:52:07.700Z"
87
+ "lastModified": "2026-10-07T08:09:43.186Z"
110
88
  }
111
89
  },
112
90
  {
@@ -128,7 +106,7 @@
128
106
  "stats": {
129
107
  "size": 182,
130
108
  "lines": 8,
131
- "lastModified": "2026-10-06T13:52:07.697Z"
109
+ "lastModified": "2026-10-07T08:09:43.183Z"
132
110
  }
133
111
  },
134
112
  {
@@ -150,7 +128,7 @@
150
128
  "stats": {
151
129
  "size": 4276,
152
130
  "lines": 75,
153
- "lastModified": "2026-10-06T13:52:07.688Z"
131
+ "lastModified": "2026-10-07T08:09:43.176Z"
154
132
  }
155
133
  },
156
134
  {
@@ -172,7 +150,29 @@
172
150
  "stats": {
173
151
  "size": 2812,
174
152
  "lines": 74,
175
- "lastModified": "2026-10-06T13:52:07.678Z"
153
+ "lastModified": "2026-10-07T08:09:43.173Z"
154
+ }
155
+ },
156
+ {
157
+ "id": "public-ui-templates:svg2font:svg:README.md",
158
+ "repoId": "public-ui-templates",
159
+ "path": "svg2font/svg/README.md",
160
+ "type": "markdown",
161
+ "content": "# SVG folder\n\nThis folder contains the SVG files.\n",
162
+ "metadata": {
163
+ "name": "README.md",
164
+ "tags": [
165
+ "template",
166
+ "generic",
167
+ "kolibri",
168
+ "starter"
169
+ ],
170
+ "templateType": "generic"
171
+ },
172
+ "stats": {
173
+ "size": 50,
174
+ "lines": 4,
175
+ "lastModified": "2026-10-07T08:09:43.187Z"
176
176
  }
177
177
  },
178
178
  {
@@ -194,7 +194,7 @@
194
194
  "stats": {
195
195
  "size": 587,
196
196
  "lines": 56,
197
- "lastModified": "2026-10-06T13:52:07.675Z"
197
+ "lastModified": "2026-10-07T08:09:43.170Z"
198
198
  }
199
199
  },
200
200
  {
@@ -216,7 +216,7 @@
216
216
  "stats": {
217
217
  "size": 566,
218
218
  "lines": 50,
219
- "lastModified": "2026-10-06T13:52:07.673Z"
219
+ "lastModified": "2026-10-07T08:09:43.169Z"
220
220
  }
221
221
  },
222
222
  {
@@ -238,7 +238,7 @@
238
238
  "stats": {
239
239
  "size": 568,
240
240
  "lines": 50,
241
- "lastModified": "2026-10-06T13:52:07.672Z"
241
+ "lastModified": "2026-10-07T08:09:43.167Z"
242
242
  }
243
243
  },
244
244
  {
@@ -260,7 +260,7 @@
260
260
  "stats": {
261
261
  "size": 601,
262
262
  "lines": 45,
263
- "lastModified": "2026-10-06T13:52:07.666Z"
263
+ "lastModified": "2026-10-07T08:09:43.162Z"
264
264
  }
265
265
  },
266
266
  {
@@ -282,7 +282,7 @@
282
282
  "stats": {
283
283
  "size": 587,
284
284
  "lines": 56,
285
- "lastModified": "2026-10-06T13:52:07.667Z"
285
+ "lastModified": "2026-10-07T08:09:43.163Z"
286
286
  }
287
287
  },
288
288
  {
@@ -304,7 +304,7 @@
304
304
  "stats": {
305
305
  "size": 566,
306
306
  "lines": 50,
307
- "lastModified": "2026-10-06T13:52:07.664Z"
307
+ "lastModified": "2026-10-07T08:09:43.161Z"
308
308
  }
309
309
  },
310
310
  {
@@ -326,7 +326,7 @@
326
326
  "stats": {
327
327
  "size": 615,
328
328
  "lines": 50,
329
- "lastModified": "2026-10-06T13:52:07.663Z"
329
+ "lastModified": "2026-10-07T08:09:43.161Z"
330
330
  }
331
331
  },
332
332
  {
@@ -348,7 +348,7 @@
348
348
  "stats": {
349
349
  "size": 31,
350
350
  "lines": 2,
351
- "lastModified": "2026-10-06T13:52:07.685Z"
351
+ "lastModified": "2026-10-07T08:09:43.175Z"
352
352
  }
353
353
  },
354
354
  {
@@ -370,7 +370,7 @@
370
370
  "stats": {
371
371
  "size": 31,
372
372
  "lines": 2,
373
- "lastModified": "2026-10-06T13:52:07.684Z"
373
+ "lastModified": "2026-10-07T08:09:43.175Z"
374
374
  }
375
375
  },
376
376
  {
@@ -392,7 +392,7 @@
392
392
  "stats": {
393
393
  "size": 25,
394
394
  "lines": 2,
395
- "lastModified": "2026-10-06T13:52:07.680Z"
395
+ "lastModified": "2026-10-07T08:09:43.174Z"
396
396
  }
397
397
  },
398
398
  {
@@ -414,7 +414,7 @@
414
414
  "stats": {
415
415
  "size": 327,
416
416
  "lines": 19,
417
- "lastModified": "2026-10-06T13:52:07.678Z"
417
+ "lastModified": "2026-10-07T08:09:43.173Z"
418
418
  }
419
419
  },
420
420
  {
@@ -436,7 +436,7 @@
436
436
  "stats": {
437
437
  "size": 416,
438
438
  "lines": 2,
439
- "lastModified": "2026-10-06T13:52:07.673Z"
439
+ "lastModified": "2026-10-07T08:09:43.168Z"
440
440
  }
441
441
  },
442
442
  {
@@ -458,7 +458,7 @@
458
458
  "stats": {
459
459
  "size": 416,
460
460
  "lines": 2,
461
- "lastModified": "2026-10-06T13:52:07.665Z"
461
+ "lastModified": "2026-10-07T08:09:43.162Z"
462
462
  }
463
463
  },
464
464
  {
@@ -481,7 +481,7 @@
481
481
  "stats": {
482
482
  "size": 88,
483
483
  "lines": 6,
484
- "lastModified": "2026-10-06T13:52:07.697Z"
484
+ "lastModified": "2026-10-07T08:09:43.183Z"
485
485
  }
486
486
  },
487
487
  {
@@ -503,7 +503,7 @@
503
503
  "stats": {
504
504
  "size": 0,
505
505
  "lines": 1,
506
- "lastModified": "2026-10-06T13:52:07.682Z"
506
+ "lastModified": "2026-10-07T08:09:43.174Z"
507
507
  }
508
508
  },
509
509
  {
@@ -525,7 +525,7 @@
525
525
  "stats": {
526
526
  "size": 0,
527
527
  "lines": 1,
528
- "lastModified": "2026-10-06T13:52:07.682Z"
528
+ "lastModified": "2026-10-07T08:09:43.174Z"
529
529
  }
530
530
  },
531
531
  {
@@ -547,7 +547,7 @@
547
547
  "stats": {
548
548
  "size": 21,
549
549
  "lines": 2,
550
- "lastModified": "2026-10-06T13:52:07.682Z"
550
+ "lastModified": "2026-10-07T08:09:43.174Z"
551
551
  }
552
552
  },
553
553
  {
@@ -569,7 +569,7 @@
569
569
  "stats": {
570
570
  "size": 23,
571
571
  "lines": 2,
572
- "lastModified": "2026-10-06T13:52:07.681Z"
572
+ "lastModified": "2026-10-07T08:09:43.174Z"
573
573
  }
574
574
  },
575
575
  {
@@ -591,7 +591,7 @@
591
591
  "stats": {
592
592
  "size": 25,
593
593
  "lines": 2,
594
- "lastModified": "2026-10-06T13:52:07.681Z"
594
+ "lastModified": "2026-10-07T08:09:43.174Z"
595
595
  }
596
596
  },
597
597
  {
@@ -613,7 +613,7 @@
613
613
  "stats": {
614
614
  "size": 220,
615
615
  "lines": 20,
616
- "lastModified": "2026-10-06T13:52:07.683Z"
616
+ "lastModified": "2026-10-07T08:09:43.174Z"
617
617
  }
618
618
  },
619
619
  {
@@ -635,7 +635,7 @@
635
635
  "stats": {
636
636
  "size": 587,
637
637
  "lines": 56,
638
- "lastModified": "2026-10-06T13:52:08.506Z"
638
+ "lastModified": "2026-10-07T08:09:43.930Z"
639
639
  }
640
640
  },
641
641
  {
@@ -658,7 +658,7 @@
658
658
  "stats": {
659
659
  "size": 472,
660
660
  "lines": 14,
661
- "lastModified": "2026-10-06T13:52:08.512Z"
661
+ "lastModified": "2026-10-07T08:09:43.936Z"
662
662
  }
663
663
  },
664
664
  {
@@ -681,7 +681,7 @@
681
681
  "stats": {
682
682
  "size": 35,
683
683
  "lines": 4,
684
- "lastModified": "2026-10-06T13:52:08.512Z"
684
+ "lastModified": "2026-10-07T08:09:43.936Z"
685
685
  }
686
686
  },
687
687
  {
@@ -704,7 +704,7 @@
704
704
  "stats": {
705
705
  "size": 43,
706
706
  "lines": 2,
707
- "lastModified": "2026-10-06T13:52:08.512Z"
707
+ "lastModified": "2026-10-07T08:09:43.936Z"
708
708
  }
709
709
  },
710
710
  {
@@ -727,7 +727,7 @@
727
727
  "stats": {
728
728
  "size": 916,
729
729
  "lines": 39,
730
- "lastModified": "2026-10-06T13:52:08.512Z"
730
+ "lastModified": "2026-10-07T08:09:43.936Z"
731
731
  }
732
732
  },
733
733
  {
@@ -750,7 +750,7 @@
750
750
  "stats": {
751
751
  "size": 368,
752
752
  "lines": 13,
753
- "lastModified": "2026-10-06T13:52:08.512Z"
753
+ "lastModified": "2026-10-07T08:09:43.936Z"
754
754
  }
755
755
  },
756
756
  {
@@ -773,7 +773,7 @@
773
773
  "stats": {
774
774
  "size": 97,
775
775
  "lines": 5,
776
- "lastModified": "2026-10-06T13:52:08.512Z"
776
+ "lastModified": "2026-10-07T08:09:43.936Z"
777
777
  }
778
778
  },
779
779
  {
@@ -796,7 +796,7 @@
796
796
  "stats": {
797
797
  "size": 2358,
798
798
  "lines": 44,
799
- "lastModified": "2026-10-06T13:52:08.512Z"
799
+ "lastModified": "2026-10-07T08:09:43.936Z"
800
800
  }
801
801
  },
802
802
  {
@@ -819,7 +819,7 @@
819
819
  "stats": {
820
820
  "size": 9997,
821
821
  "lines": 367,
822
- "lastModified": "2026-10-06T13:52:08.510Z"
822
+ "lastModified": "2026-10-07T08:09:43.934Z"
823
823
  }
824
824
  },
825
825
  {
@@ -842,7 +842,7 @@
842
842
  "stats": {
843
843
  "size": 1199,
844
844
  "lines": 34,
845
- "lastModified": "2026-10-06T13:52:08.510Z"
845
+ "lastModified": "2026-10-07T08:09:43.934Z"
846
846
  }
847
847
  },
848
848
  {
@@ -865,7 +865,7 @@
865
865
  "stats": {
866
866
  "size": 10353,
867
867
  "lines": 555,
868
- "lastModified": "2026-10-06T13:52:08.509Z"
868
+ "lastModified": "2026-10-07T08:09:43.933Z"
869
869
  }
870
870
  },
871
871
  {
@@ -888,7 +888,7 @@
888
888
  "stats": {
889
889
  "size": 646,
890
890
  "lines": 21,
891
- "lastModified": "2026-10-06T13:52:08.512Z"
891
+ "lastModified": "2026-10-07T08:09:43.936Z"
892
892
  }
893
893
  },
894
894
  {
@@ -911,7 +911,7 @@
911
911
  "stats": {
912
912
  "size": 519,
913
913
  "lines": 19,
914
- "lastModified": "2026-10-06T13:52:08.512Z"
914
+ "lastModified": "2026-10-07T08:09:43.936Z"
915
915
  }
916
916
  },
917
917
  {
@@ -934,7 +934,7 @@
934
934
  "stats": {
935
935
  "size": 670,
936
936
  "lines": 22,
937
- "lastModified": "2026-10-06T13:52:08.511Z"
937
+ "lastModified": "2026-10-07T08:09:43.935Z"
938
938
  }
939
939
  },
940
940
  {
@@ -957,7 +957,7 @@
957
957
  "stats": {
958
958
  "size": 3451,
959
959
  "lines": 9,
960
- "lastModified": "2026-10-06T13:52:08.511Z"
960
+ "lastModified": "2026-10-07T08:09:43.935Z"
961
961
  }
962
962
  },
963
963
  {
@@ -980,7 +980,7 @@
980
980
  "stats": {
981
981
  "size": 10313,
982
982
  "lines": 46,
983
- "lastModified": "2026-10-06T13:52:08.510Z"
983
+ "lastModified": "2026-10-07T08:09:43.935Z"
984
984
  }
985
985
  },
986
986
  {
@@ -1003,7 +1003,7 @@
1003
1003
  "stats": {
1004
1004
  "size": 107635,
1005
1005
  "lines": 364,
1006
- "lastModified": "2026-10-06T13:52:08.510Z"
1006
+ "lastModified": "2026-10-07T08:09:43.935Z"
1007
1007
  }
1008
1008
  },
1009
1009
  {
@@ -1026,7 +1026,7 @@
1026
1026
  "stats": {
1027
1027
  "size": 64024,
1028
1028
  "lines": 323,
1029
- "lastModified": "2026-10-06T13:52:08.510Z"
1029
+ "lastModified": "2026-10-07T08:09:43.934Z"
1030
1030
  }
1031
1031
  },
1032
1032
  {
@@ -1049,7 +1049,7 @@
1049
1049
  "stats": {
1050
1050
  "size": 23737,
1051
1051
  "lines": 110,
1052
- "lastModified": "2026-10-06T13:52:08.510Z"
1052
+ "lastModified": "2026-10-07T08:09:43.934Z"
1053
1053
  }
1054
1054
  },
1055
1055
  {
@@ -1072,7 +1072,7 @@
1072
1072
  "stats": {
1073
1073
  "size": 18200,
1074
1074
  "lines": 75,
1075
- "lastModified": "2026-10-06T13:52:08.510Z"
1075
+ "lastModified": "2026-10-07T08:09:43.934Z"
1076
1076
  }
1077
1077
  },
1078
1078
  {
@@ -1095,7 +1095,7 @@
1095
1095
  "stats": {
1096
1096
  "size": 12909,
1097
1097
  "lines": 87,
1098
- "lastModified": "2026-10-06T13:52:08.510Z"
1098
+ "lastModified": "2026-10-07T08:09:43.934Z"
1099
1099
  }
1100
1100
  },
1101
1101
  {
@@ -1118,7 +1118,7 @@
1118
1118
  "stats": {
1119
1119
  "size": 19632,
1120
1120
  "lines": 75,
1121
- "lastModified": "2026-10-06T13:52:08.510Z"
1121
+ "lastModified": "2026-10-07T08:09:43.934Z"
1122
1122
  }
1123
1123
  },
1124
1124
  {
@@ -1141,7 +1141,7 @@
1141
1141
  "stats": {
1142
1142
  "size": 8806,
1143
1143
  "lines": 38,
1144
- "lastModified": "2026-10-06T13:52:08.510Z"
1144
+ "lastModified": "2026-10-07T08:09:43.934Z"
1145
1145
  }
1146
1146
  },
1147
1147
  {
@@ -1164,7 +1164,7 @@
1164
1164
  "stats": {
1165
1165
  "size": 103382,
1166
1166
  "lines": 377,
1167
- "lastModified": "2026-10-06T13:52:08.510Z"
1167
+ "lastModified": "2026-10-07T08:09:43.934Z"
1168
1168
  }
1169
1169
  },
1170
1170
  {
@@ -1187,7 +1187,7 @@
1187
1187
  "stats": {
1188
1188
  "size": 3703,
1189
1189
  "lines": 21,
1190
- "lastModified": "2026-10-06T13:52:08.510Z"
1190
+ "lastModified": "2026-10-07T08:09:43.934Z"
1191
1191
  }
1192
1192
  },
1193
1193
  {
@@ -1210,7 +1210,7 @@
1210
1210
  "stats": {
1211
1211
  "size": 35770,
1212
1212
  "lines": 74,
1213
- "lastModified": "2026-10-06T13:52:08.510Z"
1213
+ "lastModified": "2026-10-07T08:09:43.934Z"
1214
1214
  }
1215
1215
  },
1216
1216
  {
@@ -1233,7 +1233,7 @@
1233
1233
  "stats": {
1234
1234
  "size": 2763,
1235
1235
  "lines": 89,
1236
- "lastModified": "2026-10-06T13:52:08.512Z"
1236
+ "lastModified": "2026-10-07T08:09:43.936Z"
1237
1237
  }
1238
1238
  },
1239
1239
  {
@@ -1256,7 +1256,7 @@
1256
1256
  "stats": {
1257
1257
  "size": 1234,
1258
1258
  "lines": 48,
1259
- "lastModified": "2026-10-06T13:52:08.512Z"
1259
+ "lastModified": "2026-10-07T08:09:43.936Z"
1260
1260
  }
1261
1261
  },
1262
1262
  {
@@ -1279,7 +1279,7 @@
1279
1279
  "stats": {
1280
1280
  "size": 897,
1281
1281
  "lines": 36,
1282
- "lastModified": "2026-10-06T13:52:08.512Z"
1282
+ "lastModified": "2026-10-07T08:09:43.936Z"
1283
1283
  }
1284
1284
  },
1285
1285
  {
@@ -1302,7 +1302,7 @@
1302
1302
  "stats": {
1303
1303
  "size": 881,
1304
1304
  "lines": 34,
1305
- "lastModified": "2026-10-06T13:52:08.512Z"
1305
+ "lastModified": "2026-10-07T08:09:43.936Z"
1306
1306
  }
1307
1307
  },
1308
1308
  {
@@ -1325,7 +1325,7 @@
1325
1325
  "stats": {
1326
1326
  "size": 1587,
1327
1327
  "lines": 56,
1328
- "lastModified": "2026-10-06T13:52:08.512Z"
1328
+ "lastModified": "2026-10-07T08:09:43.936Z"
1329
1329
  }
1330
1330
  },
1331
1331
  {
@@ -1348,7 +1348,7 @@
1348
1348
  "stats": {
1349
1349
  "size": 1226,
1350
1350
  "lines": 49,
1351
- "lastModified": "2026-10-06T13:52:08.512Z"
1351
+ "lastModified": "2026-10-07T08:09:43.936Z"
1352
1352
  }
1353
1353
  },
1354
1354
  {
@@ -1371,7 +1371,7 @@
1371
1371
  "stats": {
1372
1372
  "size": 1446,
1373
1373
  "lines": 57,
1374
- "lastModified": "2026-10-06T13:52:08.512Z"
1374
+ "lastModified": "2026-10-07T08:09:43.936Z"
1375
1375
  }
1376
1376
  },
1377
1377
  {
@@ -1394,7 +1394,7 @@
1394
1394
  "stats": {
1395
1395
  "size": 293,
1396
1396
  "lines": 13,
1397
- "lastModified": "2026-10-06T13:52:08.512Z"
1397
+ "lastModified": "2026-10-07T08:09:43.936Z"
1398
1398
  }
1399
1399
  },
1400
1400
  {
@@ -1417,7 +1417,7 @@
1417
1417
  "stats": {
1418
1418
  "size": 453,
1419
1419
  "lines": 21,
1420
- "lastModified": "2026-10-06T13:52:08.512Z"
1420
+ "lastModified": "2026-10-07T08:09:43.936Z"
1421
1421
  }
1422
1422
  },
1423
1423
  {
@@ -1440,7 +1440,7 @@
1440
1440
  "stats": {
1441
1441
  "size": 149,
1442
1442
  "lines": 7,
1443
- "lastModified": "2026-10-06T13:52:08.512Z"
1443
+ "lastModified": "2026-10-07T08:09:43.936Z"
1444
1444
  }
1445
1445
  },
1446
1446
  {
@@ -1463,7 +1463,7 @@
1463
1463
  "stats": {
1464
1464
  "size": 3978,
1465
1465
  "lines": 140,
1466
- "lastModified": "2026-10-06T13:52:09.838Z"
1466
+ "lastModified": "2026-10-07T08:09:45.097Z"
1467
1467
  }
1468
1468
  },
1469
1469
  {
@@ -1486,7 +1486,7 @@
1486
1486
  "stats": {
1487
1487
  "size": 4209,
1488
1488
  "lines": 140,
1489
- "lastModified": "2026-10-06T13:52:09.838Z"
1489
+ "lastModified": "2026-10-07T08:09:45.097Z"
1490
1490
  }
1491
1491
  },
1492
1492
  {
@@ -1509,7 +1509,7 @@
1509
1509
  "stats": {
1510
1510
  "size": 9615,
1511
1511
  "lines": 318,
1512
- "lastModified": "2026-10-06T13:52:09.838Z"
1512
+ "lastModified": "2026-10-07T08:09:45.097Z"
1513
1513
  }
1514
1514
  },
1515
1515
  {
@@ -1532,7 +1532,7 @@
1532
1532
  "stats": {
1533
1533
  "size": 14891,
1534
1534
  "lines": 466,
1535
- "lastModified": "2026-10-06T13:52:09.838Z"
1535
+ "lastModified": "2026-10-07T08:09:45.096Z"
1536
1536
  }
1537
1537
  },
1538
1538
  {
@@ -1556,7 +1556,7 @@
1556
1556
  "stats": {
1557
1557
  "size": 350,
1558
1558
  "lines": 12,
1559
- "lastModified": "2026-10-06T13:52:09.867Z"
1559
+ "lastModified": "2026-10-07T08:09:45.129Z"
1560
1560
  }
1561
1561
  },
1562
1562
  {
@@ -1580,7 +1580,7 @@
1580
1580
  "stats": {
1581
1581
  "size": 77,
1582
1582
  "lines": 5,
1583
- "lastModified": "2026-10-06T13:52:09.867Z"
1583
+ "lastModified": "2026-10-07T08:09:45.129Z"
1584
1584
  }
1585
1585
  },
1586
1586
  {
@@ -1604,7 +1604,7 @@
1604
1604
  "stats": {
1605
1605
  "size": 720,
1606
1606
  "lines": 44,
1607
- "lastModified": "2026-10-06T13:52:09.867Z"
1607
+ "lastModified": "2026-10-07T08:09:45.129Z"
1608
1608
  }
1609
1609
  },
1610
1610
  {
@@ -1628,17 +1628,17 @@
1628
1628
  "stats": {
1629
1629
  "size": 7031,
1630
1630
  "lines": 276,
1631
- "lastModified": "2026-10-06T13:52:09.867Z"
1631
+ "lastModified": "2026-10-07T08:09:45.129Z"
1632
1632
  }
1633
1633
  },
1634
1634
  {
1635
- "id": "public-ui-template-theme:src:global:properties.scss",
1635
+ "id": "public-ui-template-theme:src:components:link-button.scss",
1636
1636
  "repoId": "public-ui-template-theme",
1637
- "path": "src/global/properties.scss",
1637
+ "path": "src/components/link-button.scss",
1638
1638
  "type": "code",
1639
- "content": "@mixin light {\n\t--background-color: #fff;\n\t--text-color: #282828;\n\t--text-contrast-color: #fefefe;\n\n\t--primary-color: #980c07;\n\t--accent-color: rgb(40, 40, 255);\n\n\t--tooltip-background-color: rgb(8, 8, 8, 0.9);\n\n\t--font-family: sans-serif;\n}\n\n@mixin dark {\n\t--background-color: #000028;\n\t--text-color: #fefefe;\n}\n",
1639
+ "content": "@use '../mixins/button' as *;\n\n@layer kol-theme-component {\n\t@include button('kol-link');\n}\n",
1640
1640
  "metadata": {
1641
- "name": "properties.scss",
1641
+ "name": "link-button.scss",
1642
1642
  "tags": [
1643
1643
  "template",
1644
1644
  "theme",
@@ -1650,19 +1650,19 @@
1650
1650
  "language": "scss"
1651
1651
  },
1652
1652
  "stats": {
1653
- "size": 313,
1654
- "lines": 18,
1655
- "lastModified": "2026-10-06T13:52:09.867Z"
1653
+ "size": 92,
1654
+ "lines": 6,
1655
+ "lastModified": "2026-10-07T08:09:45.129Z"
1656
1656
  }
1657
1657
  },
1658
1658
  {
1659
- "id": "public-ui-template-theme:src:components:link-button.scss",
1659
+ "id": "public-ui-template-theme:src:components:button.scss",
1660
1660
  "repoId": "public-ui-template-theme",
1661
- "path": "src/components/link-button.scss",
1661
+ "path": "src/components/button.scss",
1662
1662
  "type": "code",
1663
- "content": "@use '../mixins/button' as *;\n\n@layer kol-theme-component {\n\t@include button('kol-link');\n}\n",
1663
+ "content": "@use '../mixins/button' as *;\n\n@layer kol-theme-component {\n\t@include button('kol-button');\n}\n",
1664
1664
  "metadata": {
1665
- "name": "link-button.scss",
1665
+ "name": "button.scss",
1666
1666
  "tags": [
1667
1667
  "template",
1668
1668
  "theme",
@@ -1674,19 +1674,19 @@
1674
1674
  "language": "scss"
1675
1675
  },
1676
1676
  "stats": {
1677
- "size": 92,
1677
+ "size": 94,
1678
1678
  "lines": 6,
1679
- "lastModified": "2026-10-06T13:52:09.867Z"
1679
+ "lastModified": "2026-10-07T08:09:45.129Z"
1680
1680
  }
1681
1681
  },
1682
1682
  {
1683
- "id": "public-ui-template-theme:src:components:button.scss",
1683
+ "id": "public-ui-template-theme:src:global:properties.scss",
1684
1684
  "repoId": "public-ui-template-theme",
1685
- "path": "src/components/button.scss",
1685
+ "path": "src/global/properties.scss",
1686
1686
  "type": "code",
1687
- "content": "@use '../mixins/button' as *;\n\n@layer kol-theme-component {\n\t@include button('kol-button');\n}\n",
1687
+ "content": "@mixin light {\n\t--background-color: #fff;\n\t--text-color: #282828;\n\t--text-contrast-color: #fefefe;\n\n\t--primary-color: #980c07;\n\t--accent-color: rgb(40, 40, 255);\n\n\t--tooltip-background-color: rgb(8, 8, 8, 0.9);\n\n\t--font-family: sans-serif;\n}\n\n@mixin dark {\n\t--background-color: #000028;\n\t--text-color: #fefefe;\n}\n",
1688
1688
  "metadata": {
1689
- "name": "button.scss",
1689
+ "name": "properties.scss",
1690
1690
  "tags": [
1691
1691
  "template",
1692
1692
  "theme",
@@ -1698,9 +1698,9 @@
1698
1698
  "language": "scss"
1699
1699
  },
1700
1700
  "stats": {
1701
- "size": 94,
1702
- "lines": 6,
1703
- "lastModified": "2026-10-06T13:52:09.867Z"
1701
+ "size": 313,
1702
+ "lines": 18,
1703
+ "lastModified": "2026-10-07T08:09:45.129Z"
1704
1704
  }
1705
1705
  },
1706
1706
  {
@@ -1724,7 +1724,7 @@
1724
1724
  "stats": {
1725
1725
  "size": 120,
1726
1726
  "lines": 8,
1727
- "lastModified": "2026-10-06T13:52:09.838Z"
1727
+ "lastModified": "2026-10-07T08:09:45.097Z"
1728
1728
  }
1729
1729
  },
1730
1730
  {
@@ -1747,7 +1747,7 @@
1747
1747
  "stats": {
1748
1748
  "size": 818,
1749
1749
  "lines": 32,
1750
- "lastModified": "2026-10-06T13:52:09.868Z"
1750
+ "lastModified": "2026-10-07T08:09:45.129Z"
1751
1751
  }
1752
1752
  },
1753
1753
  {
@@ -1770,7 +1770,7 @@
1770
1770
  "stats": {
1771
1771
  "size": 3041,
1772
1772
  "lines": 90,
1773
- "lastModified": "2026-10-06T13:52:09.840Z"
1773
+ "lastModified": "2026-10-07T08:09:45.099Z"
1774
1774
  }
1775
1775
  },
1776
1776
  {
@@ -1793,7 +1793,7 @@
1793
1793
  "stats": {
1794
1794
  "size": 667863,
1795
1795
  "lines": 18947,
1796
- "lastModified": "2026-10-06T13:52:09.840Z"
1796
+ "lastModified": "2026-10-07T08:09:45.099Z"
1797
1797
  }
1798
1798
  }
1799
1799
  ]