@public-ui/mcp 4.4.0-rc.0 → 4.4.0

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.4.0-rc.0",
3
+ "version": "4.4.0",
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.4.3",
51
- "@public-ui/components": "4.4.0-rc.0"
51
+ "@public-ui/components": "4.4.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@modelcontextprotocol/inspector": "2.4.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "metadata": {
3
- "generatedAt": "2026-09-07T13:52:19.220Z",
3
+ "generatedAt": "2026-09-09T07:08:55.741Z",
4
4
  "buildMode": "ci",
5
5
  "counts": {
6
6
  "total": 334,
@@ -10,7 +10,7 @@
10
10
  "totalScenarios": 20
11
11
  },
12
12
  "repo": {
13
- "commit": "cec8305b216a7738d03e4812cfbfd473eb47251b",
13
+ "commit": "9ac818e686a0ab8ef2d6e77598c2e576779cec15",
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- 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`).\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\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- 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.\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.\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`.\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### 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\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### 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 `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\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- Visual and snapshot tests can be updated with `pnpm test:update` or via the `update-snapshots.yml` GitHub workflow (see `CONTRIBUTING.md`).\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- 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`).\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\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- 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.\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.\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`.\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### 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\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### 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 `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\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
  {
@@ -333,7 +333,7 @@
333
333
  "group": "docs",
334
334
  "name": "CONTRIBUTING",
335
335
  "path": "CONTRIBUTING.md",
336
- "code": "# Contributing\n\nWe would love for you to contribute to **KoliBri**and help make it even better than it is today! As a contributor, we ask that you follow the following guidelines:\n\n- [Contributing](#contributing)\n - [Code of Conduct](#code-of-conduct)\n - [Questions and problems](#questions-and-problems)\n - [Report an error](#report-an-error)\n - [Further development](#further-development)\n - [Git flow](#git-flow)\n - [Pull Request Guidelines](#pull-request-guidelines)\n - [Developing](#developing)\n - [Develop new component](#develop-new-component)\n - [Switching between branches](#switching-between-branches)\n - [Back porting to older Major-Versions](#back-porting-to-older-major-versions)\n - [Snapshot Testing for Visual Changes](#snapshot-testing-for-visual-changes)\n - [How to Update Snapshots](#how-to-update-snapshots)\n\n## Code of Conduct\n\nHelp us keep **KoliBri** open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).\n\n## Questions and problems\n\nPlease do not create issue tickets for general support questions. We want to use the ticket system for tracking bug reports and feature requests.\n\nInstead, we recommend first checking [Stack Overflow](https://stackoverflow.com/questions/tagged/kolibri) to see whether someone else has already solved the question or problem. You can also create new questions with the tag ā€œhummingbirdā€.\nTo save your time and ours, we will close all general questions in the ticket system and redirect those asking to Stack Overflow.\n\nIf you would like to contact us, please send us an email to [kolibri@itzbund.de](mailto:kolibri@itzbund.de).\n\n## Report an error\n\nIf you find an error in the source code, you can report it to our ticket system.\n\nIt would be even better if you suggested a solution to us as a pull request.\n\n## Further development\n\nYou can request new features by submitting an issue to our ticket system. If you would like to implement a new function, please note the following steps for further action:\n\n- It is helpful to read the KoliBri [architecture concept](https://public-ui.github.io/docs/concepts/architecture) before implementing.\n- For major innovations, please create a ticket with the description of the new function.\n- For small innovations, you can offer and justify the implementation directly as a pull request.\n\n### Git flow\n\nWe work according to the Git flow: https://medium.com/android-news/gitflow-with-github-c675aa4f606a\n\n### Pull Request Guidelines\n\nWhen creating a pull request, please follow these guidelines:\n\n- **PR Title:** The pull request title must follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. This is enforced by automated validation in our CI pipeline.\n- **PR Title Format:** `<type>: <description>` or `<type>(<scope>): <description>`\n- **Allowed Types:** `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`\n- **Description:** The description should start with a lowercase letter and clearly explain the change.\n\n**Examples of valid PR titles:**\n\n- `feat: add new button component`\n- `fix: resolve navigation issue on mobile devices`\n- `docs: update installation instructions`\n- `refactor(components): simplify input validation logic`\n\n**Examples of invalid PR titles:**\n\n- `Add new feature` (missing type prefix)\n- `feat: Add feature` (description should start with lowercase)\n- `feature: add new button` (invalid type, should be `feat`)\n\n### Developing\n\n1. For contributing, you need a [GitHub account](https://github.com/login)\n2. Fork [our repository](https://github.com/public-ui/kolibri) on GitHub\n3. Open your preferred command line interface\n4. Clone the forked repository via HTTPS to your local machine. The VS Code GitHub extension can handle authentication.\n5. Navigate the project root directory\n6. Create a new branch for your changes\n7. Install Node.js version 22\n8. [Install PNPM](https://pnpm.io/installation) on you local machine\n9. Install all packages with `pnpm i`\n10. Build all packages within the mono repository `pnpm -r build`\n11. Navigate to the desired package in our monorepo\n12. When you want to start the project navigate to `packages/components/` and run `pnpm dev`\n13. To watch for changes navigate to `packages/samples/react/` and execute `pnpm start`. `http://localhost:8080/` will open automatically\n\nRun ESLint across the repository with `pnpm lint` (or `pnpm lint:eslint` to invoke ESLint directly); the configuration lives in `packages/*/eslint.config.cjs`. Formatting is handled by Prettier via `pnpm format`, so run format first to keep ESLint focused on code-quality rules rather than style drift.\n\n### VS Code Setup\n\nWe recommend using [Visual Studio Code](https://code.visualstudio.com/):\n\n- Install the Prettier and ESLint extensions.\n- Enable \"Format on Save\" in your settings.\n\n### Tests\n\nAll tests run via GitHub Actions when you open a pull request. Monitor them under the **Actions** tab.\n\n### Develop new component\n\nRefer to [new component](docs/tutorials/NEW_COMPONENT.md) tutorial.\n\n### Switching between branches\n\nWhen changing the current working branch, it is important to reinstall all dependencies, as these may have changed. It is very important that all packages are built when working on dependents. This is because the packages always use the built state of the referenced packages in the mono repo.\nTo avoid unexpected problems, it is therefore always advisable to build all packages once. This can be done with these steps:\n\n- Reinstall all dependencies: `pnpm i`\n- Build all packages: `pnpm -r build`\n- You can then switch to the package to be processed and start it with `pnpm start`.\n\nIf it is also necessary to edit dependent packages such as `@public-ui/components`, these must be rebuilt for each change. Such packages offer the `dev` script for this purpose. This automatically rebuilds the package after each change.\n\n### Back porting to older Major-Versions\n\nBy default, development is carried out in the `development` branch for the following version. However, if it becomes necessary to provide an issue for an older major release, such as version 1.x.x, the code change must also be merged into the corresponding release branch. In this case, it would be the `release/1` branch. It is important that the branch that was created from the `develop` is not merged into the release branch, as otherwise the next patch version will receive all the changes from the current development status.\nThe simplest procedure is therefore to create a new branch from the release branch (e.g. `release/1`) and transfer the individual commits of the feature branch from the `develop` to the new branch using cherry-picking. This branch can then be merged into the release branch as normal with a new pull request.\n\n### Snapshot Testing for Visual Changes\n\nThe Continuous Integration (CI) pipeline incorporates automated visual regression testing using the React sample app across all available themes.\n\nWhen introducing visual modifications to components, themes, or the React sample app, initial test failures are expected. To address this, the\n`update-snapshots.yml` action on GitHub should be executed, followed by a **careful review** of the changes.\n\n#### How to Update Snapshots\n\nThe following methods can be used to update the snapshots.\n\n1. **GitHub website:** Update the snapshots directly on the GitHub website by following these steps.\n\n- Navigate to the `Actions` tab in the `kolibri` repository.\n- Execute the `03 - Update Snapshots` action.\n- Select the desired branch in which you want to update the snapshots.\n- The workflow checks out the branch, updates all snapshot files, and commits the changes to that branch.\n\n2. **Terminal Command:** Use the [GitHub CLI (gh)](https://cli.github.com/) to run the `update-snapshots.yml` action from the local terminal. This method is recommended for updating snapshots on the current branch without navigating to the GitHub website. For terminal convenience, the [GitHub CLI (gh)](https://cli.github.com/) needs to be installed.\n\n- Run the following command within the project directory to update the snapshots in your checked-out branch:\n ```bash\n gh workflow run update-snapshots.yml -r `git rev-parse --abbrev-ref HEAD`\n ```\n- If your want to delete all snapshots before regenerating them add `-f purge_snapshots=true` to the command:\n ```bash\n gh workflow run update-snapshots.yml -r `git rev-parse --abbrev-ref HEAD` -f purge_snapshots=true\n ```\n- You can also run the action on a different branch by specifying the another target branch with the `-r <branch_name>` flag. For example, to update snapshots on the `main` branch:\n ```bash\n gh workflow run update-snapshots.yml -r main\n ```\n\nThese steps ensure that visual snapshots are updated systematically, maintaining the integrity of the testing process.\n",
336
+ "code": "# Contributing\n\nWe would love for you to contribute to **KoliBri**and help make it even better than it is today! As a contributor, we ask that you follow the following guidelines:\n\n- [Contributing](#contributing)\n - [Code of Conduct](#code-of-conduct)\n - [Questions and problems](#questions-and-problems)\n - [Report an error](#report-an-error)\n - [Further development](#further-development)\n - [Git flow](#git-flow)\n - [Pull Request Guidelines](#pull-request-guidelines)\n - [Developing](#developing)\n - [Develop new component](#develop-new-component)\n - [Switching between branches](#switching-between-branches)\n - [Back porting to older Major-Versions](#back-porting-to-older-major-versions)\n - [Snapshot Testing for Visual Changes](#snapshot-testing-for-visual-changes)\n - [How to Update Snapshots](#how-to-update-snapshots)\n\n## Code of Conduct\n\nHelp us keep **KoliBri** open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).\n\n## Questions and problems\n\nPlease do not create issue tickets for general support questions. We want to use the ticket system for tracking bug reports and feature requests.\n\nInstead, we recommend first checking [Stack Overflow](https://stackoverflow.com/questions/tagged/kolibri) to see whether someone else has already solved the question or problem. You can also create new questions with the tag ā€œhummingbirdā€.\nTo save your time and ours, we will close all general questions in the ticket system and redirect those asking to Stack Overflow.\n\nIf you would like to contact us, please send us an email to [kolibri@itzbund.de](mailto:kolibri@itzbund.de).\n\n## Report an error\n\nIf you find an error in the source code, you can report it to our ticket system.\n\nIt would be even better if you suggested a solution to us as a pull request.\n\n## Further development\n\nYou can request new features by submitting an issue to our ticket system. If you would like to implement a new function, please note the following steps for further action:\n\n- It is helpful to read the KoliBri [architecture concept](https://public-ui.github.io/docs/concepts/architecture) before implementing.\n- For major innovations, please create a ticket with the description of the new function.\n- For small innovations, you can offer and justify the implementation directly as a pull request.\n\n### Git flow\n\nWe work according to the Git flow: https://medium.com/android-news/gitflow-with-github-c675aa4f606a\n\n### Pull Request Guidelines\n\nWhen creating a pull request, please follow these guidelines:\n\n- **PR Title:** The pull request title must follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. This is enforced by automated validation in our CI pipeline.\n- **PR Title Format:** `<type>: <description>` or `<type>(<scope>): <description>`\n- **Allowed Types:** `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`\n- **Description:** The description should start with a lowercase letter and clearly explain the change.\n\n**Examples of valid PR titles:**\n\n- `feat: add new button component`\n- `fix: resolve navigation issue on mobile devices`\n- `docs: update installation instructions`\n- `refactor(components): simplify input validation logic`\n\n**Examples of invalid PR titles:**\n\n- `Add new feature` (missing type prefix)\n- `feat: Add feature` (description should start with lowercase)\n- `feature: add new button` (invalid type, should be `feat`)\n\n### Developing\n\n1. For contributing, you need a [GitHub account](https://github.com/login)\n2. Fork [our repository](https://github.com/public-ui/kolibri) on GitHub\n3. Open your preferred command line interface\n4. Clone the forked repository via HTTPS to your local machine. The VS Code GitHub extension can handle authentication.\n5. Navigate the project root directory\n6. Create a new branch for your changes\n7. Install Node.js version 22\n8. [Install PNPM](https://pnpm.io/installation) on you local machine\n9. Install all packages with `pnpm i`\n10. Build all packages within the mono repository `pnpm -r build`\n11. Navigate to the desired package in our monorepo\n12. When you want to start the project navigate to `packages/components/` and run `pnpm dev`\n13. To watch for changes navigate to `packages/samples/react/` and execute `pnpm start`. `http://localhost:8080/` will open automatically\n\nRun ESLint across the repository with `pnpm lint` (or `pnpm lint:eslint` to invoke ESLint directly); the configuration lives in `packages/*/eslint.config.cjs`. Formatting is handled by Prettier via `pnpm format`, so run format first to keep ESLint focused on code-quality rules rather than style drift.\n\n### VS Code Setup\n\nWe recommend using [Visual Studio Code](https://code.visualstudio.com/):\n\n- Install the Prettier and ESLint extensions.\n- Enable \"Format on Save\" in your settings.\n\n### Tests\n\nAll tests run via GitHub Actions when you open a pull request. Monitor them under the **Actions** tab.\n\n### Develop new component\n\nRefer to [new component](docs/tutorials/NEW_COMPONENT.md) tutorial.\n\n### Switching between branches\n\nWhen changing the current working branch, it is important to reinstall all dependencies, as these may have changed. It is very important that all packages are built when working on dependents. This is because the packages always use the built state of the referenced packages in the mono repo.\nTo avoid unexpected problems, it is therefore always advisable to build all packages once. This can be done with these steps:\n\n- Reinstall all dependencies: `pnpm i`\n- Build all packages: `pnpm -r build`\n- You can then switch to the package to be processed and start it with `pnpm start`.\n\nIf it is also necessary to edit dependent packages such as `@public-ui/components`, these must be rebuilt for each change. Such packages offer the `dev` script for this purpose. This automatically rebuilds the package after each change.\n\n### Back porting to older Major-Versions\n\nBy default, development is carried out in the `development` branch for the following version. However, if it becomes necessary to provide an issue for an older major release, such as version 1.x.x, the code change must also be merged into the corresponding release branch. In this case, it would be the `release/1` branch. It is important that the branch that was created from the `develop` is not merged into the release branch, as otherwise the next patch version will receive all the changes from the current development status.\nThe simplest procedure is therefore to create a new branch from the release branch (e.g. `release/1`) and transfer the individual commits of the feature branch from the `develop` to the new branch using cherry-picking. This branch can then be merged into the release branch as normal with a new pull request.\n\n### Visual Review for Visual Changes\n\nThe Continuous Integration (CI) pipeline takes screenshots of the React sample app in every theme and compares them with the baseline of the base branch. The screenshots are **not** stored in git: every push to `develop`, `main` and `release/*` publishes them as the artifact `visual-baseline-<package>`, and a pull request compares against the artifact of the commit it is merged with.\n\nWhen you introduce visual modifications to components, themes or the React sample app:\n\n1. The `visual-tests (<package>)` jobs report the differences. That is expected – there is nothing to regenerate or commit.\n2. The bot comment **šŸ“ø Visual Review** on the pull request links the review page (`https://public-ui.github.io/kolibri/visual/?pr=<number>`), where every changed, added and removed screenshot can be inspected side by side, with a slider, as onion skin or as diff.\n3. A reviewer with write access approves (or rejects) the screenshots there – directly with a fine-grained GitHub token, or by pasting the generated comment on the pull request. The commit status **Visual Review** turns green once everything is approved; approvals are bound to the screenshot content and survive later pushes that do not change the screenshot again.\n\nThe full process is described in [docs/visual-review.md](docs/visual-review.md).\n\n#### Running the visual tests locally\n\n```bash\npnpm snapshots:pull # download the current develop baseline into the snapshot folders (needs `gh auth login`)\npnpm --filter @public-ui/theme-default test # compare; the result is written to packages/themes/default/visual-report/\npnpm test:update:docker default # regenerate a baseline locally in the pinned Playwright container\n```\n\nScreenshots are platform specific (font rendering), so only the Docker variant produces files that match the CI.\n\n#### Text snapshots of the unit tests\n\nThe `__snapshots__` files of the unit tests (components, hydrate, hydrate-server) stay in git. Update them with `pnpm test:update:unit`, or run the `03 - Update Snapshots` action on your branch:\n\n```bash\ngh workflow run update-snapshots.yml -r `git rev-parse --abbrev-ref HEAD`\n```\n",
337
337
  "kind": "doc"
338
338
  },
339
339
  {
@@ -509,7 +509,7 @@
509
509
  "group": "docs",
510
510
  "name": "visual-review",
511
511
  "path": "docs/visual-review.md",
512
- "code": "# Visual Review\n\nHow screenshot changes of the KoliBri themes are detected, published and approved.\n\n## In one picture\n\n```\npush to develop ──► Visual Baseline workflow ──► artifact visual-baseline-<package> (per commit, 90 days)\n\npull request push ──► CI-Pipeline, job visual-tests (<package>)\n compares against the baseline of the base commit\n ──► artifact visual-review-<package> (report.json + changed images)\n │\n ā–¼\n Visual Review workflow (base repository context)\n publishes visual/pr-<n>/ on GitHub Pages\n reads the reviewers' comments\n sets the commit status \"Visual Review\"\n │\n ā–¼\nreviewer ──► https://public-ui.github.io/kolibri/visual/?pr=<n>\n inspects baseline / actual / diff, approves or rejects, leaves notes\n saves the review as a pull-request comment (directly with a token, or by pasting it)\n```\n\n## What a contributor sees\n\n- The job `visual-tests (<package>)` of the CI-Pipeline fails when screenshots differ – that is\n expected and not something to \"fix\" by regenerating snapshots. The job summary lists what changed.\n- The bot comment **šŸ“ø Visual Review** on the pull request links the review page and shows the counts\n per package.\n- The commit status **Visual Review** stays `pending` until a reviewer with write access approved every\n changed, added and removed screenshot, turns `success` then, and `failure` when a screenshot was\n rejected or a route could not be compared at all (missing block, timeout).\n- Docs-only pull requests get `success` immediately; nothing to review.\n\nNothing has to be committed: the baseline is regenerated from `develop` after the merge.\n\n## What a reviewer does\n\n1. Open the review page from the bot comment (or the status link).\n2. Walk through the changed, added and removed snapshots (`j`/`k` or the list). Compare with\n _side by side_, _slider_, _onion skin_, _diff_ or _blink_; zoom in for subpixel changes.\n3. Approve (`a`), reject or annotate each one – or **Approve all open changes** for an intentional\n sweep such as a browser upgrade.\n4. Save the review:\n - **with a token**: enter a fine-grained personal access token with _Pull requests: read and write_\n for `public-ui/kolibri` at the bottom of the page. The page posts (and later edits) one comment\n in your name. The token stays in this browser session unless you tick \"remember\".\n - **without a token**: click _Copy comment for the pull request_ and paste it as a comment on the\n pull request.\n\nThe comment carries a machine-readable block, for example:\n\n```markdown\n<!-- visual-review:v1\n{\"approveAll\":{\"digest\":\"sha256:…\"},\"approvals\":[{\"item\":\"theme-default/button-basic--variants\",\"hash\":\"sha256:…\"}],\"rejects\":[],\"notes\":[]}\n-->\n\n**Visual Review** – all changes approved ([review page](…))\n```\n\nApprovals bind to the **content hash** of a screenshot, not to a commit: a later push that leaves an\napproved screenshot untouched keeps its approval, a push that changes it again reopens exactly that\none. `approveAll` binds to the digest of the whole report and therefore expires with the next change.\n\nOnly comments of users with write access count. Bots are ignored. A rejection wins over an approval.\n\n## Where things live\n\n| What | Where |\n| -------------------------------- | ------------------------------------------------------------------------------------- |\n| Report per package (CI artifact) | `visual-review-<package>` – `report.json` + PNGs of changed items, 14 days |\n| Baseline per base commit | `visual-baseline-<package>` – snapshots + `meta.json`, 90 days |\n| Published review data | `gh-pages`: `visual/pr-<n>/report.json`, `status.json`, `<package>/<name>.<kind>.png` |\n| Review page | `gh-pages`: `visual/` (built from `packages/tools/visual-tests/review-ui`) |\n| Reporter | `packages/tools/visual-tests/src/visual-reporter.js` |\n| Workflow scripts | `scripts/visual-review/` (see `scripts/README.md`) |\n| Workflows | `visual-baseline.yml`, `visual-review.yml`, `visual-review-ui.yml`, job in `ci.yml` |\n\nThe folder `visual/pr-<n>/` is removed when the pull request closes (`pr-preview-cleanup.yml`).\n\n## Trust boundary\n\nThe reports come from the pull request's own CI run, i.e. from code the pull request controls. The\nVisual Review workflow never executes that code: it downloads the artifacts, validates every field and\nfile name (`merge-reports.mjs`) and publishes only what passes. A pull request could still upload a\nreport that claims \"no changes\" – the human review of the code and the branch protection remain the\nactual safeguard; the visual review makes intentional changes visible and reviewable, it does not\nreplace code review.\n\n## Local work\n\n```bash\npnpm snapshots:pull # fetch the current develop baseline into the snapshot folders\npnpm --filter @public-ui/theme-default test\npnpm --filter @public-ui/visual-tests review-ui:dev # the review page against a local report: ?src=<folder>\n```\n\n`pnpm test:update:docker <theme>` regenerates a baseline locally in the pinned Playwright container.\n",
512
+ "code": "# Visual Review\n\nHow screenshot changes of the KoliBri themes are detected, published and approved.\n\n## In one picture\n\n```\npush to develop ──► Visual Baseline workflow ──► artifact visual-baseline-<package> (per commit, 90 days)\n\npull request push ──► CI-Pipeline, job visual-tests (<package>)\n compares against the baseline of the base commit\n ──► artifact visual-review-<package> (report.json + changed images)\n │\n ā–¼\n Visual Review workflow (base repository context)\n publishes visual/pr-<n>/ on GitHub Pages\n reads the reviewers' comments\n sets the commit status \"Visual Review\"\n │\n ā–¼\nreviewer ──► https://public-ui.github.io/kolibri/visual/?pr=<n>\n inspects baseline / actual / diff, approves or rejects, leaves notes\n saves the review as a pull-request comment (directly with a token, or by pasting it)\n```\n\n## What a contributor sees\n\n- The job `visual-tests (<package>)` of the CI-Pipeline fails when screenshots differ – that is\n expected and not something to \"fix\" by regenerating snapshots. The job summary lists what changed.\n- The bot comment **šŸ“ø Visual Review** on the pull request links the review page and shows the counts\n per package.\n- The commit status **Visual Review** stays `pending` until a reviewer with write access approved every\n changed, added and removed screenshot, turns `success` then, and `failure` when a screenshot was\n rejected or a route could not be compared at all (missing block, timeout).\n- Docs-only pull requests get `success` immediately; nothing to review.\n\nNothing has to be committed: the baseline is regenerated from `develop` after the merge.\n\n## What a reviewer does\n\n1. Open the review page from the bot comment (or the status link).\n2. Walk through the changed, added and removed snapshots (`j`/`k` or the list). Compare with\n _side by side_, _slider_, _onion skin_, _diff_ or _blink_; zoom in for subpixel changes.\n3. Approve (`a`), reject or annotate each one – or **Approve all open changes** for an intentional\n sweep such as a browser upgrade.\n4. Save the review:\n - **with a token**: enter a fine-grained personal access token with _Pull requests: read and write_\n for `public-ui/kolibri` at the bottom of the page. The page posts (and later edits) one comment\n in your name. The token stays in this browser session unless you tick \"remember\".\n - **without a token**: click _Copy comment for the pull request_ and paste it as a comment on the\n pull request. To change your verdict later, edit that comment or post a new one – only your\n newest comment counts.\n\nThe comment carries a machine-readable block, for example:\n\n```markdown\n<!-- visual-review:v1\n{\"approveAll\":{\"digest\":\"sha256:…\"},\"approvals\":[{\"item\":\"theme-default/button-basic--variants\",\"hash\":\"sha256:…\"}],\"rejects\":[],\"notes\":[]}\n-->\n\n**Visual Review** – all changes approved ([review page](…))\n```\n\nApprovals bind to the **content hash** of a screenshot, not to a commit: a later push that leaves an\napproved screenshot untouched keeps its approval, a push that changes it again reopens exactly that\none. `approveAll` binds to the digest of the whole report and therefore expires with the next change.\n\nOnly comments of users with write access count. Bots are ignored. A rejection wins over an approval.\n\n## Where things live\n\n| What | Where |\n| -------------------------------- | ------------------------------------------------------------------------------------- |\n| Report per package (CI artifact) | `visual-review-<package>` – `report.json` + PNGs of changed items, 14 days |\n| Baseline per base commit | `visual-baseline-<package>` – snapshots + `meta.json`, 90 days |\n| Published review data | `gh-pages`: `visual/pr-<n>/report.json`, `status.json`, `<package>/<name>.<kind>.png` |\n| Review page | `gh-pages`: `visual/` (built from `packages/tools/visual-tests/review-ui`) |\n| Reporter | `packages/tools/visual-tests/src/visual-reporter.js` |\n| Workflow scripts | `scripts/visual-review/` (see `scripts/README.md`) |\n| Workflows | `visual-baseline.yml`, `visual-review.yml`, `visual-review-ui.yml`, job in `ci.yml` |\n\nThe folder `visual/pr-<n>/` is removed when the pull request closes (`pr-preview-cleanup.yml`).\n\n## Trust boundary\n\nThe reports come from the pull request's own CI run, i.e. from code the pull request controls. The\nVisual Review workflow never executes that code: it downloads the artifacts, validates every field and\nfile name (`merge-reports.mjs`) and publishes only what passes. A pull request could still upload a\nreport that claims \"no changes\" – the human review of the code and the branch protection remain the\nactual safeguard; the visual review makes intentional changes visible and reviewable, it does not\nreplace code review.\n\n## Local work\n\n```bash\npnpm snapshots:pull # fetch the current develop baseline into the snapshot folders\npnpm --filter @public-ui/theme-default test\npnpm --filter @public-ui/visual-tests review-ui:dev # the review page against a local report: ?src=<folder>\n```\n\n`pnpm test:update:docker <theme>` regenerates a baseline locally in the pinned Playwright container.\n",
513
513
  "kind": "doc"
514
514
  },
515
515
  {
@@ -18,7 +18,7 @@
18
18
  "stats": {
19
19
  "size": 9600,
20
20
  "lines": 246,
21
- "lastModified": "2026-09-07T13:50:47.899Z"
21
+ "lastModified": "2026-09-09T07:07:14.860Z"
22
22
  }
23
23
  },
24
24
  {
@@ -40,7 +40,7 @@
40
40
  "stats": {
41
41
  "size": 3486,
42
42
  "lines": 75,
43
- "lastModified": "2026-09-07T13:50:47.899Z"
43
+ "lastModified": "2026-09-09T07:07:14.860Z"
44
44
  }
45
45
  },
46
46
  {
@@ -62,7 +62,7 @@
62
62
  "stats": {
63
63
  "size": 2425,
64
64
  "lines": 98,
65
- "lastModified": "2026-09-07T13:50:47.935Z"
65
+ "lastModified": "2026-09-09T07:07:14.897Z"
66
66
  }
67
67
  },
68
68
  {
@@ -84,7 +84,7 @@
84
84
  "stats": {
85
85
  "size": 50,
86
86
  "lines": 4,
87
- "lastModified": "2026-09-07T13:50:47.935Z"
87
+ "lastModified": "2026-09-09T07:07:14.897Z"
88
88
  }
89
89
  },
90
90
  {
@@ -106,7 +106,7 @@
106
106
  "stats": {
107
107
  "size": 1549,
108
108
  "lines": 35,
109
- "lastModified": "2026-09-07T13:50:47.934Z"
109
+ "lastModified": "2026-09-09T07:07:14.896Z"
110
110
  }
111
111
  },
112
112
  {
@@ -128,7 +128,7 @@
128
128
  "stats": {
129
129
  "size": 182,
130
130
  "lines": 8,
131
- "lastModified": "2026-09-07T13:50:47.931Z"
131
+ "lastModified": "2026-09-09T07:07:14.892Z"
132
132
  }
133
133
  },
134
134
  {
@@ -150,7 +150,7 @@
150
150
  "stats": {
151
151
  "size": 4276,
152
152
  "lines": 75,
153
- "lastModified": "2026-09-07T13:50:47.922Z"
153
+ "lastModified": "2026-09-09T07:07:14.884Z"
154
154
  }
155
155
  },
156
156
  {
@@ -172,7 +172,7 @@
172
172
  "stats": {
173
173
  "size": 2812,
174
174
  "lines": 74,
175
- "lastModified": "2026-09-07T13:50:47.915Z"
175
+ "lastModified": "2026-09-09T07:07:14.876Z"
176
176
  }
177
177
  },
178
178
  {
@@ -194,7 +194,7 @@
194
194
  "stats": {
195
195
  "size": 587,
196
196
  "lines": 56,
197
- "lastModified": "2026-09-07T13:50:47.912Z"
197
+ "lastModified": "2026-09-09T07:07:14.873Z"
198
198
  }
199
199
  },
200
200
  {
@@ -216,7 +216,7 @@
216
216
  "stats": {
217
217
  "size": 566,
218
218
  "lines": 50,
219
- "lastModified": "2026-09-07T13:50:47.910Z"
219
+ "lastModified": "2026-09-09T07:07:14.872Z"
220
220
  }
221
221
  },
222
222
  {
@@ -238,7 +238,7 @@
238
238
  "stats": {
239
239
  "size": 568,
240
240
  "lines": 50,
241
- "lastModified": "2026-09-07T13:50:47.909Z"
241
+ "lastModified": "2026-09-09T07:07:14.870Z"
242
242
  }
243
243
  },
244
244
  {
@@ -260,7 +260,7 @@
260
260
  "stats": {
261
261
  "size": 601,
262
262
  "lines": 45,
263
- "lastModified": "2026-09-07T13:50:47.902Z"
263
+ "lastModified": "2026-09-09T07:07:14.864Z"
264
264
  }
265
265
  },
266
266
  {
@@ -282,7 +282,7 @@
282
282
  "stats": {
283
283
  "size": 587,
284
284
  "lines": 56,
285
- "lastModified": "2026-09-07T13:50:47.903Z"
285
+ "lastModified": "2026-09-09T07:07:14.865Z"
286
286
  }
287
287
  },
288
288
  {
@@ -304,7 +304,7 @@
304
304
  "stats": {
305
305
  "size": 566,
306
306
  "lines": 50,
307
- "lastModified": "2026-09-07T13:50:47.901Z"
307
+ "lastModified": "2026-09-09T07:07:14.862Z"
308
308
  }
309
309
  },
310
310
  {
@@ -326,7 +326,7 @@
326
326
  "stats": {
327
327
  "size": 615,
328
328
  "lines": 50,
329
- "lastModified": "2026-09-07T13:50:47.900Z"
329
+ "lastModified": "2026-09-09T07:07:14.861Z"
330
330
  }
331
331
  },
332
332
  {
@@ -348,7 +348,7 @@
348
348
  "stats": {
349
349
  "size": 31,
350
350
  "lines": 2,
351
- "lastModified": "2026-09-07T13:50:47.920Z"
351
+ "lastModified": "2026-09-09T07:07:14.881Z"
352
352
  }
353
353
  },
354
354
  {
@@ -370,7 +370,7 @@
370
370
  "stats": {
371
371
  "size": 31,
372
372
  "lines": 2,
373
- "lastModified": "2026-09-07T13:50:47.919Z"
373
+ "lastModified": "2026-09-09T07:07:14.881Z"
374
374
  }
375
375
  },
376
376
  {
@@ -392,7 +392,7 @@
392
392
  "stats": {
393
393
  "size": 25,
394
394
  "lines": 2,
395
- "lastModified": "2026-09-07T13:50:47.917Z"
395
+ "lastModified": "2026-09-09T07:07:14.878Z"
396
396
  }
397
397
  },
398
398
  {
@@ -414,7 +414,7 @@
414
414
  "stats": {
415
415
  "size": 327,
416
416
  "lines": 19,
417
- "lastModified": "2026-09-07T13:50:47.915Z"
417
+ "lastModified": "2026-09-09T07:07:14.877Z"
418
418
  }
419
419
  },
420
420
  {
@@ -436,7 +436,7 @@
436
436
  "stats": {
437
437
  "size": 416,
438
438
  "lines": 2,
439
- "lastModified": "2026-09-07T13:50:47.910Z"
439
+ "lastModified": "2026-09-09T07:07:14.871Z"
440
440
  }
441
441
  },
442
442
  {
@@ -458,7 +458,7 @@
458
458
  "stats": {
459
459
  "size": 416,
460
460
  "lines": 2,
461
- "lastModified": "2026-09-07T13:50:47.902Z"
461
+ "lastModified": "2026-09-09T07:07:14.863Z"
462
462
  }
463
463
  },
464
464
  {
@@ -481,7 +481,7 @@
481
481
  "stats": {
482
482
  "size": 88,
483
483
  "lines": 6,
484
- "lastModified": "2026-09-07T13:50:47.931Z"
484
+ "lastModified": "2026-09-09T07:07:14.892Z"
485
485
  }
486
486
  },
487
487
  {
@@ -503,7 +503,7 @@
503
503
  "stats": {
504
504
  "size": 0,
505
505
  "lines": 1,
506
- "lastModified": "2026-09-07T13:50:47.918Z"
506
+ "lastModified": "2026-09-09T07:07:14.879Z"
507
507
  }
508
508
  },
509
509
  {
@@ -525,7 +525,7 @@
525
525
  "stats": {
526
526
  "size": 0,
527
527
  "lines": 1,
528
- "lastModified": "2026-09-07T13:50:47.918Z"
528
+ "lastModified": "2026-09-09T07:07:14.880Z"
529
529
  }
530
530
  },
531
531
  {
@@ -547,7 +547,7 @@
547
547
  "stats": {
548
548
  "size": 21,
549
549
  "lines": 2,
550
- "lastModified": "2026-09-07T13:50:47.918Z"
550
+ "lastModified": "2026-09-09T07:07:14.879Z"
551
551
  }
552
552
  },
553
553
  {
@@ -569,7 +569,7 @@
569
569
  "stats": {
570
570
  "size": 23,
571
571
  "lines": 2,
572
- "lastModified": "2026-09-07T13:50:47.918Z"
572
+ "lastModified": "2026-09-09T07:07:14.879Z"
573
573
  }
574
574
  },
575
575
  {
@@ -591,7 +591,7 @@
591
591
  "stats": {
592
592
  "size": 25,
593
593
  "lines": 2,
594
- "lastModified": "2026-09-07T13:50:47.917Z"
594
+ "lastModified": "2026-09-09T07:07:14.879Z"
595
595
  }
596
596
  },
597
597
  {
@@ -613,7 +613,7 @@
613
613
  "stats": {
614
614
  "size": 220,
615
615
  "lines": 20,
616
- "lastModified": "2026-09-07T13:50:47.919Z"
616
+ "lastModified": "2026-09-09T07:07:14.880Z"
617
617
  }
618
618
  },
619
619
  {
@@ -635,7 +635,7 @@
635
635
  "stats": {
636
636
  "size": 587,
637
637
  "lines": 56,
638
- "lastModified": "2026-09-07T13:50:48.305Z"
638
+ "lastModified": "2026-09-09T07:07:15.233Z"
639
639
  }
640
640
  },
641
641
  {
@@ -658,7 +658,7 @@
658
658
  "stats": {
659
659
  "size": 472,
660
660
  "lines": 14,
661
- "lastModified": "2026-09-07T13:50:48.311Z"
661
+ "lastModified": "2026-09-09T07:07:15.245Z"
662
662
  }
663
663
  },
664
664
  {
@@ -681,7 +681,7 @@
681
681
  "stats": {
682
682
  "size": 35,
683
683
  "lines": 4,
684
- "lastModified": "2026-09-07T13:50:48.311Z"
684
+ "lastModified": "2026-09-09T07:07:15.245Z"
685
685
  }
686
686
  },
687
687
  {
@@ -704,7 +704,7 @@
704
704
  "stats": {
705
705
  "size": 43,
706
706
  "lines": 2,
707
- "lastModified": "2026-09-07T13:50:48.311Z"
707
+ "lastModified": "2026-09-09T07:07:15.245Z"
708
708
  }
709
709
  },
710
710
  {
@@ -727,7 +727,7 @@
727
727
  "stats": {
728
728
  "size": 916,
729
729
  "lines": 39,
730
- "lastModified": "2026-09-07T13:50:48.311Z"
730
+ "lastModified": "2026-09-09T07:07:15.245Z"
731
731
  }
732
732
  },
733
733
  {
@@ -750,7 +750,7 @@
750
750
  "stats": {
751
751
  "size": 368,
752
752
  "lines": 13,
753
- "lastModified": "2026-09-07T13:50:48.311Z"
753
+ "lastModified": "2026-09-09T07:07:15.245Z"
754
754
  }
755
755
  },
756
756
  {
@@ -773,7 +773,7 @@
773
773
  "stats": {
774
774
  "size": 97,
775
775
  "lines": 5,
776
- "lastModified": "2026-09-07T13:50:48.311Z"
776
+ "lastModified": "2026-09-09T07:07:15.245Z"
777
777
  }
778
778
  },
779
779
  {
@@ -796,7 +796,7 @@
796
796
  "stats": {
797
797
  "size": 2358,
798
798
  "lines": 44,
799
- "lastModified": "2026-09-07T13:50:48.311Z"
799
+ "lastModified": "2026-09-09T07:07:15.245Z"
800
800
  }
801
801
  },
802
802
  {
@@ -819,7 +819,7 @@
819
819
  "stats": {
820
820
  "size": 9997,
821
821
  "lines": 367,
822
- "lastModified": "2026-09-07T13:50:48.309Z"
822
+ "lastModified": "2026-09-09T07:07:15.240Z"
823
823
  }
824
824
  },
825
825
  {
@@ -842,7 +842,7 @@
842
842
  "stats": {
843
843
  "size": 1199,
844
844
  "lines": 34,
845
- "lastModified": "2026-09-07T13:50:48.309Z"
845
+ "lastModified": "2026-09-09T07:07:15.240Z"
846
846
  }
847
847
  },
848
848
  {
@@ -865,7 +865,7 @@
865
865
  "stats": {
866
866
  "size": 10353,
867
867
  "lines": 555,
868
- "lastModified": "2026-09-07T13:50:48.308Z"
868
+ "lastModified": "2026-09-09T07:07:15.240Z"
869
869
  }
870
870
  },
871
871
  {
@@ -888,7 +888,7 @@
888
888
  "stats": {
889
889
  "size": 646,
890
890
  "lines": 21,
891
- "lastModified": "2026-09-07T13:50:48.311Z"
891
+ "lastModified": "2026-09-09T07:07:15.244Z"
892
892
  }
893
893
  },
894
894
  {
@@ -911,7 +911,7 @@
911
911
  "stats": {
912
912
  "size": 519,
913
913
  "lines": 19,
914
- "lastModified": "2026-09-07T13:50:48.311Z"
914
+ "lastModified": "2026-09-09T07:07:15.244Z"
915
915
  }
916
916
  },
917
917
  {
@@ -934,7 +934,7 @@
934
934
  "stats": {
935
935
  "size": 670,
936
936
  "lines": 22,
937
- "lastModified": "2026-09-07T13:50:48.310Z"
937
+ "lastModified": "2026-09-09T07:07:15.243Z"
938
938
  }
939
939
  },
940
940
  {
@@ -957,7 +957,7 @@
957
957
  "stats": {
958
958
  "size": 3451,
959
959
  "lines": 9,
960
- "lastModified": "2026-09-07T13:50:48.310Z"
960
+ "lastModified": "2026-09-09T07:07:15.242Z"
961
961
  }
962
962
  },
963
963
  {
@@ -980,7 +980,7 @@
980
980
  "stats": {
981
981
  "size": 10313,
982
982
  "lines": 46,
983
- "lastModified": "2026-09-07T13:50:48.310Z"
983
+ "lastModified": "2026-09-09T07:07:15.242Z"
984
984
  }
985
985
  },
986
986
  {
@@ -1003,7 +1003,7 @@
1003
1003
  "stats": {
1004
1004
  "size": 107635,
1005
1005
  "lines": 364,
1006
- "lastModified": "2026-09-07T13:50:48.310Z"
1006
+ "lastModified": "2026-09-09T07:07:15.242Z"
1007
1007
  }
1008
1008
  },
1009
1009
  {
@@ -1026,7 +1026,7 @@
1026
1026
  "stats": {
1027
1027
  "size": 64024,
1028
1028
  "lines": 323,
1029
- "lastModified": "2026-09-07T13:50:48.310Z"
1029
+ "lastModified": "2026-09-09T07:07:15.242Z"
1030
1030
  }
1031
1031
  },
1032
1032
  {
@@ -1049,7 +1049,7 @@
1049
1049
  "stats": {
1050
1050
  "size": 23737,
1051
1051
  "lines": 110,
1052
- "lastModified": "2026-09-07T13:50:48.310Z"
1052
+ "lastModified": "2026-09-09T07:07:15.242Z"
1053
1053
  }
1054
1054
  },
1055
1055
  {
@@ -1072,7 +1072,7 @@
1072
1072
  "stats": {
1073
1073
  "size": 18200,
1074
1074
  "lines": 75,
1075
- "lastModified": "2026-09-07T13:50:48.310Z"
1075
+ "lastModified": "2026-09-09T07:07:15.242Z"
1076
1076
  }
1077
1077
  },
1078
1078
  {
@@ -1095,7 +1095,7 @@
1095
1095
  "stats": {
1096
1096
  "size": 12909,
1097
1097
  "lines": 87,
1098
- "lastModified": "2026-09-07T13:50:48.310Z"
1098
+ "lastModified": "2026-09-09T07:07:15.242Z"
1099
1099
  }
1100
1100
  },
1101
1101
  {
@@ -1118,7 +1118,7 @@
1118
1118
  "stats": {
1119
1119
  "size": 19632,
1120
1120
  "lines": 75,
1121
- "lastModified": "2026-09-07T13:50:48.310Z"
1121
+ "lastModified": "2026-09-09T07:07:15.242Z"
1122
1122
  }
1123
1123
  },
1124
1124
  {
@@ -1141,7 +1141,7 @@
1141
1141
  "stats": {
1142
1142
  "size": 8806,
1143
1143
  "lines": 38,
1144
- "lastModified": "2026-09-07T13:50:48.310Z"
1144
+ "lastModified": "2026-09-09T07:07:15.242Z"
1145
1145
  }
1146
1146
  },
1147
1147
  {
@@ -1164,7 +1164,7 @@
1164
1164
  "stats": {
1165
1165
  "size": 103382,
1166
1166
  "lines": 377,
1167
- "lastModified": "2026-09-07T13:50:48.310Z"
1167
+ "lastModified": "2026-09-09T07:07:15.242Z"
1168
1168
  }
1169
1169
  },
1170
1170
  {
@@ -1187,7 +1187,7 @@
1187
1187
  "stats": {
1188
1188
  "size": 3703,
1189
1189
  "lines": 21,
1190
- "lastModified": "2026-09-07T13:50:48.310Z"
1190
+ "lastModified": "2026-09-09T07:07:15.242Z"
1191
1191
  }
1192
1192
  },
1193
1193
  {
@@ -1210,7 +1210,7 @@
1210
1210
  "stats": {
1211
1211
  "size": 35770,
1212
1212
  "lines": 74,
1213
- "lastModified": "2026-09-07T13:50:48.309Z"
1213
+ "lastModified": "2026-09-09T07:07:15.240Z"
1214
1214
  }
1215
1215
  },
1216
1216
  {
@@ -1233,7 +1233,7 @@
1233
1233
  "stats": {
1234
1234
  "size": 2763,
1235
1235
  "lines": 89,
1236
- "lastModified": "2026-09-07T13:50:48.311Z"
1236
+ "lastModified": "2026-09-09T07:07:15.245Z"
1237
1237
  }
1238
1238
  },
1239
1239
  {
@@ -1256,7 +1256,7 @@
1256
1256
  "stats": {
1257
1257
  "size": 1234,
1258
1258
  "lines": 48,
1259
- "lastModified": "2026-09-07T13:50:48.311Z"
1259
+ "lastModified": "2026-09-09T07:07:15.245Z"
1260
1260
  }
1261
1261
  },
1262
1262
  {
@@ -1279,7 +1279,7 @@
1279
1279
  "stats": {
1280
1280
  "size": 897,
1281
1281
  "lines": 36,
1282
- "lastModified": "2026-09-07T13:50:48.311Z"
1282
+ "lastModified": "2026-09-09T07:07:15.245Z"
1283
1283
  }
1284
1284
  },
1285
1285
  {
@@ -1302,7 +1302,7 @@
1302
1302
  "stats": {
1303
1303
  "size": 881,
1304
1304
  "lines": 34,
1305
- "lastModified": "2026-09-07T13:50:48.311Z"
1305
+ "lastModified": "2026-09-09T07:07:15.245Z"
1306
1306
  }
1307
1307
  },
1308
1308
  {
@@ -1325,7 +1325,7 @@
1325
1325
  "stats": {
1326
1326
  "size": 1587,
1327
1327
  "lines": 56,
1328
- "lastModified": "2026-09-07T13:50:48.311Z"
1328
+ "lastModified": "2026-09-09T07:07:15.245Z"
1329
1329
  }
1330
1330
  },
1331
1331
  {
@@ -1348,7 +1348,7 @@
1348
1348
  "stats": {
1349
1349
  "size": 1226,
1350
1350
  "lines": 49,
1351
- "lastModified": "2026-09-07T13:50:48.311Z"
1351
+ "lastModified": "2026-09-09T07:07:15.245Z"
1352
1352
  }
1353
1353
  },
1354
1354
  {
@@ -1371,7 +1371,7 @@
1371
1371
  "stats": {
1372
1372
  "size": 1446,
1373
1373
  "lines": 57,
1374
- "lastModified": "2026-09-07T13:50:48.311Z"
1374
+ "lastModified": "2026-09-09T07:07:15.244Z"
1375
1375
  }
1376
1376
  },
1377
1377
  {
@@ -1394,7 +1394,7 @@
1394
1394
  "stats": {
1395
1395
  "size": 293,
1396
1396
  "lines": 13,
1397
- "lastModified": "2026-09-07T13:50:48.311Z"
1397
+ "lastModified": "2026-09-09T07:07:15.245Z"
1398
1398
  }
1399
1399
  },
1400
1400
  {
@@ -1417,7 +1417,7 @@
1417
1417
  "stats": {
1418
1418
  "size": 453,
1419
1419
  "lines": 21,
1420
- "lastModified": "2026-09-07T13:50:48.311Z"
1420
+ "lastModified": "2026-09-09T07:07:15.245Z"
1421
1421
  }
1422
1422
  },
1423
1423
  {
@@ -1440,7 +1440,7 @@
1440
1440
  "stats": {
1441
1441
  "size": 149,
1442
1442
  "lines": 7,
1443
- "lastModified": "2026-09-07T13:50:48.311Z"
1443
+ "lastModified": "2026-09-09T07:07:15.245Z"
1444
1444
  }
1445
1445
  },
1446
1446
  {
@@ -1463,7 +1463,7 @@
1463
1463
  "stats": {
1464
1464
  "size": 3978,
1465
1465
  "lines": 140,
1466
- "lastModified": "2026-09-07T13:50:48.714Z"
1466
+ "lastModified": "2026-09-09T07:07:15.625Z"
1467
1467
  }
1468
1468
  },
1469
1469
  {
@@ -1486,7 +1486,7 @@
1486
1486
  "stats": {
1487
1487
  "size": 4209,
1488
1488
  "lines": 140,
1489
- "lastModified": "2026-09-07T13:50:48.714Z"
1489
+ "lastModified": "2026-09-09T07:07:15.625Z"
1490
1490
  }
1491
1491
  },
1492
1492
  {
@@ -1509,7 +1509,7 @@
1509
1509
  "stats": {
1510
1510
  "size": 9615,
1511
1511
  "lines": 318,
1512
- "lastModified": "2026-09-07T13:50:48.714Z"
1512
+ "lastModified": "2026-09-09T07:07:15.625Z"
1513
1513
  }
1514
1514
  },
1515
1515
  {
@@ -1532,7 +1532,7 @@
1532
1532
  "stats": {
1533
1533
  "size": 14891,
1534
1534
  "lines": 466,
1535
- "lastModified": "2026-09-07T13:50:48.714Z"
1535
+ "lastModified": "2026-09-09T07:07:15.625Z"
1536
1536
  }
1537
1537
  },
1538
1538
  {
@@ -1556,7 +1556,7 @@
1556
1556
  "stats": {
1557
1557
  "size": 350,
1558
1558
  "lines": 12,
1559
- "lastModified": "2026-09-07T13:50:48.745Z"
1559
+ "lastModified": "2026-09-09T07:07:15.654Z"
1560
1560
  }
1561
1561
  },
1562
1562
  {
@@ -1580,7 +1580,7 @@
1580
1580
  "stats": {
1581
1581
  "size": 77,
1582
1582
  "lines": 5,
1583
- "lastModified": "2026-09-07T13:50:48.745Z"
1583
+ "lastModified": "2026-09-09T07:07:15.654Z"
1584
1584
  }
1585
1585
  },
1586
1586
  {
@@ -1604,7 +1604,7 @@
1604
1604
  "stats": {
1605
1605
  "size": 720,
1606
1606
  "lines": 44,
1607
- "lastModified": "2026-09-07T13:50:48.745Z"
1607
+ "lastModified": "2026-09-09T07:07:15.654Z"
1608
1608
  }
1609
1609
  },
1610
1610
  {
@@ -1628,7 +1628,7 @@
1628
1628
  "stats": {
1629
1629
  "size": 7031,
1630
1630
  "lines": 276,
1631
- "lastModified": "2026-09-07T13:50:48.745Z"
1631
+ "lastModified": "2026-09-09T07:07:15.654Z"
1632
1632
  }
1633
1633
  },
1634
1634
  {
@@ -1652,7 +1652,7 @@
1652
1652
  "stats": {
1653
1653
  "size": 313,
1654
1654
  "lines": 18,
1655
- "lastModified": "2026-09-07T13:50:48.745Z"
1655
+ "lastModified": "2026-09-09T07:07:15.654Z"
1656
1656
  }
1657
1657
  },
1658
1658
  {
@@ -1676,7 +1676,7 @@
1676
1676
  "stats": {
1677
1677
  "size": 92,
1678
1678
  "lines": 6,
1679
- "lastModified": "2026-09-07T13:50:48.745Z"
1679
+ "lastModified": "2026-09-09T07:07:15.654Z"
1680
1680
  }
1681
1681
  },
1682
1682
  {
@@ -1700,7 +1700,7 @@
1700
1700
  "stats": {
1701
1701
  "size": 94,
1702
1702
  "lines": 6,
1703
- "lastModified": "2026-09-07T13:50:48.745Z"
1703
+ "lastModified": "2026-09-09T07:07:15.654Z"
1704
1704
  }
1705
1705
  },
1706
1706
  {
@@ -1724,7 +1724,7 @@
1724
1724
  "stats": {
1725
1725
  "size": 120,
1726
1726
  "lines": 8,
1727
- "lastModified": "2026-09-07T13:50:48.714Z"
1727
+ "lastModified": "2026-09-09T07:07:15.625Z"
1728
1728
  }
1729
1729
  },
1730
1730
  {
@@ -1747,7 +1747,7 @@
1747
1747
  "stats": {
1748
1748
  "size": 818,
1749
1749
  "lines": 32,
1750
- "lastModified": "2026-09-07T13:50:48.746Z"
1750
+ "lastModified": "2026-09-09T07:07:15.654Z"
1751
1751
  }
1752
1752
  },
1753
1753
  {
@@ -1770,7 +1770,7 @@
1770
1770
  "stats": {
1771
1771
  "size": 3041,
1772
1772
  "lines": 90,
1773
- "lastModified": "2026-09-07T13:50:48.716Z"
1773
+ "lastModified": "2026-09-09T07:07:15.627Z"
1774
1774
  }
1775
1775
  },
1776
1776
  {
@@ -1793,7 +1793,7 @@
1793
1793
  "stats": {
1794
1794
  "size": 667863,
1795
1795
  "lines": 18947,
1796
- "lastModified": "2026-09-07T13:50:48.716Z"
1796
+ "lastModified": "2026-09-09T07:07:15.626Z"
1797
1797
  }
1798
1798
  }
1799
1799
  ]