diff --git a/.cspell-project-words.txt b/.cspell-project-words.txt
index a3a6be5a032a505498aefc21bc13468bffbd203e..22ad45387850e3386535b91bc66236690f09678e 100644
--- a/.cspell-project-words.txt
+++ b/.cspell-project-words.txt
@@ -1,17 +1,29 @@
+behaviours
+ctahref
+hotwire
+htmx
 canonicalizer
 canonicalized
+coloris
+contextful
 corge
 criticals
+daisyui
+dsfr
 endsandbox
+favourite
 getattr
 grault
 kint
 maxcontains
 mincontains
+pdureau
 proptype
+pymdownx
 recursivity
 sameas
 sdc's
+spottable
 subcomponent
 toolset
-daisyui
+uswds
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1d7482b9f8a1f68b073ef8b1ca42e8325c821d11..f5d41b281b98054cc5938e68b9151f5d95949881 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -60,11 +60,32 @@ include:
     paths:
       - twig-lint-quality-report.xml
 
+.prettier-lint-base:
+  stage: validate
+  script:
+    - echo "Prettier version $(${CI_PROJECT_DIR}/${_WEB_ROOT}/core/node_modules/.bin/prettier --version)"
+    - ${CI_PROJECT_DIR}/${_WEB_ROOT}/core/node_modules/.bin/prettier --check ${CI_PROJECT_DIR}/docs/
+  rules:
+    - changes:
+        - "docs/*.md"
+        - "docs/**/*.md"
+  allow_failure: false
+  artifacts:
+    expose_as: prettier-lint
+    when: always
+    expire_in: 6 mos
+    reports:
+      codequality: prettier-lint-quality-report.xml
+    name: artifacts-$CI_PIPELINE_ID-$CI_JOB_NAME_SLUG
+    paths:
+      - prettier-lint-quality-report.xml
 
 phpmd:
   extends: .phpmd-base
 twig-lint:
   extends: .twig-lint-base
+prettier-lint:
+  extends: .prettier-lint-base
 composer-lint:
   allow_failure: false
 cspell:
diff --git a/README.md b/README.md
index 5dac28d32fad20f154b6f256de1105bfa96e3908..fcb55506a5cc52bf9f86406a60dccd4f952eb1a8 100644
--- a/README.md
+++ b/README.md
@@ -8,27 +8,20 @@ Components are reusable, nestable, guided by clear standards, and can be assembl
 
 The UI Patterns project provides 3 "toolset" modules:
 
-- **UI Patterns**: the main module, based on Drupal Core SDC API, with additional powerful API and quality-of-life improvements
-- **UI Patterns Library**: generates a pattern library page available at `/patterns`
+- **UI Patterns**: the main module, based on Drupal Core SDC API, with some extra features and quality-of-life improvements
+- **UI Patterns Library**: generates a pattern library page available at `/admin/appearance/ui/components`
   to be used as documentation for content editors or as a showcase for business. Use this module if you don't plan to
   use more advanced component library systems such as Storybook, PatternLab or Fractal.
-  [Learn more](https://www.drupal.org/docs/contributed-modules/ui-patterns/define-your-patterns)
 - **UI Patterns Legacy**: Load your UI Patterns 1.x components inside UI Patterns 2.x
 
 4 "integration" modules:
 
 - **UI Patterns Layouts**: allows to use components as layouts. This allows patterns to be used with Layout Builder,
-  [Display Suite](https://www.drupal.org/project/ds) or [Panels](https://www.drupal.org/project/panels)
-  out of the box. [Learn more](https://www.drupal.org/docs/contributed-modules/ui-patterns/use-patterns-as-layouts)
+  [Display Suite](https://www.drupal.org/project/ds) or [Layout Paragraphs](https://www.drupal.org/project/layout_paragraphs)
+  out of the box.
 - **UI Patterns Blocks**: allows to use components as Blocks plugins.
 - **UI Patterns Field Formatters**: allows to use components as Field Formatters plugins.
 - **UI Patterns Views**: allows to use components as Views styles or Views rows plugins.
-  [Learn more](https://www.drupal.org/docs/contributed-modules/ui-patterns/use-patterns-with-views)
-
-1 "devel" module:
-
-- **UI Patterns Devel**: provide some tools to help developers working with Component. Currently a Twig static
-  validator to detect errors and help follow good practices for UI Patterns.
 
 ## Documentation
 
diff --git a/docs/1-users/0-component-form.md b/docs/1-users/0-component-form.md
new file mode 100644
index 0000000000000000000000000000000000000000..691e1c713464c8dee1a45ecb70691af6e85843fe
--- /dev/null
+++ b/docs/1-users/0-component-form.md
@@ -0,0 +1,115 @@
+# Component form
+
+The biggest feature of UI Patterns is the generation of forms from the components definition:
+
+| From component definition....     | ... to component form   |
+| --------------------------------- | ----------------------- |
+| ![](images/bs-alert-example.webp) | ![](images/form-1.webp) |
+
+Those forms will be shown everywhere a component is used:
+
+- [as blocks](1-as-block.md)
+- [as layouts](1-as-block.md)
+- [in field formatters](1-as-block.md)
+- [in views](1-as-block.md)
+- ...
+
+## Data sources
+
+Values are taken from sources:
+
+- "Widgets": simple form elements storing directly the data filled by the user. For example, a `textfield` for a string or a `checkbox` for a boolean.
+- Sources retrieving data from Drupal API: they can be context agnostic (ex: a menu for links) or context specific (ex: the title field for a string)
+- Context switchers: They don't retrieve data but they give access to other data sources. For example, the author fields from an article content.
+
+If there is only a single source available, the source form is directly displayed:
+
+![](images/sources-1.webp)
+
+If there are at least 2, a source selector is shown:
+
+![](images/sources-2.webp)
+
+Some sources doesn't have a form, selecting the source is enough:
+
+![](images/sources-3.webp)
+
+## Context
+
+Sometimes sources require another object in order to retrieve the data. This is known as context.
+
+Some source doesn't need a context and are site wide, for example:
+
+- All “widgets” which are source plugins with only direct input: Textfield, Select, Checkbox…
+- List of all menus
+- The breadcrumb
+- …
+
+But some of them will need context. Examples:
+
+| Context         | Source              | Prop type | Description                                |
+| --------------- | ------------------- | --------- | ------------------------------------------ |
+| Content entity  | Data from a field   |           | Switch to a Field context.                 |
+| Content entity  | Entity link         | URL       |
+| Content entity  | Referenced entities |           | Switch to an other Content entity context. |
+| Field           | Field formatter     | Slot      |
+| Field           | Field label         | String    |
+| Field           | Field prop : \*     | (many)    |
+| Reference field | Field prop: entity  |           | Switch to a Content entity context.        |
+| View            | View title          | String    |
+| View            | View rows           | Slot      |
+| View row        | View title          | String    |
+| View row        | View field          | Slot      |
+
+## Variant selector
+
+Some components have variants, a list of different "look" of the component. Variants doesn't change the model or the meaning of the component, only the look.
+
+![](images/variant-1.webp)
+
+## Slots
+
+SDC components are made of slots & props:
+
+- **Slots**: “areas” for free renderables only, like Drupal blocks or other SDC components for example.
+- **Props**: strictly typed data only, for some UI logic in the template.
+
+You can draw the slots areas in a component screenshot:
+
+![](images/slots-vs-props.webp)
+
+For each slots, its is possible to add one or many sources:
+
+![](images/slot-1.webp)
+
+For example:
+
+- "Component": nest another SDC component in the slot.
+- "Block": add a Drupal block plugin
+- "Wysiwyg": a simple text editor, using the text formats defined in your site.
+
+Other modules can add other sources. For example, "Icon" in this screenshot is brought by https://www.drupal.org/project/ui_icons
+
+Once a source is added, it can be configured and we can add more because the selector is still present:
+
+![](images/slot-2.webp)
+
+Sources can be reordered inside a slot.
+
+Using the "Component" source, we have access to the embedded component slots and we can nest data:
+
+![](images/slot-3.webp)
+
+## Props
+
+A bit like the form for slots with 2 main differences:
+
+- We don’t allow multiple items, so we can replace the source but not add some (and of course no reordering)
+- The default source form is already loaded.
+
+![](images/props-1.webp)
+
+The available sources are varying according to both:
+
+- the prop type. Each prop as a type, which is related to its JSON schema typing, but not exactly the same. You can check what type has a prop in the [component library](../2-authors/1-stories-and-library.md). A prop without a type is not displayed in the form.
+- the context, as explained before.
diff --git a/docs/1-users/1-as-block.md b/docs/1-users/1-as-block.md
new file mode 100644
index 0000000000000000000000000000000000000000..6a8539eeccaa1de58b9ef597982d9043c781d398
--- /dev/null
+++ b/docs/1-users/1-as-block.md
@@ -0,0 +1,41 @@
+# Using a component as a Drupal block
+
+You need to activate `ui_patterns_blocks` sub-module.
+
+Blocks are boxes of content rendered into an area, or region, of a web page (such as "User Login" or "Who's online") that can be displayed in regions (such as footer or sidebar) on your page or content display.
+
+## In Block Layout (`/admin/structure/block`)
+
+Every UI component is a Drupal block plugin, available in the "Place block" modal:
+
+![](images/block-1.webp)
+
+For example, to assign any component in the Header region, click on "Place Block" button and choose the component to be placed in this particular region.
+
+The component is configurable as an usual block plugin, with the [Component form](3.0-component-form.md) alongside the block title, the visibility settings and the block placement:
+
+![](images/block-2.webp)
+
+### Contextual data sources
+
+There is no specific context here. Only the generic data sources are available.
+
+## In Layout Builder
+
+Drupal's Layout Builder allows content editors and site builders to create visual layouts for displaying content. Users can customize how content is arranged on a single page, across types of content, or even create custom landing pages with an easy to use drag-and-drop interface.
+
+The Layout Builder provides the ability to drag and drop site-wide blocks and content fields into regions within a given layout.
+
+![](images/block-3.webp)
+
+Component props are available in the sidebar as block settings:
+
+![](images/block-4.webp)
+
+### Contextual data sources
+
+| Context        | Source              | Prop type | Description                                |
+| -------------- | ------------------- | --------- | ------------------------------------------ |
+| Content entity | Data from a field   |           | Switch to a Field context.                 |
+| Content entity | Entity link         | URL       |
+| Content entity | Referenced entities |           | Switch to an other Content entity context. |
diff --git a/docs/1-users/2-as-layout.md b/docs/1-users/2-as-layout.md
new file mode 100644
index 0000000000000000000000000000000000000000..596eb4ced8c50c507a11595d0135010ec41ee745
--- /dev/null
+++ b/docs/1-users/2-as-layout.md
@@ -0,0 +1,38 @@
+# Using a component as a layout
+
+You need to activate `ui_patterns_layouts` sub-module.
+
+## Layout plugins
+
+SDC components have a model quite similar to Drupal layout plugins:
+
+- Component slots are layout plugin regions
+- Component props are layout plugin settings
+
+## In Layout Builder
+
+Drupal's Layout Builder allows content editors and site builders to create visual layouts for displaying content. Users can customize how content is arranged on a single page, across types of content, or even create custom landing pages with an easy to use drag-and-drop interface.
+
+The Layout Builder provides the ability to drag and drop site-wide blocks and content fields into regions within a given layout.
+
+Each section can contain content arranged in a certain layout. Each UI component is exposed as a layout plugin:
+
+![](images/layout-1.webp)
+
+If a component has a `thumbnail.webp`, it will be shown in the layouts list:
+
+![](images/layout-3.webp)
+
+Section configuration is a [Component form](3.0-component-form.md), without the slots because slots are directly managed by Layout Builder as regions of the layout:
+
+![](images/layout-2.webp)
+
+### Contextual data sources
+
+There is no UI Patterns sources for slots here because slots are directly managed by Layout Builder as regions. So, only Drupal blocks plugins are available.
+
+| Context        | Source              | Prop type | Description                                |
+| -------------- | ------------------- | --------- | ------------------------------------------ |
+| Content entity | Data from a field   |           | Switch to a Field context.                 |
+| Content entity | Entity link         | URL       |
+| Content entity | Referenced entities |           | Switch to an other Content entity context. |
diff --git a/docs/1-users/3-in-field-formatter.md b/docs/1-users/3-in-field-formatter.md
new file mode 100644
index 0000000000000000000000000000000000000000..bc83c6b29fea20b95d7ed24577934e2644d308b8
--- /dev/null
+++ b/docs/1-users/3-in-field-formatter.md
@@ -0,0 +1,89 @@
+# Using a component in field formatters
+
+Field Formatters are Drupal plugins formatting the output of a content field. For example:
+
+- Date field formatted as "... time ago"
+- Date field formatted with a custom date format
+- Entity reference field formatted as label
+- Entity reference field formatted as a rendered entity
+- ...
+
+There are 2 field formatters provided by `ui_patterns_field_formatters` sub-module:
+
+- **Component per item**: Each item will be displayed as a component.
+- **Component**: Available only for multi-valued fields. The full field is displayed as a component.
+
+## In Manage Display
+
+Manage display manages the way your content is displayed on the frontend.
+
+The UI Patterns field formatters are available in the format select list, for every fields,
+
+![](images/formatter-1.webp)
+
+Once selected, the field formatters are configurable as usual field formatters, with the UI Patterns 2's [Component form](3.0-component-form.md)
+
+![](images/formatter-2.webp)
+
+### Contextual data sources
+
+| Context         | Source              | Prop type | Description                                |
+| --------------- | ------------------- | --------- | ------------------------------------------ |
+| Field           | Field formatter     | Slot      |
+| Field           | Field label         | String    |
+| Field           | Field prop: \*      | (many)    |
+| Reference field | Field prop: entity  |           | Switch to a Content entity context.        |
+| Content entity  | Data from a field   |           | Switch to a Field context.                 |
+| Content entity  | Entity link         | URL       |
+| Content entity  | Referenced entities |           | Switch to an other Content entity context. |
+
+## In Layout Builder
+
+Drupal's Layout Builder allows content editors and site builders to create visual layouts for displaying content. Users can customize how content is arranged on a single page, across types of content, or even create custom landing pages with an easy to use drag-and-drop interface.
+
+Fields are available as blocks:
+
+![](images/formatter-3.webp)
+
+Once selected, the field formatters are configurable as usual field formatters, with the UI Patterns 2's [Component form](3.0-component-form.md):
+
+![](images/formatter-4.webp)
+
+### Contextual data sources
+
+| Context         | Source              | Prop type | Description                                |
+| --------------- | ------------------- | --------- | ------------------------------------------ |
+| Field           | Field formatter     | Slot      |
+| Field           | Field label         | String    |
+| Field           | Field prop : \*     | (many)    |
+| Reference field | Field prop: entity  |           | Switch to a Content entity context.        |
+| Content entity  | Data from a field   |           | Switch to a Field context.                 |
+| Content entity  | Entity link         | URL       |
+| Content entity  | Referenced entities |           | Switch to an other Content entity context. |
+
+## In Views
+
+Drupal Views is both:
+
+- a query builder: fetch content from the database, with filters, sorts and grouping.
+- a display builder: present the results as lists, galleries, tables, maps, graphs, reports...
+
+If your display accepts fields, the field formatters are available:
+
+![](images/formatter-5.webp)
+
+Once selected, the field formatters are configurable as usual field formatters, with the UI Patterns 2's [Component form](3.0-component-form.md):
+
+![](images/formatter-6.webp)
+
+### Contextual data sources
+
+| Context         | Source              | Prop type | Description                                |
+| --------------- | ------------------- | --------- | ------------------------------------------ |
+| Field           | Field formatter     | Slot      |
+| Field           | Field label         | String    |
+| Field           | Field prop: \*      | (many)    |
+| Reference field | Field prop: entity  |           | Switch to a Content entity context.        |
+| Content entity  | Data from a field   |           | Switch to a Field context.                 |
+| Content entity  | Entity link         | URL       |
+| Content entity  | Referenced entities |           | Switch to an other Content entity context. |
diff --git a/docs/1-users/4-with-views.md b/docs/1-users/4-with-views.md
new file mode 100644
index 0000000000000000000000000000000000000000..b587a02a4ac7df3d32c7736a944bd6974ee88e3e
--- /dev/null
+++ b/docs/1-users/4-with-views.md
@@ -0,0 +1,63 @@
+# Using a component with Views
+
+Drupal Views is both:
+
+- a query builder: fetch content from the database, with filters, sorts and grouping.
+- a display builder: present the results as lists, galleries, tables, maps, graphs, reports...
+
+You need to activate `ui_patterns_views` sub-module.
+
+## View style plugin
+
+To build the display around the results:
+
+- the table and not the rows
+- the slider and not the slides
+- the map and not the points of interest
+- the mosaic and not the pictures
+
+### Steps
+
+Pick "Component" in the modal:
+
+![](images/views-1.webp)
+
+Select the component and fill the configuration form:
+
+[Component form](3.0-component-form.md)
+
+![](images/views-2.webp)
+
+### Contextual data sources
+
+| Context | Source     | Prop type | Description |
+| ------- | ---------- | --------- | ----------- |
+| View    | View title | String    |
+| View    | View rows  | Slot      |
+
+## View row plugin
+
+To build the display of each result:
+
+- the rows instead of the table
+- the sliders instead of the slides
+- the point of interests instead of the map
+- the pictures instead of the mosaic
+
+Pick "Component" in the modal:
+
+![](images/views-3.webp)
+
+Select the component and fill the configuration form:
+
+![](images/views-4.webp)
+
+### Contextual data sources
+
+| Context        | Source              | Prop type | Description                                |
+| -------------- | ------------------- | --------- | ------------------------------------------ |
+| View row       | View title          | String    |
+| View row       | View field          | Slot      |
+| Content entity | Data from a field   |           | Switch to a Field context.                 |
+| Content entity | Entity link         | URL       |
+| Content entity | Referenced entities |           | Switch to an other Content entity context. |
diff --git a/docs/1-users/5-presenter-templates.md b/docs/1-users/5-presenter-templates.md
new file mode 100644
index 0000000000000000000000000000000000000000..48b6b5ded0d3b781b4f56ed253fdc483f909bd5a
--- /dev/null
+++ b/docs/1-users/5-presenter-templates.md
@@ -0,0 +1,134 @@
+# Using a component in Drupal templates
+
+## Presenter templates
+
+Presenter templates are standard Drupal templates that:
+
+- transform data received from Drupal
+- use Twig [include()](http://twig.sensiolabs.org/doc/function/include.html) function to include one or more components and pass the transformed data.
+- should be totally free of markup
+- use [theme suggestions](https://www.drupal.org/docs/8/theming/twig/twig-template-naming-conventions) to plug itself to data model
+
+For example, a “normal” template has markup:
+
+```twig
+{% if subtitle %}
+<h3 class="callout__subtitle">{{ subtitle }}</h3>
+{% endif %}
+```
+
+But a presenter template has only a call to a component (and sometimes a bit of logic):
+
+```twig
+{{ include('my_theme:menu', {
+  'items': items,
+  'attributes': attributes.addClass('bg-primary'),
+}, with_context=false)}}
+```
+
+Examples of presenter templates can be found on those folders:
+
+- https://git.drupalcode.org/project/ui_suite_bootstrap/-/tree/5.1.x/templates
+- https://git.drupalcode.org/project/ui_suite_daisyui/-/tree/4.0.x/templates
+- https://git.drupalcode.org/project/ui_suite_dsfr/-/tree/1.1.x/templates
+- https://git.drupalcode.org/project/ui_suite_material/-/tree/2.0.x/templates
+- https://git.drupalcode.org/project/ui_suite_uswds/-/tree/4.0.x/templates
+
+More about presenter templates:
+
+- https://www.aleksip.net/presenting-component-projects (May 2016)
+- https://www.mediacurrent.com/blog/accommodating-drupal-your-components/ (Broken link)
+
+### Don’t use presenter templates when site building is possible
+
+Presenter templates are a clever trick, however they hurt the site building because everything which is normally set in the display settings by the site builder has to be done in a Twig file by the developer.
+
+However, there are some cases when site building is not easily possible. For examples:
+
+- rendering a menu. Menu are config entities without configurable displays.
+- rendering a content entity where the configurable display has no admin UI.
+
+🚫 Don't do presenter templates when display building is available:
+
+- Node: `/admin/structure/types/manage/{bundle}/display`
+- BlockContent: `/admin/structure/block/block-content/manage/{bundle}/display`
+- Comment: `/admin/structure/comment/manage/{bundle}/display`
+- Media: `/admin/structure/media/manage/{bundle}/display`
+- Taxonomy Term: `/admin/structure/taxonomy/manage/{bundle}/overview/display`
+- User: `/admin/config/people/accounts/display`
+- Views
+
+✅ Presenter templates are OK for renderables without display building:
+
+- Page layout: `page.html.twig` and `region.html.twig`
+- Menu config entity: `menu.html.twig`
+- ...
+
+### Slots & props
+
+Most of those templates have distinct variables for data to send to slots or props.
+
+For example, in `node.html.twig`:
+
+- `node` variable has the typed data to send to props
+- `content` has the renderable data to send to slots
+
+Other example, in `user.html.twig`:
+
+- `user` variable has the typed data to send to props
+- `content` has the renderable data to send to slots
+
+## Clean default templates
+
+Even without doing presenter templates, template overriding can be useful to clean some cruft from templates provided by core or contrib modules.
+
+The node.html.twig template is a good example, because it carries a lot of legacy junk, like a title base field display condition based on view mode name (!) and a poor man submitted by.
+
+It is better to keep those templates as lean as possible, and to push the complexity to layouts and other display modes plugins.
+
+For example:
+
+- `field.html.twig`
+- `block.html.twig`
+- `node.html.twig`
+- `taxonomy-term.html.twig`
+- `media.html.twig`
+- `comment.html.twig`
+- ...
+
+Those templates content can be replaced by:
+
+```twig
+{% if attributes.storage() %}
+<div{{ attributes }}>
+{% endif %}
+  {{ content }}
+{% if attributes.storage() %}
+</div>
+{% endif %}
+```
+
+Or sometimes, by more complex stuff like:
+
+```twig
+{% if attributes.storage() %}
+<div{{ attributes }}>
+{% endif %}
+  {{ title_prefix }}
+  {{ title_suffix }}
+  {{ content }}
+  {% if attributes.storage() %}
+  <div{{ content_attributes }}>
+  {% endif %}
+   {{ content }}
+  {% if attributes.storage() %}
+  </div>
+  {% endif %}
+{% if attributes.storage() %}
+</div>
+{% endif %}
+```
+
+Some markup of components or some utilities style expect specific markup with direct children like flex feature. Currently when trying to use those components in lists the wrappers inside templates like field.html.twig and node.html.twig will interfere with the expected markup. So sometimes even the wrappers need to be removed with templates override.
+
+Use the <a href="https://www.drupal.org/project/entity_vdts" rel="nofollow">Entity View Display Template Suggestions module</a> to be able to remove the wrapper of some entity displays. If the theme provides templates with bare minimum markup like just the "content" variable printed, for content entities with the module you will be able to remove the wrapper with configuration.
diff --git a/docs/1-users/images/block-1.webp b/docs/1-users/images/block-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..d6a2cb491dec76aced3ed37a002252b4d021abae
Binary files /dev/null and b/docs/1-users/images/block-1.webp differ
diff --git a/docs/1-users/images/block-2.webp b/docs/1-users/images/block-2.webp
new file mode 100644
index 0000000000000000000000000000000000000000..7eaf69d1f8225f3fe6fdc2d41ac86341e6df8f97
Binary files /dev/null and b/docs/1-users/images/block-2.webp differ
diff --git a/docs/1-users/images/block-3.webp b/docs/1-users/images/block-3.webp
new file mode 100644
index 0000000000000000000000000000000000000000..64fa3168f953a9af5d46b0b06a9bbab50b8634c9
Binary files /dev/null and b/docs/1-users/images/block-3.webp differ
diff --git a/docs/1-users/images/block-4.webp b/docs/1-users/images/block-4.webp
new file mode 100644
index 0000000000000000000000000000000000000000..ab321d68990710edffdb0fa8a3ee7253208d5dc5
Binary files /dev/null and b/docs/1-users/images/block-4.webp differ
diff --git a/docs/1-users/images/bs-alert-example.webp b/docs/1-users/images/bs-alert-example.webp
new file mode 100644
index 0000000000000000000000000000000000000000..60d612a073e8522ddf8924a57a3fadcf6b55c79e
Binary files /dev/null and b/docs/1-users/images/bs-alert-example.webp differ
diff --git a/docs/1-users/images/form-1.webp b/docs/1-users/images/form-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..a13abe1059956afa07ffa8c8e4b0d2ca19081f33
Binary files /dev/null and b/docs/1-users/images/form-1.webp differ
diff --git a/docs/1-users/images/formatter-1.webp b/docs/1-users/images/formatter-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..f1416ad61e26ab6731da752d1f4111c660cdb996
Binary files /dev/null and b/docs/1-users/images/formatter-1.webp differ
diff --git a/docs/1-users/images/formatter-2.webp b/docs/1-users/images/formatter-2.webp
new file mode 100644
index 0000000000000000000000000000000000000000..557c0b9c4fa0938258abfc1751a847832834cd3d
Binary files /dev/null and b/docs/1-users/images/formatter-2.webp differ
diff --git a/docs/1-users/images/formatter-3.webp b/docs/1-users/images/formatter-3.webp
new file mode 100644
index 0000000000000000000000000000000000000000..62125ab44b5be301727ece7209df4d9ae0c02869
Binary files /dev/null and b/docs/1-users/images/formatter-3.webp differ
diff --git a/docs/1-users/images/formatter-4.webp b/docs/1-users/images/formatter-4.webp
new file mode 100644
index 0000000000000000000000000000000000000000..4116e30fd2adc34001c09e43e5253cef2e7b5ccd
Binary files /dev/null and b/docs/1-users/images/formatter-4.webp differ
diff --git a/docs/1-users/images/formatter-5.webp b/docs/1-users/images/formatter-5.webp
new file mode 100644
index 0000000000000000000000000000000000000000..309a57489841ebeaf1dd94b6c809a98a8e8206aa
Binary files /dev/null and b/docs/1-users/images/formatter-5.webp differ
diff --git a/docs/1-users/images/formatter-6.webp b/docs/1-users/images/formatter-6.webp
new file mode 100644
index 0000000000000000000000000000000000000000..ea8384cca1110a7da1ab97c8c19016f5e19ebc66
Binary files /dev/null and b/docs/1-users/images/formatter-6.webp differ
diff --git a/docs/1-users/images/layout-1.webp b/docs/1-users/images/layout-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..dd5940e6f548db8903057052a6a16aa9d0acbc4e
Binary files /dev/null and b/docs/1-users/images/layout-1.webp differ
diff --git a/docs/1-users/images/layout-2.webp b/docs/1-users/images/layout-2.webp
new file mode 100644
index 0000000000000000000000000000000000000000..119d7fcc5506d9d375a452a9a9d98a5b24b8628c
Binary files /dev/null and b/docs/1-users/images/layout-2.webp differ
diff --git a/docs/1-users/images/layout-3.webp b/docs/1-users/images/layout-3.webp
new file mode 100644
index 0000000000000000000000000000000000000000..1994dfa37d6932b759966d1d44ad445890bcb50f
Binary files /dev/null and b/docs/1-users/images/layout-3.webp differ
diff --git a/docs/1-users/images/props-1.webp b/docs/1-users/images/props-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..5ebf8f13aac47189ffc92b92ae31111e86e63583
Binary files /dev/null and b/docs/1-users/images/props-1.webp differ
diff --git a/docs/1-users/images/slot-1.webp b/docs/1-users/images/slot-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..6742eb41b6b4b66d75356d843c99f35a351e26ef
Binary files /dev/null and b/docs/1-users/images/slot-1.webp differ
diff --git a/docs/1-users/images/slot-2.webp b/docs/1-users/images/slot-2.webp
new file mode 100644
index 0000000000000000000000000000000000000000..096499b8086b669055f0822520162e50dcc00af5
Binary files /dev/null and b/docs/1-users/images/slot-2.webp differ
diff --git a/docs/1-users/images/slot-3.webp b/docs/1-users/images/slot-3.webp
new file mode 100644
index 0000000000000000000000000000000000000000..42597aa5866da418604ad4e85fd391411616ce3b
Binary files /dev/null and b/docs/1-users/images/slot-3.webp differ
diff --git a/docs/1-users/images/slots-vs-props.webp b/docs/1-users/images/slots-vs-props.webp
new file mode 100644
index 0000000000000000000000000000000000000000..984d413d8d7e54d6d33ada6a9848a71e7f831f27
Binary files /dev/null and b/docs/1-users/images/slots-vs-props.webp differ
diff --git a/docs/1-users/images/sources-1.webp b/docs/1-users/images/sources-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..a9ee854cf52a04c6c72fbd1c39fcb0a8d91a2bae
Binary files /dev/null and b/docs/1-users/images/sources-1.webp differ
diff --git a/docs/1-users/images/sources-2.webp b/docs/1-users/images/sources-2.webp
new file mode 100644
index 0000000000000000000000000000000000000000..663ca76ff5024ed24283ac5861036c996faf91b8
Binary files /dev/null and b/docs/1-users/images/sources-2.webp differ
diff --git a/docs/1-users/images/sources-3.webp b/docs/1-users/images/sources-3.webp
new file mode 100644
index 0000000000000000000000000000000000000000..7d5e7143c4a088d876e65429b92e37519a750ae7
Binary files /dev/null and b/docs/1-users/images/sources-3.webp differ
diff --git a/docs/1-users/images/variant-1.webp b/docs/1-users/images/variant-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..06f106296930e410eca8638b72b6059f41bd7dfb
Binary files /dev/null and b/docs/1-users/images/variant-1.webp differ
diff --git a/docs/1-users/images/views-1.webp b/docs/1-users/images/views-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..2630a83981bf5e5f0466f2ef2fc60e7782953fa4
Binary files /dev/null and b/docs/1-users/images/views-1.webp differ
diff --git a/docs/1-users/images/views-2.webp b/docs/1-users/images/views-2.webp
new file mode 100644
index 0000000000000000000000000000000000000000..4f4193a35d823d4c589a66409b680be063e85362
Binary files /dev/null and b/docs/1-users/images/views-2.webp differ
diff --git a/docs/1-users/images/views-3.webp b/docs/1-users/images/views-3.webp
new file mode 100644
index 0000000000000000000000000000000000000000..581a763849a72f12fa3ac77c7432b9ef1fd19057
Binary files /dev/null and b/docs/1-users/images/views-3.webp differ
diff --git a/docs/1-users/images/views-4.webp b/docs/1-users/images/views-4.webp
new file mode 100644
index 0000000000000000000000000000000000000000..0175d1fdcd833c3724f6168363b8ded4a470ee66
Binary files /dev/null and b/docs/1-users/images/views-4.webp differ
diff --git a/docs/2-authors/0-authoring-a-component.md b/docs/2-authors/0-authoring-a-component.md
new file mode 100644
index 0000000000000000000000000000000000000000..8dae7534446ad07c648f919ac6aaab15983daedf
--- /dev/null
+++ b/docs/2-authors/0-authoring-a-component.md
@@ -0,0 +1,372 @@
+# Authoring a component
+
+UI Patterns 2 are SDC components, with a few additions and some better practices.
+
+So, we expects the reader to be already comfortable with SDC before reading this chapter which is complementing the SDC documentation: https://www.drupal.org/docs/develop/theming-drupal/using-single-directory-components
+
+## Links metadata
+
+UI Patterns 2 is adding the links metadata property for documentation, with both a compact and a full syntax:
+
+```yaml
+name: Example
+links:
+  - "https://test.com"
+  - url: "https://example.com"
+    title: "Example"
+props: {}
+slots: {}
+```
+
+## Tags metadata
+
+For documentation only:
+
+```yaml
+name: Example
+tags: [Foo, Bar, Baz]
+slots: {}
+props: {}
+```
+
+## Component variants
+
+A “variants” property is available in component definition.
+
+Variants are a “glorified” prop but it is still a prop. This property was added:
+
+- to ease the experience of the front developer which doesn't need to set a schema for an already well known data type
+- because JSON schema enums have no label and using a anyOf with constant is verbose and complicated
+- to show this prop will have a special treatment
+- to be able to put variant prop (and this prop only) before slots in the form builder trait.
+
+YAML:
+
+```yaml
+name: Card
+variants:
+  default:
+    title: Default
+    description: An ordinary card.
+  highlighted:
+    title: Highlighted
+    description: A special card.
+slots: {}
+props: {}
+```
+
+Once loaded, this property will also be available as a string prop with enum:
+
+```yaml
+name: Card
+props:
+  type: object
+  properties:
+    variants:
+      type: string
+      enum: [default, highlighted]
+```
+
+So it can be manipulated like that in render elements, twig functions…
+
+> Related SDC ticket: https://www.drupal.org/project/drupal/issues/3390712
+
+## Explicit prop typing
+
+Using JSON schema for props definition is enough for simple data:
+
+- `type: string` for the strings
+- `type: [number, integer]` for the numbers
+- `type: string, format: uri` for the URL
+- ...
+
+For more complicated data, we need "shortcuts", because it may be difficult for component authors to type complex schema without errors.
+
+Those shortcuts are based on a JSON schema references provider with `ui-patterns://` URL scheme.
+
+So, instead of writing the full prop schema, a component every prop type plugin is a JSON schema reference. For example:
+
+```yaml
+props:
+  type: object
+  properties:
+    figcaption_attributes:
+      title: "Figcaption attributes"
+      description: "The attributes to customize the figcaption tag."
+      "$ref": "ui-patterns://attributes"
+```
+
+JSON Schema processors can resolve this $ref and build the complete schema to validate
+
+It is important to understand the [URI is opaque](https://www.w3.org/DesignIssues/Axioms.html#opaque). In `ui-patterns://attributes` the word "attributes" means nothing. No information must be guessed from that. Only the data retrieved from the request is relevant.
+
+UI Patterns is then working on the already resolved JSON schema.
+
+UI Patterns 2.x is shipped with some prop type plugins included.
+
+### Attributes
+
+Reference shortcut: `ui-patterns://attributes`
+
+Resolved schema:
+
+```yaml
+type: object
+patternProperties:
+  ".+":
+    anyOf:
+      - type:
+          - string
+          - number
+      - type: array
+        items:
+          anyOf:
+            - type: number
+            - type: string
+```
+
+The value is transformed into an `\Drupal\Core\Template\Attribute` object before being sent to the template.
+
+### Boolean
+
+Reference shortcut: `ui-patterns://boolean`
+
+It is better to use the resolved schema:
+
+```yaml
+type: boolean
+```
+
+Default form widget: a checkbox.
+
+### List of enums
+
+Reference shortcut: `ui-patterns://enum_list`
+
+Resolved schema:
+
+```yaml
+type: array
+items:
+  type:
+    - string
+    - number
+    - integer
+  enum: []
+```
+
+Because the enum values are expected, it is better to use directly the schema like that:
+
+```yaml
+type: array
+minItems: 2
+maxItems: 4
+items:
+  enum: [Apple, Banana, Cocoa]
+```
+
+With two optional properties used in the component form:
+
+- `minItems` to set the number of required values (default: 0)
+- `maxItems` to set the number of values (default: 1)
+
+Default form widget: A `maxItems` number of select lists.
+
+### Enum
+
+A single value restricted to a fixed set of values.
+
+Reference shortcut: `ui-patterns://enum`
+
+Resolved schema:
+
+```yaml
+type: ["string", "number", "integer"]
+enum: []
+```
+
+It is better to use the resolved schema with only the enum values:
+
+```yaml
+enum:
+  - "Foo"
+  - "Bar"
+  - "Baz"
+```
+
+```yaml
+enum:
+  - 5
+  - 10
+  - 15
+```
+
+Default form widget: A select list.
+
+### Set of enums
+
+Set of unique predefined string or number items.
+
+Reference shortcut: `ui-patterns://enum_set`
+
+Resolved schema:
+
+```yaml
+type: array
+uniqueItems: true
+items:
+  type:
+    - string
+    - number
+    - integer
+  enum: []
+```
+
+It is necessary to set the enum values:
+
+```yaml
+ui-patterns://enum_set
+items:
+  enum: ["Foo", "Bar", "Baz"]
+```
+
+Default form widget: A checkbox for each value.
+
+### Identifier
+
+A string with restricted characters, suitable for an HTML ID.
+
+Reference shortcut: `ui-patterns://attributes`
+
+Resolved schema:
+
+```yaml
+type: string
+pattern: '(?:--|-?[A-Za-z_\x{00A0}-\x{10FFFF}])[A-Za-z0-9-_\x{00A0}-\x{10FFFF}\.]*']
+```
+
+Default form widget: A textfield.
+
+### Links
+
+A list of link objects. Useful to model menu, breadcrumbs, pagers...
+
+Reference shortcut: `ui-patterns://links`
+
+Resolved schema:
+
+```yaml
+type: array
+items:
+  type: object
+  properties:
+    title:
+      type: string
+    url:
+      "$ref": ui-patterns://url
+    attributes:
+      "$ref": ui-patterns://attributes
+    link_attributes:
+      "$ref": ui-patterns://attributes
+    below:
+      type: array
+      items:
+        type: object
+```
+
+Default form source: A Drupal menus selector.
+
+### List
+
+List of free string or number items.
+
+Reference shortcut: `ui-patterns://list`
+
+Resolved schema:
+
+```yaml
+type: array
+items:
+  type: [string, number, integer]
+```
+
+Default form widget: A textarea. One value per line.
+
+### Number
+
+Reference shortcut: `ui-patterns://number`
+
+It is better to use the resolved schema:
+
+- for a decimal value: `type: number`
+- for an integer value: `type: integer`
+
+Default form widget: a number textfield with incremental steps (0.01 for decimal)
+
+It is possible to set minimum and/or maximum values:
+
+```yaml
+type: integer
+minimum: 1789
+maximum: 2025
+```
+
+### String
+
+Reference shortcut: `ui-patterns://string`
+
+It is better to use the resolved schema:
+
+```yaml
+type: string
+```
+
+Default form widget: a textfield.
+
+### URL
+
+Reference shortcut: `ui-patterns://url`
+
+Resolved schema:
+
+```yaml
+type: string
+format: iri-reference
+```
+
+Default form widget: a textfield.
+
+## Prop default values
+
+UI Patterns 2 uses <code>default</code> when building the component form, as <code>#default_value</code>.
+
+<code>default</code> must not be used in the rendering process (sending default value if prop value is missing or empty) because:
+
+- sometimes we want a default value in forms while allowing the user to set empty or missing value
+- the [|default()](https://twig.symfony.com/doc/3.x/filters/default.html") Twig filter is the expected tool for such an enforcement
+
+## meta:enum
+
+For your information, in UI Patterns 2, we use `meta:enum` which is not an official standard but supported by some popular projects:
+
+- https://github.com/adobe/jsonschema2md
+- https://github.com/coveooss/json-schema-for-human
+
+```yaml
+props:
+  type: object
+  properties:
+    position:
+      type: string
+      enum:
+        - top
+        - bottom
+      "meta:enum":
+        top: Top
+        bottom: Bottom
+```
+
+So:
+
+- If an item is in enum but not in meta:enum, its label will be the item string
+- If an item is in meta:enum but not in enum, it is ignored.
diff --git a/docs/2-authors/1-stories-and-library.md b/docs/2-authors/1-stories-and-library.md
new file mode 100644
index 0000000000000000000000000000000000000000..6414e4c004c3c73b89af5e0c4c28794bdc50b950
--- /dev/null
+++ b/docs/2-authors/1-stories-and-library.md
@@ -0,0 +1,192 @@
+# Component libraries and stories
+
+While you are authoring your component, or when you are showing your work to the stakeholders, you can use the components library.
+
+You need to activate `ui_patterns_library` sub-module for both:
+
+- being able to declare stories
+- browse the components and their stories in a component library
+
+## Stories
+
+A story is a data that describes how to render a component. You can have multiple stories per component, to describe all the “interesting” states a component can support.
+
+Stories are for documentation only.
+
+### Discovery
+
+Each story will have its own YML file:
+
+- to not clutter the component definition file.
+- sub themes and additional modules can add stories to existing components.
+
+They are expected to be found in the `components/` folder with this name: `{component_id}.{story_id}.story.yml`
+
+There is an optional `component` key in the story definition:
+
+- If missing, the related component will be the one of the current folder. So, it is optional when stories files are in the same folder as the component.
+- If present, the component will be the value of the property, so sub themes and additional modules can add stories to existing components.
+
+Example of a story targeting a component defined elsewhere:
+
+```yaml
+name: In latin
+component: "bootstrap:card"
+slots:
+  title: "Dapibus ac facilisis"
+  subtitle: "Cras justo odio"
+props:
+  heading_level: 5
+```
+
+### File format
+
+Props are straightforward: they expect values which is valid according to the JSON schema.
+
+#### Slots
+
+Slots are more flexible and are using the render API.
+
+Because slots are "normal" Drupal render arrays, it is possible to nest components:
+
+```yaml
+slots:
+  bottom:
+    type: component
+    component: "my_project:transcription"
+    slots:
+      text: "When they got to the road he stopped the boy with his hand."
+      actions:
+        type: component
+        component: "material:button"
+        slots:
+          label: Bookmark
+```
+
+A slot can have multiple renderables, in a YAML list:
+
+```yaml
+slots:
+  actions:
+    - type: component
+      component: "material:button"
+      slots:
+        label: Bookmark
+    - type: component
+      component: "material:button"
+      slots:
+        label: Bookmark
+```
+
+Full example:
+
+```yaml
+name: Video card
+description: A card with a video
+slots:
+  media:
+    type: html_tag
+    tag: img
+    attributes:
+      src: http://example.org/path/to/media.png
+  bottom:
+    type: component
+    component: "my_project:transcription"
+    slots:
+      text: "When they got to the road he stopped the boy with his hand."
+      actions:
+        - type: component
+          component: "material:button"
+          slots:
+            label: Bookmark
+        - type: component
+          component: "material:button"
+          slots:
+            label: Bookmark
+props:
+  title: Wanna learn about Drupal?
+  date: "2024-05-22 - 11:38pm"
+```
+
+The “#” prefix is optional in the slots’ render arrays.
+
+```yaml
+slots:
+  picture:
+    "#type": html_tag
+    "#tag": img
+    "#attributes":
+      src: http://example.org/path/to/media.png
+```
+
+is the same as:
+
+```yaml
+slots:
+  picture:
+    type: html_tag
+    tag: img
+    attributes:
+      src: http://example.org/path/to/media.png
+```
+
+#### Library wrappers
+
+```yaml
+name: In latin
+library_wrapper: '<div class="card">{{ _story }}</div>'
+slots:
+  title: "Dapibus ac facilisis"
+  subtitle: "Cras justo odio"
+props:
+  heading_level: 5
+```
+
+Beware of the underscore in `_story`.
+
+## Library pages
+
+Components library can be found in `/admin/appearance/ui`:
+
+![](images/library-1.webp)
+
+### Overview pages
+
+There is a global component library and one per provider:
+
+- `/admin/appearance/ui/components`
+- `/admin/appearance/ui/components/{provider}`
+
+![](images/library-overview.png)
+
+### Component single page
+
+Every component has its own page: `/admin/appearance/ui/components/{provider}/{component_id}`
+
+![](images/library-single-page.png)
+
+### Stories
+
+Stories are displayed after the component metadata and the slots/props table.
+
+> ⚠️ If a component has no stories, nothing is displayed after the slots/props table. But this may change in future UI Patterns 2.x versions.
+
+If a story has a variant prop, it will be displayed once. If a story doesn't have a variant prop (the most common case), it will be displayed for each variant.
+
+### Overriding library pages
+
+How can I customize the component library?
+
+It may be surprising but UI Pattens Library is using the old `hook_theme` way of managing templates
+
+- [ui-patterns-component-metadata.html.twig](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/modules/ui_patterns_library/templates/ui-patterns-component-metadata.html.twig): Component metadata (description, status, links, tags...)
+- [ui-patterns-component-table.html.twig](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/modules/ui_patterns_library/templates/ui-patterns-component-table.html.twig): Table of slots & props
+- [ui-patterns-overview-page.html.twig](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/modules/ui_patterns_library/templates/ui-patterns-overview-page.html.twig): Overview page.
+- [ui-patterns-overview-quicklinks.html.twig](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/modules/ui_patterns_library/templates/ui-patterns-overview-quicklinks.html.twig): Quicklinks, used in overview page.
+- [ui-patterns-single-page.html.twig](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/modules/ui_patterns_library/templates/ui-patterns-single-page.html.twig): Single page.
+- [ui-patterns-stories-compact.html.twig](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/modules/ui_patterns_library/templates/ui-patterns-stories-compact.html.twig): Stories without the stories and variants metadata. Used in the overview page.
+- [ui-patterns-stories-full.html.twi](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/modules/ui_patterns_library/templates/ui-patterns-stories-full.html.twig): Stories with the stories and variants metadata. Used in the single component page.
+
+So, you can copy and overrides any of those templates in your own Drupal theme to customize the library the way you want.
+
+> ⚠️ We plan to switch to SDC components and display building for UI Patterns 2.1 or 2.2: [#3438360](https://www.drupal.org/project/ui_patterns/issues/3438360). It will break stuff.
diff --git a/docs/2-authors/2-best-practices.md b/docs/2-authors/2-best-practices.md
new file mode 100644
index 0000000000000000000000000000000000000000..c9cdabf3b05fbe14a3d03fd4113e8805af114636
--- /dev/null
+++ b/docs/2-authors/2-best-practices.md
@@ -0,0 +1,562 @@
+# Best practices for component authoring
+
+> ⚠️ The most important good practices can be automatically audited with Drupal's [sdv_devel](https://www.drupal.org/project/sdc_devel) module, and will be described in `sdc_devel` document. The present documentation is only for non auditable, mostly secondary, good practices.
+
+## Component definition: Metadata
+
+### Stay business agnostic while naming component
+
+For example:
+
+- Don't use words relative to the data model, or business structure
+- If possible, use the BEM block name of the root element as a component name
+
+✅ Do:
+
+- Card
+- Carousel
+- Carousel item
+
+🚫 Don't:
+
+- Event card
+- Article card
+- News slideshow
+
+## Component definition: Variants
+
+### Use variants when needed
+
+A variant is a different visual version of the component. It has a label and a description. All variants share the same data model, they may not use some slots or props, but they do the same use of the slots and props.
+
+So, don’t fake it with a prop.
+
+Examples, set 4 variants in a component:
+
+```yaml
+label: Button Group
+variants:
+  default:
+    title: Default
+  vertical:
+    title: Vertical
+    description: Make a set of buttons appear vertically stacked rather than horizontally. Split button dropdowns are not supported here.
+  lg:
+    title: Large
+  sm:
+    title: Small
+```
+
+And then add the modifier class in the Twig template based on the variant name:
+
+```twig
+{% set attributes = variant ? attributes.addClass('btn-group--' ~ variant) : variant %}
+<div{{ attributes.addClass('btn-group') }}</div>
+```
+
+Sometimes, a variant can be split between multiple modifier classes:
+
+```twig
+{% set variants = variant|split('__')|map(v => v|replace({(v): 'progress-bar-' ~ v})) %}
+{% set attributes = attributes.addClass(variants) %}
+<div{{ attributes.addClass(progress-bar) }}>
+```
+
+### Always set a default variant
+
+Each component with variants must be rendered correctly, in the most expected way, if no variant is specified.
+
+It is common to name it “default”, but it can be any name. It must act the same as a missing or empty “variant” value:
+
+```twig
+{% set attributes = variant and (variant != 'default') ? attributes.addClass('btn-group--' ~ variant) : variant %}
+<div{{ attributes.addClass('btn-group') }}</div>
+```
+
+Your default variant can have any name. For example, `vertical`:
+
+```twig
+{% set attributes = variant and (variant != 'vertical') ? attributes.addClass('btn-group--' ~ variant) : variant %}
+<div{{ attributes.addClass('card') }}</div>
+```
+
+### If possible, name variants according to markup
+
+And name it according to markup class names if possible.
+
+In this example:
+
+```html
+<button type="button" class="btn btn-primary btn-lg">Large button</button>
+<button type="button" class="btn btn-secondary btn-lg">Large button</button>
+<button type="button" class="btn btn-primary btn-sm">Small button</button>
+<button type="button" class="btn btn-secondary btn-sm">Small button</button>
+```
+
+The component is “btn” and the variants are:
+
+- primary\_\_lg
+- secondary\_\_lg
+- primary\_\_sm
+- Secondary\_\_lg
+
+With BEM naming, it is even easier, because blocks are components and blocks modifiers are variants:
+
+```html
+<a class="mdc-button" href="http://example.com"></a>
+<a class="mdc-button mdc-button--outlined" href="http://example.com"></a>
+<a class="mdc-button mdc-button--raised" href="http://example.com"></a>
+<a class="mdc-button mdc-button--unelevated" href="http://example.com"></a>
+```
+
+The component is “button” and the variants are:
+
+- "" (default)
+- outlined
+- raised
+- unelevated
+
+## Component definition: Slots and props
+
+### Slot or prop?
+
+SDC components are made of slots & props:
+
+- **Slots**: “areas” for free renderables only, like other components.
+- **Props**: strictly typed data only, for some UI logic in the template.
+
+You can draw the slots areas in a component screenshot:
+
+![](../1-users/images/slots-vs-props.webp)
+
+Sometimes, for a printable text, deciding between slots and props can be tricky:
+
+- Simple plain text? Only plain text? Forever plain text? ✅ It is a prop.
+- Markup or renderable, and the wrapper HTML element is a block (`<div>`, `<section>`...)? ✅ It is a slot
+- Markup or renderable, but the wrapper HTML element is a `<p>` or an inline element (`<a>`, `<span>`...) ? ⚠️ That's may be tricky.
+
+### Avoid prop drilling
+
+If we have this in the component definition:
+
+```yaml
+props:
+  type: object
+  properties:
+    cta:
+      type: string
+      title: CTA text
+    cta_href:
+      type: string
+      format: uri
+      title: CTA link
+```
+
+And this in the template:
+
+```twig
+<div class="featured__cta-wrapper">
+   <a class="button--primary" href="{{ cta_href }}">{{ cta }}</a>
+</div>
+```
+
+`button--primary` is clearly its own component, distinct from feature, so we have those 2 issues:
+
+- the button component markup is duplicated in the feature component template, which will cause maintenance issues when the former will evolve
+- the feature component is too busy (2 unexpected props!) because of the "prop drilling" (defining props in a component to pass them in a child component)
+
+In this case, we need a cta slot, where it will be possible to inject a button component (or anything else).
+
+### Avoid "drilling' for other renderables.
+
+It is less important than for slots, but the same logic can sometimes be useful for other renderables.
+
+Example: renderable image element instead of “src” prop. That way you can inject your image with field formatters and benefit from the Drupal image manipulation system.
+
+✅ Do:
+
+```yaml
+slots:
+  picture:
+    title: "Picture"
+```
+
+In twig:
+
+```twig
+{{ picture }}
+```
+
+With this injected data:
+
+```yaml
+slots:
+  picture:
+    type: "html_tag"
+    tag: "img"
+    attributes:
+      src: "/path/to/photo.jpg"
+      alt: "Hello world"
+```
+
+🚫 Instead of:
+
+```yaml
+props:
+  type: object
+  properties:
+    label:
+      type: "string"
+      label: "Label"
+   url:
+      type: "url"
+      label: "URL"
+```
+
+```twig
+<img src={{ url }} alt="{{ label }}"</a>
+```
+
+### Make sub components easily spottable in library
+
+In other words, components intended to be used only in a specific context.
+
+To be able to distinguish such components:
+
+- Put the component’s label inside parenthesis. (Carousel Item)
+- Begin the component’s description with “Internal: ” and describe with which other component the component is intended to be used with.
+- Internal: to be used in the 'Carousel' component.
+- You can also prefix the component machine name with an underscore
+- Use categories to group components togethers.
+
+> ⚠️ This issue will made this advice obsolete: <a href="https://www.drupal.org/project/ui_patterns/issues/3351682" rel="nofollow">UI Patterns Library: add sub-components</a>.
+
+### Keep slots independent from each others
+
+When working with two sequences of slots, don’t get an item from one using the index of the other one. Because:
+
+- It may break if not the same number of items
+- It will be hard to use in Drupal admin UI
+
+🚫 Don’t (in YML):
+
+```yaml
+slots:
+  images:
+    label: Images
+  labels:
+    label: Labels
+```
+
+With this data:
+
+```yaml
+slots:
+  images:
+    - theme: image
+      uri: assets/image-1.webp
+    - theme: image
+      uri: assets/image-2.jpg
+  labels:
+    - "Portrait blue"
+    - "Landscape yellow"
+```
+
+🚫 Don’t (in Twig):
+
+```twig
+{% for image in images %}
+<li class="mdc-image-list__item">
+  {{ image }}
+  {% set index = loop.index0 %}
+  {% if labels[index] %}
+  <span class="mdc-image-list__label">{{ labels[index] }}</span>
+  {% endif %}
+</li>
+{% endfor %}
+```
+
+✅ A solution may be to create a sub-component.
+
+### Avoid props paradoxes by leveraging orthogonality
+
+🚫 Don't allow the component to be in a state where props values are not compatible with each others:
+
+```yaml
+props:
+  type: object
+  properties:
+    responsive:
+      type: "string"
+      title: "Responsive"
+      enum:
+        - offcanvas-sm
+        - offcanvas-md
+        - offcanvas-lg
+        - offcanvas-xl
+        - offcanvas-xxl
+    backdrop:
+      type: "string"
+      title: "Backdrop"
+      description: "When backdrop is set to static, the offcanvas will not close when clicking outside of it."
+      enum:
+        - "false"
+        - static
+    scroll:
+      type: "boolean"
+      title: "Body scrolling"
+      description: "By default, body scrolling is disabled."
+```
+
+### For menus, breadcrumbs, links and pager, use the links prop type
+
+The link prop type offer an unified and consistent way of dealing with (sometimes nested) list of links.
+
+✅ Do, keep the recursive structure and the variables names:
+
+```twig
+{{ menus.menu_links(items, attributes, 0) }}
+
+{% macro menu_links(items, attributes, menu_level) %}
+  {% if items %}
+    {% if menu_level == 0 %}
+      <ul{{ attributes }}>
+    {% else %}
+      <ul>
+    {% endif %}
+    {% for item in items %}
+      <li{{ item.attributes }}>
+        {{ link(item.title, item.url) }}
+         {% if item.below %}
+           {{ _self.menu_links(item.below, attributes, menu_level + 1) }}
+         {% endif %}
+       </li>
+    {% endfor %}
+   </ul>
+  {% endif %}
+{% endmacro %}
+```
+
+## Definitions: Stories
+
+### Useless lists of renderables in slots
+
+Keep you structure flat.
+
+✅ Do:
+
+```yaml
+slots:
+  - type: component
+    component: "material:card"
+    story: long_text
+  - type: component
+    component: "material:card"
+    story: long_text
+```
+
+✅ Do:
+
+```yaml
+slots:
+  type: component
+  component: "material:card"
+```
+
+🚫 Don't:
+
+```yaml
+slots:
+  - type: component
+    component: "material:card"
+```
+
+## Twig templating
+
+###  Be careful with looping
+
+Looping on a slot is a risky thing, because there is no way of knowing if an array is a renderable or a list of renderable. It is not possible to use an <a href="https://twig.symfony.com/doc/3.x/tests/iterable.html" rel="nofollow">iterable test </a>because render arrays are considered as iterable.
+
+🚫 For example, this will break if 'slides' value is not a list but a single renderable:
+
+```twig
+<div class="carousel-inner" role="listbox">
+  {% for slide in slides %}
+    <div class="carousel-item">
+      {{ slide }}
+    </div>
+  {% endfor %}
+</div
+```
+
+It is also possible to get two or more nested loops (example: a table where every cell is a slot).
+
+✅ Do:
+
+```twig
+<div class="carousel-inner" role="listbox">
+  {% set slides = slides and slides is not sequence ? [slides] : slides %}
+  {% for slide in slides %}
+    <div class="carousel-item">
+      {{ slide }}
+    </div>
+  {% endfor %}
+</div
+```
+
+### Use the Drupal attributes
+
+The `attributes` variable is automatically on every SDC template and must be used because it is expected by a lot of API:
+
+- SEO modules can insert tagging attributes through it
+- Accessibility modules can alter/insert some attributes values (`aria-*`, `role`, `alt`...) through it
+- Translation modules can add the `lang` attribute when needed
+- Styles utilities modules (like [UI Styles](https://www.drupal.org/project/ui_styles), Style Options...) can insert helpers classes through it
+- Hypermedia modules (HTMX, Hotwire/Turbo...) can insert triggers and behaviours attributes through it
+- Drupal Core's |add_class() and |set_attribute() Twig filters rely on it
+- Display builders (like Paragraph Layout, Layout Builder, Experience Builder) can insert annotation through it
+- ...
+
+Use it directly in the component wrapper:
+
+✅ Do:
+
+```twig
+<a{{ attributes.addClass('ds-btn') }}>
+  {% if icon_attributes %}<i{{ icon_attributes }}></i>{% endif %}
+  {{ label }}
+</a>
+```
+
+✅ Do:
+
+```twig
+<div{{ attributes.addClass('ds-quote') }}>
+  <i class="ds-quote__icon ds-ico ds-ico-quote-sign"></i>
+  <div class="ds-quote__text">
+    {{ value }}
+  </div>
+</div>
+```
+
+🚫 Don’t (missing attributes object and the BEM modifier is hardcoded)
+
+```twig
+<ul class="ds-nav ds-nav--buttons">
+  {% for item in items %}
+  ...
+  {% endfor %}
+</ul>
+```
+
+🚫 Don’t (using attribute object twice, or outside the wrapper)
+
+```twig
+<div{{ attributes.addClass('ds-quote') }}>
+  <i class="ds-quote__icon ds-ico ds-ico-quote-sign"></i>
+  <div {{ attributes.addClass('ds-quote__text') }}>
+    {{ value }}
+  </div>
+</div>
+```
+
+### Don’t rely on props typing
+
+Props are strongly typed, but the type must not be tested in templates or alter processing. Because:
+
+- The type is set in component definitions and must not change
+- There is no safe and reliable way of testing the types in Twig. Source: <a href="https://twig.symfony.com/doc/1.x/tests/index.html" rel="nofollow">https://twig.symfony.com/doc/1.x/tests/index.html</a>
+- Type checking to filter out unsafe values must be done before the template execution
+
+### Slots values are totally free and optional
+
+Your component must survive with any components injected in its slots. As if you use a randomizer.
+
+Of course, it doesn’t have to look “clean”, but it doesn’t have to break.
+
+This has also an impact on filters. Filters can be really powerful and save us a lot of time. But they are dependent on existing data structures and can crash if applied to another.
+
+So, most of the filters are forbidden on slots. Except a few filters identified a few slots friendly filters, and called “slot filters” (add_class, set_attributes…), don’t use filters on slots.
+
+### Use default values when props are mandatory
+
+Error proof: nothing  is expected to be mandatory.  Always test your components with only empty values. Of course, it doesn’t have to look “clean”, but it doesn’t have to break.
+
+If you absolutely need a value when processing in the templates, use |default() filter.
+
+🚫 Don’t:
+
+```twig
+<h{{ heading_level }}>{{ title}}</h{{ heading_level }}>
+```
+
+✅ Do:
+
+```twig
+{{ set heading_level = heading_level|default(3) }}
+<h{{ heading_level }}>{{ title}}</h{{ heading_level }}>
+```
+
+### Keep components independent of each other
+
+Let the render arrays do this job of imbrication. So, as the front developer you have to create nestable templates, but the template nesting is the job of the back developer &amp; the site builders, not yours.
+
+### For unavoidable hardcoded dependencies, use include() function
+
+If you really need to call a component from another component template, use `include()` function:
+
+- with the component ID
+- with `with_context = false` to avoid context bleeding
+
+✅ Do:
+
+```twig
+include(
+  "bootstrap:card",
+  {slot_1: foo, slot_2: bar, prop_1: baz, prop_2: true},
+  with_context = false
+)
+```
+
+🚫 Don't call the template path directly:
+
+```twig
+include(
+  "/templates/includes/other-events.html.twig')",
+  {slot_1: foo, slot_2: bar, prop_1: baz, prop_2: true},
+  with_context = false
+)
+```
+
+### Don’t hardcode ID values
+
+Components must be repeatable and nestable, so different instances of the component can’t share the same ID.
+
+Instead, you can:
+
+- Generate the ID with the Twig random() function
+- Inject the ID from a prop
+
+🚫 Don’t:
+
+```html
+<span id="foo">Lorem ipsum</span>
+```
+
+🚫 Don’t:
+
+```twig
+{{ attributes.setAttribute("id", "foo") }}
+```
+
+✅ Do:
+
+```twig
+<span id="{{ id }}">Lorem ipsum</span>
+```
+
+✅ Do:
+
+```twig
+{{ attributes.setAttribute("id", id) }}
+```
diff --git a/docs/2-authors/3-migration-from-UIP1.md b/docs/2-authors/3-migration-from-UIP1.md
new file mode 100644
index 0000000000000000000000000000000000000000..f4e548acc67c1349dd1dfca8da3d48d441db3deb
--- /dev/null
+++ b/docs/2-authors/3-migration-from-UIP1.md
@@ -0,0 +1,289 @@
+# Migration from UI Patterns 1
+
+# Ecosystem consolidation
+
+If you are coming from UI Patterns 1.x, you may not find UI Patterns 2.x version of your favourite modules on https://www.drupal.org/project/project_module
+
+Maybe because it was merged into an UI Patterns 2.x sub-module:
+
+![](images/ecosystem.webp)
+
+So, you can now found most of the UI Patterns integration inside the main `ui_patterns` project and 2 sub-modules were moved out of the project:
+
+- Display Suite. Now found in https://www.drupal.org/project/ui_patterns_ds
+- Field Group. Now found in https://www.drupal.org/project/ui_patterns_field_group
+
+## Automatic components migration
+
+You need to activate `ui_patterns_legacy` sub-module.
+
+And run:
+
+```bash
+drush ui-patterns:migrate my_theme
+```
+
+Or:
+
+```bash
+drush upm my_theme
+```
+
+The converted components can be found in `components/`. `patterns/` folder is kept by the migration, but can be removed.
+
+### Component definitions
+
+It is done automatically by the drush command:
+
+- "fields" are becoming slots
+- "settings" are becoming props
+
+| UIP 1.x setting type | UIP2 2.X prop type |
+| -------------------- | ------------------ |
+| Attributes           | attributes         |
+| Boolean              | boolean            |
+| Checkboxes           | list               |
+| Links                | links              |
+| Machine Name         | identifier         |
+| Number               | number             |
+| Radios               |  enum              |
+| Select               |  enum              |
+| Textfield            |  string            |
+| Token                |  string            |
+| Url                  | url                |
+
+> ⚠️ Some features, mixing data structure and data sources, doesn't make sense with SDC and are ignored: `required`, `allow_expose`, `expose_as_field`, `allow_token`…
+
+Anyway, there are a few tasks you may want to do after that:
+
+#### identifier props
+
+In UI Patterns 1.x, `machine_name` setting type was overlooked because:
+
+- it was added late (mid 2023)
+- it was not compatible with the broadly used `token` source
+
+In UI Patterns 2.x, it was replaced by `identifier` prop type can be used without those limitation.
+
+#### number props
+
+In UI Patterns 1.x, `number` setting type doesn't allow to tell when a number is a decimal or an integer.
+
+In UI Patterns 2.x, you can replace `type: number` by `type: integer`.
+
+#### Ignored setting types
+
+Those settings are not ignored because they are not too "business":
+
+- ColorWidget
+- ColorisWidget
+- GroupType
+- LanguageCheckboxes
+- LanguageAccess
+- MediaLibrary
+- Publish
+
+### Templates
+
+The templates are exactly the same between UI Patterns 1.x and UI Patterns 2.x, except `pattern()` function which has been replaced by the Twig native `include()` function:
+
+```twig
+pattern(
+  "card",
+  {slot_1: foo, slot_2: bar, prop_1: baz, prop_2: true},
+  variant_id
+)
+```
+
+becomes:
+
+```twig
+include(
+  "bootstrap:card",
+  {slot_1: foo, slot_2: bar, prop_1: baz, prop_2: true, variant: variant_id},
+  with_context = false
+)
+```
+
+Differences:
+
+- `component_id` is now prefixed by the provider (theme or module)
+- `variant` is now a prop instead of
+- `with_context = false` must be added to avoid scope leaks.
+
+Until the manual conversion is done, you can still use `pattern()` thanks to a compatibility layer, if you keep `ui_patterns_legacy` activated.
+
+> ⚠️ variants templates (ex: `pattern-card--variant-horizontal.html.twig`) are not kept because they don't exist in UI Patterns 2
+
+### Preview/Stories
+
+A story called `preview` is automatically created from all the `preview` values extracted from the component definition.
+
+For example, this UI Patterns 1.x definition:
+
+```yaml
+button:
+  label: "Button"
+  settings:
+    disabled:
+      type: "boolean"
+      label: "Disabled?"
+      preview: false
+      allow_token: true
+    label_visually_hidden:
+      type: "boolean"
+      label: "Hide button label?"
+      preview: false
+    url:
+      type: "url"
+      label: "URL"
+      preview: "https://example.com"
+  fields:
+    label:
+      type: "text"
+      label: "Label"
+      preview: "Submit"
+```
+
+Is becoming this story:
+
+```yaml
+name: Preview
+slots:
+  label: Submit
+props:
+  disabled: false
+  label_visually_hidden: false
+  url: "https://example.com"
+```
+
+### Preview templates
+
+Preview templates (`pattern-{component_id}--preview.html.twig`) are replaced by `library_wrapper` properties of story definition, but this is not done automatically.
+
+## Compatibility layer at runtime
+
+By keeping `ui_patterns_legacy` activated after the migration, you can leverage a compatibility layer between UI Patterns 1.x and SDC API.
+
+### Render elements
+
+For example, this render element:
+
+```php
+[
+  '#type' => 'pattern',
+  '#id' => 'blockquote',
+  '#variant' => 'highlighted',
+  '#fields' => [
+    'quote' => 'You must do the things you think you cannot do.',
+    'attribution' => 'Eleanor Roosevelt',
+   ],
+  '#settings' => [
+     'url' => 'https://example.org'
+  ]
+]
+```
+
+And this one:
+
+```php
+[
+  '#type' => 'pattern',
+  '#id' => 'blockquote',
+  '#variant' => 'highlighted',
+  'quote' => 'You must do the things you think you cannot do.',
+  'attribution' => 'Eleanor Roosevelt',
+   'url' => 'https://example.org'
+]
+```
+
+Are both converted to:
+
+```php
+[
+  '#type' => 'component',
+  '#component' => 'provider:blockquote',
+  '#slots' => [
+    'quote' => 'You must do the things you think you cannot do.',
+    'attribution' => 'Eleanor Roosevelt',
+   ],
+  '#props' => [
+     'url' => 'https://example.org',
+     'variant' => 'highlighted'
+  ]
+]
+```
+
+It works also for `pattern_preview` render element:
+
+```php
+[
+  '#type' => 'pattern_preview',
+  '#id' => 'blockquote',
+  '#variant' => 'highlighted',
+]
+```
+
+Is converted at runtime to:
+
+```php
+[
+  '#type' => 'component',
+  '#component' => 'provider:blockquote',
+  '#story' => 'preview',
+  '#props' => [
+     'variant' => 'highlighted'
+  ]
+]
+```
+
+### Twig functions
+
+At runtime, `pattern()` twig function:
+
+```twig
+pattern(
+  "card",
+  {slot_1: foo, slot_2: bar, prop_1: baz, prop_2: true},
+  variant_id
+)
+```
+
+is processed as:
+
+```php
+[
+  '#type' => 'component',
+  '#component' => 'bootstrap:card',
+  '#slots' => [
+    'slot_1' => foo,
+    'slot_2' => bar,
+   ],
+  '#props' => [
+     'prop_1' => 'baz',
+     'prop_2' => true,
+     'variant' => 'variant_id'
+  ]
+]
+```
+
+> ⚠️ The provider is guessed. If you have many components with the same ID (so, in this example, many cards), the provider may be guessed wrong.
+
+Same for `pattern_preview`:
+
+```twig
+{{ pattern_preview('modal', 'highlighted') }}
+```
+
+is processed as:
+
+```php
+[
+  '#type' => 'component',
+  '#component' => 'provider:modal',
+  '#story' => 'preview',
+  '#props' => [
+     'variant' => 'variant_id'
+  ]
+]
+```
diff --git a/docs/2-authors/images/ecosystem.webp b/docs/2-authors/images/ecosystem.webp
new file mode 100644
index 0000000000000000000000000000000000000000..442c8e1399387f87c578c53f1428d3b229e2caf1
Binary files /dev/null and b/docs/2-authors/images/ecosystem.webp differ
diff --git a/docs/2-authors/images/library-1.webp b/docs/2-authors/images/library-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..d22fff18221d444f4513b84393df8df35977b500
Binary files /dev/null and b/docs/2-authors/images/library-1.webp differ
diff --git a/docs/2-authors/images/library-overview.png b/docs/2-authors/images/library-overview.png
new file mode 100644
index 0000000000000000000000000000000000000000..9dd0a8d92650e6e07a2ce38142358ca5c59f63c5
Binary files /dev/null and b/docs/2-authors/images/library-overview.png differ
diff --git a/docs/2-authors/images/library-single-page.png b/docs/2-authors/images/library-single-page.png
new file mode 100644
index 0000000000000000000000000000000000000000..969c001e738f5a9253b211aff56c9545a0f5157c
Binary files /dev/null and b/docs/2-authors/images/library-single-page.png differ
diff --git a/docs/3-devs/1-source-plugins.md b/docs/3-devs/1-source-plugins.md
new file mode 100644
index 0000000000000000000000000000000000000000..94037f2d256f12d7be398034941ab3dfbefc4575
--- /dev/null
+++ b/docs/3-devs/1-source-plugins.md
@@ -0,0 +1,31 @@
+# Extends with your own source plugins
+
+> ⚠️ **DRAFT: writing in progress**
+
+The most common way of extending UI Patterns 2.x API is to add source plugins.
+
+https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/src/Plugin/UiPatterns/Source/
+
+- Same source plugin type for slots and props
+- Same source plugin type for data from Drupal API or from direct input
+
+## Context awareness
+
+Sometimes sources require another object in order to retrieve the data. This is known as context.
+
+## Default value
+
+Some source plugins are using it to fill the default value of the form, when they extends SourcePluginPropValue because:
+
+- the source store only one config value called value
+- value data is validating to the prop schema
+
+Examples:
+
+- [UrlWidget](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/src/Plugin/UiPatterns/Source/UrlWidget.php)
+- [SelectsWidget](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/src/Plugin/UiPatterns/Source/SelectsWidget.php)
+- [NumberWidget](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/src/Plugin/UiPatterns/Source/NumberWidget.php)
+- [CheckboxesWidget](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/src/Plugin/UiPatterns/Source/CheckboxesWidget)
+- [SelectWidget](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/src/Plugin/UiPatterns/Source/CheckboxesWidget)
+- [CheckboxWidget](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/src/Plugin/UiPatterns/Source/CheckboxWidget.php)
+- [TextfieldWidget](https://git.drupalcode.org/project/ui_patterns/-/tree/2.0.x/src/Plugin/UiPatterns/Source/TextfieldWidget.php)
diff --git a/docs/3-devs/2-prop-type-plugins.md b/docs/3-devs/2-prop-type-plugins.md
new file mode 100644
index 0000000000000000000000000000000000000000..b9642afc2d2737e3d13b30f64292c0d8480fc830
--- /dev/null
+++ b/docs/3-devs/2-prop-type-plugins.md
@@ -0,0 +1,25 @@
+# Prop types
+
+> ⚠️ **DRAFT: writing in progress**
+
+Prop type plugins acts as a proxy between component definition and source plugins. For streamlined software architecture, we consider “slot” as a “prop type”. All slots will have the “slot” prop type, no exceptions.
+
+Not the same as JSON schema types.
+
+## Extends with your own prop types
+
+### Add your own plugin
+
+You can add your own prop types
+
+### Add a prop type adapter plugin
+
+However, those themes don”t use the explicit prop typing from UI Patterns and rely only on the schema compatibility checker.
+
+Sometimes, a prop JSON schema is different enough to not be caught by the compatibility checker, but close enough to address the same Drupal API as existing prop type with only some small unidirectional transformation of the data.
+
+But we prefer to keep the list of prop types as tight as possible, and their JSON schemas as strict as possible, because they are also used for data validation.
+So we need a new plugin type:
+
+- Lightweight, just a proxy, with basic unidirectional transformations
+- We will not be afraid to create a lot of them
diff --git a/docs/3-devs/3-internals.md b/docs/3-devs/3-internals.md
new file mode 100644
index 0000000000000000000000000000000000000000..0bee4da06241da7c3da8a4ae94508ae5a71b2a0b
--- /dev/null
+++ b/docs/3-devs/3-internals.md
@@ -0,0 +1,30 @@
+# Internals
+
+> ⚠️ **DRAFT: work in progress**
+
+UI Patterns 2 is doing 3 jobs.
+
+## Guessing the PropType plugin for every components' props.
+
+Schema compatibility checker:
+
+```
+src/SchemaManager/
+├── Canonicalizer.php
+├── CompatibilityChecker.php
+├── ReferencesResolver.php
+├── ScalarCompatibilityTrait.php
+└── StreamWrapper.php
+```
+
+For implicit prop type declaration. UI Patterns must work with every SDC component, even the ones not built with UI Patterns. So, if a component is not using a direct reference to a prop type plugin, we can guess the prop type.
+
+![](images/internals-1.webp)
+
+## Building a form for each component by loading Source plugins
+
+![](images/internals-2.webp)
+
+## Building a renderable from the component form data
+
+![](images/internals-3.webp)
diff --git a/docs/3-devs/images/internals-1.webp b/docs/3-devs/images/internals-1.webp
new file mode 100644
index 0000000000000000000000000000000000000000..f090b62261a5f59377d3052b652669e48fee1108
Binary files /dev/null and b/docs/3-devs/images/internals-1.webp differ
diff --git a/docs/3-devs/images/internals-2.webp b/docs/3-devs/images/internals-2.webp
new file mode 100644
index 0000000000000000000000000000000000000000..03641c74a43e7d032e0634e5f005edb9090dca11
Binary files /dev/null and b/docs/3-devs/images/internals-2.webp differ
diff --git a/docs/3-devs/images/internals-3.webp b/docs/3-devs/images/internals-3.webp
new file mode 100644
index 0000000000000000000000000000000000000000..939524348302201bcf39bac5f1baae8fbf06d11a
Binary files /dev/null and b/docs/3-devs/images/internals-3.webp differ
diff --git a/docs/faq.md b/docs/faq.md
new file mode 100644
index 0000000000000000000000000000000000000000..04d93adc97e8052fefe233b540e747786a72a80c
--- /dev/null
+++ b/docs/faq.md
@@ -0,0 +1,124 @@
+# Frequently Asked Questions
+
+## Questions from components users
+
+### Where are Field Group and Display Suite integrations?
+
+`ui_patterns_ds` and `ui_patterns_field_group` were submodules in 1.0.x branch. These modules are leaving the main project, because we have reorganized the ecosystem:
+
+- integrations with Core APIs is implemented in `ui_patterns` project sub-modules
+- integrations with Contrib APIs is implemented in dedicated contrib modules
+
+So, development is happening here:
+
+- https://www.drupal.org/project/ui_patterns_ds
+- https://www.drupal.org/project/ui_patterns_field_group
+
+### Is it compatible with `ckeditor_layouts`?
+
+UI Patterns 2.x layout plugins are not compatible with `ckeditor_layouts` [because](https://www.drupal.org/project/ui_patterns/issues/3474131#comment-15907843) the module is loading the layout through the theme manager but SDC is not passing through the theme manager.
+
+```php
+$template = ['#theme' => $layout->getThemeHook()];
+```
+
+### Do you provide configuration migration (entity displays, views...)?
+
+We provide only code migration for now (2.0.0, February 2025) through the `drush upm` command provided by `ui_patterns_legacy` sub-module.
+
+We plan to propose config migration, but:
+
+- it will be alter in 2025. If you are in a hurry, it is better to rebuild your displays manually.
+- we target around 80% of the use cases. If you have a specific usage, it is better to rebuild your displays manually.
+
+### What about Experience Builder?
+
+[Experience Builder](https://www.drupal.org/project/experience_builder), a new display builder expected for late 2025, which will also be shipped with an SDC integration.
+
+UI Patterns 2 is not competing with Experience Builder because it is not a new display builder, it converts SDC components to configurable plugins to be used with existing display builders (Manage Display, Layout Builder, Paragraph Layout, Views...):
+
+![](images/xb.png)
+
+However, UIP2 can provide some advanced features (especially about data retrieval from Drupal API to props & slots) to XB if they allow it with an API.
+
+Any compatibility issue between the two modules must be considered as a bug and fixed on XB side, or UIP2 side, or both side. Making the effort of staying compatible will improve the quality of both solutions: that would mean none of them is doing crazy stuff with SDC.
+
+See:
+
+- https://www.drupal.org/project/ui_patterns/issues/3490873
+- https://www.drupal.org/project/drupal_cms/issues/3491465
+
+## Questions from component authors
+
+### What is the relationship with SDC?
+
+UI Patterns 2 is connecting SDC to Drupal API:
+
+- Form building
+- Cache management
+- Context management
+- Config dependencies
+- Exposition as configurable plugins (blocks, layouts...)
+
+Also, Pierre ([pdureau](https://www.drupal.org/u/pdureau)) is both a maintainer of SDC in Core and the project manager of UI Patterns 2.
+
+UI Patterns 2.x team have worked hard to stay as close as vanilla SDC as possible, but we have added some extensions. However, all of them will be proposed to Drupal Core: [#3471454: List of related core issues](https://www.drupal.org/project/ui_patterns/issues/3471454).
+
+### Why my SDC component doesn't work well with UI Patterns 2?
+
+UI Patterns 2 is not expecting you to change your SDC component in order to be compatible.
+
+However, if your component has definitions or templating issues, it will be harder for UI Patterns 2.x to connect it to Drupal API
+
+You can check your component with [sdc_devel](https://www.drupal.org/project/sdc_devel) which provides automatic audits.
+
+A component without error must be compatible with UI Patterns 2.x
+
+### One of my prop has an "Unknown" prop type, why?
+
+If your prop doesn't show up in the component form, or is marked with "Unknown ⚠️" in the component library, it is because its prop type was not guessed from its JSON schema.
+
+See the prop types list in [Authoring a component](2-authors/0-authoring-a-component.md) chapter.
+
+Maybe because the prop schema has something wrong.
+
+Or maybe because the prop type is missing from UI Patterns 2 API. You can propose it by creating a feature request: https://www.drupal.org/project/issues/ui_patterns?categories=All
+
+### Can we deprecate a component?
+
+There is a `status` enum in SDC:
+
+```yaml
+status:
+  type: string
+  title: Development Status
+  description:
+    Use this property to identify if the component can be safely used in
+    production.
+  enum:
+    - experimental
+    - stable
+    - deprecated
+    - obsolete
+```
+
+https://git.drupalcode.org/project/drupal/-/blob/11.x/core/assets/schemas/v1/metadata.schema.json
+
+This information is shown in the component library, but the component is still available for selection.
+
+### Relationship with Storybook module
+
+https://www.drupal.org/project/storybook provides an integration between SDC and Storybook component library.
+
+So it looks like `ui_patterns_library` but the goals are different:
+
+- `storybook` is a development tool, powerful, outside of Drupal, an industry standard, great for the front developers
+- `ui_patterns_library` is to check the components once developed, inside Drupal, well integrated in Drupal and the Render API, great for the other stakeholders, without having to go to another tool
+
+Some people use `ui_patterns_library` for local SDC development, because it is good enough for them.
+
+### Relationship with SDC Styleguide module
+
+This module is a friendly competitor to `ui_patterns_library` sub-module.
+
+We are working with SDC Styleguide team to be compatible: [#3464909: Collaboration with UI Patterns 2](https://www.drupal.org/project/sdc_styleguide/issues/3464909)
diff --git a/docs/images/logo.webp b/docs/images/logo.webp
new file mode 100644
index 0000000000000000000000000000000000000000..193340ce061cd2b3356f25242845fdb555845eb2
Binary files /dev/null and b/docs/images/logo.webp differ
diff --git a/docs/images/overview.webp b/docs/images/overview.webp
new file mode 100644
index 0000000000000000000000000000000000000000..1892c5d363b42a777970ab540d0d44d8301e05ee
Binary files /dev/null and b/docs/images/overview.webp differ
diff --git a/docs/images/xb.png b/docs/images/xb.png
new file mode 100644
index 0000000000000000000000000000000000000000..131d537462499361b7b1b25e9c22a59f8826751a
Binary files /dev/null and b/docs/images/xb.png differ
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..b3f709fe3c09c64ab6cafa8866997ee00e52be43
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,54 @@
+# UI Patterns 2 — SDC in Drupal UI
+
+UI Patterns 2.x load your SDC components as Drupal plugins to make them available in Drupal UI and configuration, for both novice and ambitious site-builders.
+
+UI components are reusable, nestable, guided by clear standards, business agnostics, and can be assembled together to build displays. Examples: card, button, slider, pager, menu, toast...
+
+## Using SDC components in Drupal UI
+
+For each SDC component, UI Patterns is providing an integration with Drupal:
+
+- **From Drupal to SDC**: Build a form from the component slots and props definitions, where it is possible to pull data from many Drupal API (See [Component form](1-users/0-component-form.md) chapter).
+- **From SDC to To Drupal**: Exposes the components as Drupal plugins.
+
+UI Patterns provides 4 sub-modules for integration with all Drupal Core display builders (Manage display, Layout Builder, Block layout and Views) and some from contrib too:
+
+- **UI Patterns Blocks** (`ui_patterns_blocks`): expose each component as a Drupal Block plugins. See [Use as block](1-users/1-as-block.md) chapter.
+- **UI Patterns Layouts** (`ui_patterns_layouts`): expose each component as a Drupal Layout plugin. See [Use as layout](1-users/2-as-layout.md) chapter.
+- **UI Patterns Field Formatters** (`ui_patterns_field_formatters`): use components in Drupal Field Formatters plugins. See [Use in Field Formatters](1-users/3-in-field-formatter.md) chapter.
+- **UI Patterns Views** (`ui_patterns_views`): use components as Views styles (all the results in a single component) and View rows (each result in a component) plugins. See [Use with Views](1-users/4-with-views.md) chapter.
+
+![](images/overview.webp)
+
+On 1.x branch, UI Patterns was also providing integration for:
+
+- Display Suite plugins. Now found in https://www.drupal.org/project/ui_patterns_ds
+- Field Group plugins. Now found in https://www.drupal.org/project/ui_patterns_field_group
+
+### No SDC components yet?
+
+You want to try UI Patterns 2.x but you don't have SDC components in you project, you need a theme providing them. For example:
+
+- [ui_suite_bootstrap](https://www.drupal.org/project/ui_suite_bootstrap) provides more than 30 components from the most popular Web design system.
+- [ui_suite_dsfr](https://www.drupal.org/project/ui_suite_dsfr) provides 44 components from the French Government design system
+- [ui_suite_uswds](https://www.drupal.org/project/ui_suite_uswds) provides 56 components from the US Government design system
+- [ui_suite_daisyui](https://www.drupal.org/project/ui_suite_daisyui) provides 38 components from Daisy UI (a famous Tailwind-based design system)
+- ...
+
+## Authoring SDC components
+
+To build the best UI components for Drupal, see how to [author a component](2-authors/0-authoring-a-component.md) and some [best practices](2-authors/2-best-practices.md).
+
+Also, two sub-modules to help component authors:
+
+- **UI Patterns Library** (`ui_patterns_library`): Generates component library pages to be used as documentation for content editors or as a showcase for business and clients. See [Add stories to the component library](2-authors/1-stories-and-library.md) chapter.
+- **UI Patterns Legacy** (`ui_patterns_legacy`): See [Migration from UI Patterns 1.x](2-authors/3-migration-from-UIP1.md) chapter.
+
+## Extending UI Patterns 2.x
+
+UI Patterns API is based on plugins. You can add your owns:
+
+- [Source plugins](3-devs/1-source-plugins.md)
+- [Prop type plugins](3-devs/2-prop-type-plugins.md)
+
+You want to go further? See [how UI Patterns works](3-devs/3-internals.md)
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a5ac3f55df02d9008e99096301f41643b5cc3181
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,69 @@
+site_name: "UI Patterns 2"
+repo_url: https://git.drupalcode.org/project/ui_patterns
+repo_name: drupal/ui_patterns
+edit_uri: /-/edit/main/docs/
+
+theme:
+  name: material
+  language: en
+  logo: images/logo.webp
+  # favicon: favicon.ico
+  palette:
+    # Palette toggle for automatic mode
+    - media: "(prefers-color-scheme)"
+      primary: indigo
+      toggle:
+        icon: material/brightness-auto
+        name: Switch to light mode
+    # Palette toggle for light mode
+    - media: "(prefers-color-scheme: light)"
+      primary: indigo
+      scheme: default
+      toggle:
+        icon: material/brightness-7
+        name: Switch to dark mode
+    # Palette toggle for dark mode
+    - media: "(prefers-color-scheme: dark)"
+      primary: indigo
+      scheme: slate
+      toggle:
+        icon: material/brightness-4
+        name: Switch to system preference
+  features:
+    # - navigation.tabs
+    # - navigation.tabs.sticky
+    - navigation.sections
+    # - navigation.expand
+
+nav:
+  - Introduction: "index.md"
+  - Authoring a component:
+      - Authoring a component: 2-authors/0-authoring-a-component.md
+      - Library pages and stories: 2-authors/1-stories-and-library.md
+      - Best practice: 2-authors/2-best-practices.md
+      - Best practice with SDC Devel: 2-authors/3-best-practices_sdc_devel.md
+      - Migration from UI Patterns 1: 2-authors/4-migration-from-UIP1.md
+
+  - Using a component:
+      - Using a component: "1-users/0-component-form.md"
+      - As a Drupal block: "1-users/1-as-block.md"
+      - As a layout: "1-users/2-as-layout.md"
+      - Field formatters: "1-users/3-in-field-formatter.md"
+      - Using a component with Views: "1-users/4-with-views.md"
+      - Presenter templates: "1-users/5-presenter-templates.md"
+
+  - Extends UI Patterns 2:
+      - Source plugins: "3-devs/1-source-plugins.md"
+      - Prop types: "3-devs/2-prop-type-plugins.md"
+      - Internals: "3-devs/3-internals.md"
+
+  - Frequently asked questions: "faq.md"
+
+plugins:
+  - search
+  - privacy:
+      enabled: !ENV [CI, false]
+
+markdown_extensions:
+  # - markdown.extensions.admonition
+  - pymdownx.extra