@wpmoo/ui 0.1.0 → 0.1.1

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/LICENSE CHANGED
@@ -2,17 +2,6 @@ MIT License
2
2
 
3
3
  Copyright (c) 2026 WPMoo (wpmoo.org)
4
4
 
5
- This license applies to the source code in this repository, except where a
6
- file, directory, or third-party notice states otherwise.
7
-
8
- WPMoo-generated visual assets are not licensed under the MIT License unless
9
- explicitly stated. This includes brand assets, component preview images,
10
- marketing images, screenshots, generated artwork, and other WPMoo-owned image
11
- assets under `static/images/`. See `ASSET_LICENSE.md`.
12
-
13
- Vendored third-party material keeps its original license and attribution.
14
- See `THIRD_PARTY_NOTICES.md`.
15
-
16
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
17
6
  of this software and associated documentation files (the "Software"), to deal
18
7
  in the Software without restriction, including without limitation the rights
package/README.md CHANGED
@@ -2,73 +2,137 @@
2
2
 
3
3
  **Bootstrap markup. shadcn feel.**
4
4
 
5
- ![Moo UI catalog preview](static/images/readme-hero.webp)
5
+ Keep your Bootstrap 5.3 HTML and behavior. Replace the stylesheet and give
6
+ your application a calmer, modern product interface without moving to React or
7
+ Tailwind.
6
8
 
7
- Moo UI is a Bootstrap 5.3 component system for teams that want the calm,
8
- modern feel of shadcn/ui without leaving server-rendered HTML, Bootstrap
9
- classes, Bootstrap Sass, or Bootstrap JavaScript behind.
9
+ [Explore the live catalog](https://ui.wpmoo.org/components/) ·
10
+ [Try it in 30 seconds](#try-it-in-30-seconds) ·
11
+ [View on npm](https://www.npmjs.com/package/@wpmoo/ui)
10
12
 
11
- It keeps Bootstrap as the public contract, then shapes the catalog, component
12
- examples, and composed blocks into a quieter product interface language.
13
+ ![Moo UI catalog preview](https://ui.wpmoo.org/assets/images/readme-hero.webp)
13
14
 
14
- ## Philosophy
15
+ [![CI](https://img.shields.io/github/actions/workflow/status/wpmoo-org/ui/ui-ci.yml?branch=main&label=CI&style=flat-square)](https://github.com/wpmoo-org/ui/actions/workflows/ui-ci.yml)
16
+ [![coverage](https://img.shields.io/codecov/c/github/wpmoo-org/ui?branch=main&label=coverage&logo=codecov&style=flat-square&color=blue)](https://codecov.io/gh/wpmoo-org/ui)
17
+ [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&style=flat-square)](https://github.com/wpmoo-org/ui)
18
+ [![npm](https://img.shields.io/npm/v/@wpmoo/ui?label=npm&logo=npm&style=flat-square&color=blue)](https://www.npmjs.com/package/@wpmoo/ui)
19
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE)
15
20
 
16
- - **Bootstrap is the contract.** Moo UI keeps Bootstrap markup, documented
17
- behavior, `data-bs-*` APIs, Sass knobs, and `--bs-*` variables wherever
18
- Bootstrap can express the need.
19
- - **shadcn is the visual language.** Moo UI studies shadcn/ui for restraint,
20
- spacing, composition, and state language. It does not copy shadcn source,
21
- React code, Tailwind code, Radix code, or example prose.
22
- - **HTML stays first-class.** Component examples are generated from Jinja
23
- macros, so the preview and copyable source share one rendered output.
24
- - **No framework adoption tax.** The catalog can be browsed, built, and
25
- shipped as static HTML without a SPA runtime.
26
- - **Product shells matter.** Moo UI includes primitives, utilities, and
27
- composed blocks for Bootstrap applications that need to feel like modern
28
- product software.
21
+ Moo UI is for teams that already like Bootstrap's durability, documented
22
+ components, and server-rendered friendliness, but want their customer portals,
23
+ admin screens, and business applications to feel more like modern SaaS
24
+ software.
29
25
 
30
- ## Documentation
26
+ It keeps Bootstrap as the public contract: familiar classes, `data-bs-*`
27
+ behavior, CSS variables, Sass customization, and Bootstrap JavaScript plugins.
28
+ Moo UI changes the visual language around that contract.
31
29
 
32
- Browse the catalog at [ui.wpmoo.org](https://ui.wpmoo.org/). Component pages,
33
- blocks, examples, local development notes, and implementation contracts belong
34
- in the documentation rather than this README.
30
+ ## Try It in 30 Seconds
35
31
 
36
- ## Package
32
+ Drop the stylesheet into ordinary Bootstrap markup:
37
33
 
38
- The canonical npm package is `@wpmoo/ui`:
34
+ ```html
35
+ <link rel="stylesheet"
36
+ href="https://unpkg.com/@wpmoo/ui@0.1.1/dist/assets/css/moo-ui.css">
39
37
 
40
- ```bash
41
- npm install @wpmoo/ui
38
+ <button type="button" class="btn btn-primary">Create workspace</button>
42
39
  ```
43
40
 
44
- For CDN usage, load the built CSS artifact from the canonical package:
41
+ That is the point of Moo UI: your markup still says Bootstrap, but the surface
42
+ feels quieter, sharper, and more product-ready.
45
43
 
46
- ```html
47
- <link rel="stylesheet" href="https://unpkg.com/@wpmoo/ui/dist/assets/css/moo-ui.css">
48
- ```
44
+ ## Install
45
+
46
+ Use the published package when a bundler owns your build:
49
47
 
50
- Bundlers can import the same stylesheet from the package export:
48
+ ```bash
49
+ npm install @wpmoo/ui
50
+ ```
51
51
 
52
52
  ```js
53
53
  import "@wpmoo/ui/moo-ui.css";
54
54
  ```
55
55
 
56
- If the shorter `@moo/ui` scope is available to WPMoo, it is reserved as a
57
- small alias package only. Use `@wpmoo/ui` in documentation, CDN examples, and
58
- production installs.
56
+ If a page uses Bootstrap plugins such as Dropdown, Tooltip, Popover, Modal,
57
+ Toast, or Offcanvas, load Bootstrap's JavaScript bundle separately through your
58
+ application. Tooltip and Popover also need the initialization Bootstrap
59
+ documents for those plugins.
60
+
61
+ ## Choose an Adoption Path
62
+
63
+ | Situation | Use | Contract |
64
+ | --- | --- | --- |
65
+ | New page or whole application | `moo-ui.css` | Complete Bootstrap CSS build with Moo UI defaults; use it instead of your existing Bootstrap stylesheet. |
66
+ | Gradual adoption inside an existing Bootstrap app | `moo.css` | Scoped Moo component layer under a `.moo-ui` boundary for gradual adoption inside an existing Bootstrap app. |
67
+
68
+ ## Why Bootstrap Teams Try It
69
+
70
+ - **No frontend rewrite.** Keep server-rendered HTML, Bootstrap classes, and
71
+ the component behavior your team already knows.
72
+ - **Modern product rhythm.** Buttons, forms, overlays, navigation, data
73
+ display, and app shells are tuned toward a restrained shadcn-inspired feel.
74
+ - **Inspectable examples.** The catalog is static HTML. Every component page
75
+ shows rendered examples and copyable markup.
76
+ - **Bootstrap-native customization.** Moo UI uses Bootstrap Sass knobs and
77
+ `--bs-*` variables wherever Bootstrap can express the need, adding Moo-owned
78
+ tokens only for gaps Bootstrap does not model.
79
+ - **Practical migration surface.** Start with one page, one scoped area, or a
80
+ full stylesheet replacement after visual review.
81
+
82
+ ## Philosophy
83
+
84
+ - **Bootstrap is the contract.** Moo UI keeps Bootstrap markup, documented
85
+ behavior, Sass knobs, and `--bs-*` variables wherever Bootstrap can express
86
+ the need.
87
+ - **shadcn is the feeling.** Moo UI studies restraint, rhythm, and product UI
88
+ sensibility without adopting React, Tailwind, Radix, or shadcn source.
89
+ - **HTML stays first-class.** The catalog is static, inspectable, and friendly
90
+ to server-rendered applications.
91
+ - **Extensions stay honest.** Moo-owned classes and behavior are added only
92
+ when Bootstrap has no native component contract for the pattern.
93
+
94
+ ## What Is Included
95
+
96
+ The live catalog is the source of truth for current coverage:
97
+
98
+ - [Components](https://ui.wpmoo.org/components/) for actions, forms,
99
+ data display, feedback, disclosure, overlays, and navigation.
100
+ - [Blocks](https://ui.wpmoo.org/blocks/) for composed application
101
+ surfaces such as sidebar layouts.
102
+ - A static documentation site that can be inspected without a client-side app
103
+ runtime.
104
+
105
+ Representative components include Button, Field, Table, Dialog, Toast, Sheet,
106
+ and Sidebar. More components are being added as the catalog roadmap continues.
107
+
108
+ ## Package Boundaries
59
109
 
60
- ## Build Outputs
110
+ The npm package distributes compiled CSS and license/notice files. It does not
111
+ ship the catalog's generated preview images, Jinja templates, Sass source, or
112
+ Moo-owned catalog JavaScript.
61
113
 
62
- The static build emits three CSS artifacts under `dist/assets/css/`:
114
+ The source repository contains the static catalog, component templates, build
115
+ tooling, tests, and documentation.
63
116
 
64
- - `moo-ui.css` for the standalone catalog and examples.
65
- - `catalog.css` for documentation chrome.
66
- - `moo-core.css` for integrations that need the Moo component surface as an
67
- opt-in native `@scope (.moo-ui)` layer.
117
+ ## Development
118
+
119
+ The catalog is intentionally small-tool friendly:
120
+
121
+ ```bash
122
+ .venv/bin/python build.py
123
+ .venv/bin/python dev.py
124
+ .venv/bin/python -m unittest discover -s tests -v
125
+ ```
126
+
127
+ For developers who prefer npm scripts, the package also exposes:
128
+
129
+ ```bash
130
+ npm run build
131
+ npm run dev
132
+ npm test
133
+ ```
68
134
 
69
- The npm package publishes only built component CSS, the optional Bootstrap
70
- bundle, and license/notice files. WPMoo-owned catalog and preview images are
71
- not included in the package.
135
+ Browse the local catalog at `http://localhost:4173/` when `dev.py` is running.
72
136
 
73
137
  ## Licensing
74
138
 
@@ -79,5 +143,4 @@ are not covered by the MIT source code license and remain copyright WPMoo, all
79
143
  rights reserved.
80
144
 
81
145
  Vendored third-party material keeps its original license and attribution. See
82
- `LICENSE`, `LICENSE-MOO-CORE.txt`, `ASSET_LICENSE.md`, and
83
- `THIRD_PARTY_NOTICES.md`.
146
+ `LICENSE`, `ASSET_LICENSE.md`, and `THIRD_PARTY_NOTICES.md`.
@@ -12966,6 +12966,19 @@ label.btn {
12966
12966
  min-width: max(100%, var(--moo-dropdown-sidebar-min-width));
12967
12967
  }
12968
12968
 
12969
+ @media (min-width: 992px) {
12970
+ [data-slot="sidebar-header"] [data-moo-sidebar-dropdown-positioned] > .dropdown-menu {
12971
+ position: fixed !important;
12972
+ z-index: 1000;
12973
+ inset-block-start: var(--moo-sidebar-dropdown-block-start) !important;
12974
+ inset-inline-start: var(--moo-sidebar-dropdown-inline-start) !important;
12975
+ width: var(--moo-dropdown-sidebar-min-width);
12976
+ min-width: var(--moo-dropdown-sidebar-min-width);
12977
+ margin: 0;
12978
+ transform: none !important;
12979
+ }
12980
+ }
12981
+
12969
12982
  .avatar {
12970
12983
  display: inline-flex;
12971
12984
  align-items: center;
@@ -13239,6 +13252,11 @@ label.btn {
13239
13252
  color: var(--moo-sidebar-foreground);
13240
13253
  }
13241
13254
 
13255
+ .sidebar-menu-button.sidebar-menu-button--account,
13256
+ .sidebar-menu-button.sidebar-menu-button--workspace {
13257
+ cursor: default;
13258
+ }
13259
+
13242
13260
  .sidebar-menu-item--account {
13243
13261
  padding-inline: 0;
13244
13262
  }
@@ -13340,6 +13358,10 @@ label.btn {
13340
13358
  font-size: 0.81288rem;
13341
13359
  }
13342
13360
 
13361
+ .sidebar-menu-sub-item {
13362
+ position: relative;
13363
+ }
13364
+
13343
13365
  .sidebar-menu-action {
13344
13366
  position: absolute;
13345
13367
  inset-inline-end: 0.25rem;
@@ -13382,6 +13404,10 @@ label.btn {
13382
13404
  padding-inline-end: 2.5rem;
13383
13405
  }
13384
13406
 
13407
+ .sidebar-menu-sub-item:has(> .sidebar-menu-badge) > .sidebar-menu-button {
13408
+ padding-inline-end: 2.5rem;
13409
+ }
13410
+
13385
13411
  .sidebar-menu-item:has(> .sidebar-menu-action) > .sidebar-menu-badge {
13386
13412
  inset-inline-end: 2rem;
13387
13413
  }
@@ -13420,8 +13446,8 @@ label.btn {
13420
13446
  }
13421
13447
 
13422
13448
  .sidebar-footer .sidebar-account-menu {
13423
- width: 100%;
13424
- min-width: 100%;
13449
+ width: auto;
13450
+ min-width: var(--moo-dropdown-sidebar-min-width);
13425
13451
  padding: 0.25rem;
13426
13452
  border-radius: var(--bs-border-radius-lg);
13427
13453
  box-shadow: var(--bs-box-shadow);
@@ -13553,6 +13579,10 @@ label.btn {
13553
13579
  flex-basis: var(--moo-sidebar-width-icon);
13554
13580
  width: var(--moo-sidebar-width-icon);
13555
13581
  }
13582
+ .sidebar-wrapper[data-moo-sidebar-state="collapsed"] .sidebar-inset {
13583
+ position: relative;
13584
+ z-index: 0;
13585
+ }
13556
13586
  [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-group-label,
13557
13587
  [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-button__text,
13558
13588
  [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-button__subtitle,
@@ -13565,10 +13595,74 @@ label.btn {
13565
13595
  [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-badge {
13566
13596
  display: none !important;
13567
13597
  }
13598
+ [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"]:has(.sidebar-menu-button[data-bs-toggle="dropdown"][aria-expanded="true"]) {
13599
+ z-index: 1000;
13600
+ }
13601
+ .sidebar-menu-flyout {
13602
+ position: fixed;
13603
+ z-index: 1000;
13604
+ inset-block-start: var(--moo-sidebar-flyout-block-start);
13605
+ inset-inline-start: var(--moo-sidebar-flyout-inline-start);
13606
+ display: flex;
13607
+ flex-direction: column;
13608
+ min-width: 10rem;
13609
+ max-width: 14rem;
13610
+ margin: 0;
13611
+ padding: 0.25rem;
13612
+ list-style: none;
13613
+ border: var(--bs-border-width) solid var(--moo-border);
13614
+ border-radius: var(--bs-border-radius-lg);
13615
+ background: var(--moo-surface);
13616
+ box-shadow: var(--bs-box-shadow);
13617
+ }
13618
+ .sidebar-menu-flyout .sidebar-menu-sub-item {
13619
+ position: relative;
13620
+ }
13621
+ .sidebar-menu-flyout .sidebar-menu-button {
13622
+ justify-content: flex-start;
13623
+ height: 2rem;
13624
+ padding-inline: 0.5rem;
13625
+ }
13626
+ .sidebar-menu-flyout .sidebar-menu-button__text {
13627
+ display: grid;
13628
+ }
13629
+ .sidebar-menu-flyout .sidebar-menu-badge {
13630
+ display: flex !important;
13631
+ }
13568
13632
  [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-button {
13569
13633
  justify-content: center;
13570
13634
  padding-inline: 0;
13571
13635
  }
13636
+ [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-button--workspace:hover {
13637
+ background: transparent;
13638
+ }
13639
+ [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-button--workspace[aria-expanded="true"] {
13640
+ background: transparent;
13641
+ outline: 0;
13642
+ box-shadow: none;
13643
+ }
13644
+ [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-button--workspace:focus-visible {
13645
+ background: transparent;
13646
+ outline: 0;
13647
+ box-shadow: none;
13648
+ }
13649
+ [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-item--account > .sidebar-menu-button--account {
13650
+ padding: 0;
13651
+ overflow: visible;
13652
+ }
13653
+ [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-item--account > .sidebar-menu-button--account:hover {
13654
+ background: transparent;
13655
+ }
13656
+ [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-item--account > .sidebar-menu-button--account[aria-expanded="true"] {
13657
+ background: transparent;
13658
+ outline: 0;
13659
+ box-shadow: none;
13660
+ }
13661
+ [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-item--account > .sidebar-menu-button--account:focus-visible {
13662
+ background: transparent;
13663
+ outline: 0;
13664
+ box-shadow: none;
13665
+ }
13572
13666
  [data-moo-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-menu-button--lg {
13573
13667
  height: 2rem;
13574
13668
  padding: 0;
@@ -13784,3 +13878,180 @@ label.btn {
13784
13878
  font-size: 0.875rem;
13785
13879
  color: var(--moo-muted-foreground);
13786
13880
  }
13881
+
13882
+ .tooltip {
13883
+ --bs-tooltip-max-width: 20rem;
13884
+ --bs-tooltip-padding-x: 0.75rem;
13885
+ --bs-tooltip-padding-y: 0.375rem;
13886
+ --bs-tooltip-font-size: 0.75rem;
13887
+ --bs-tooltip-opacity: 1;
13888
+ line-height: 1.333;
13889
+ }
13890
+
13891
+ .tooltip-trigger {
13892
+ color: var(--moo-foreground);
13893
+ text-decoration-line: underline;
13894
+ text-decoration-style: dotted;
13895
+ text-decoration-color: var(--moo-muted-foreground);
13896
+ text-underline-offset: 0.2em;
13897
+ }
13898
+
13899
+ .tooltip-kbd {
13900
+ padding: 0.125rem 0.375rem;
13901
+ font-size: 0.75rem;
13902
+ color: var(--bs-body-bg);
13903
+ background-color: var(--bs-body-color);
13904
+ border-radius: var(--bs-border-radius-sm);
13905
+ }
13906
+
13907
+ .popover {
13908
+ --bs-popover-border-radius: var(--bs-border-radius-lg);
13909
+ --bs-popover-border-color: var(--moo-border);
13910
+ --bs-popover-header-bg: var(--bs-popover-bg);
13911
+ --bs-popover-header-color: var(--bs-popover-body-color);
13912
+ --bs-popover-header-padding-x: 0.625rem;
13913
+ --bs-popover-header-padding-y: 0.625rem;
13914
+ --bs-popover-body-padding-x: 0.625rem;
13915
+ --bs-popover-body-padding-y: 0.625rem;
13916
+ --bs-popover-font-size: 0.875rem;
13917
+ line-height: 1.43;
13918
+ --bs-popover-max-width: 20rem;
13919
+ width: 20rem;
13920
+ box-shadow: var(--bs-box-shadow-lg);
13921
+ }
13922
+
13923
+ .popover-header {
13924
+ padding-bottom: 0;
13925
+ border-bottom: 0;
13926
+ font-weight: 500;
13927
+ }
13928
+
13929
+ .popover .popover-arrow {
13930
+ display: none;
13931
+ }
13932
+
13933
+ .modal {
13934
+ --bs-modal-border-radius: var(--bs-border-radius-xl);
13935
+ --bs-modal-border-color: var(--moo-border);
13936
+ --bs-modal-header-border-width: 0;
13937
+ --bs-modal-footer-border-color: var(--moo-border);
13938
+ --bs-modal-title-line-height: 1;
13939
+ }
13940
+
13941
+ .modal[tabindex]:focus-visible {
13942
+ outline: none;
13943
+ }
13944
+
13945
+ .modal-content {
13946
+ box-shadow: var(--bs-box-shadow-lg);
13947
+ }
13948
+
13949
+ .modal-title {
13950
+ font-size: 1rem;
13951
+ font-weight: 500;
13952
+ }
13953
+
13954
+ .modal-footer {
13955
+ padding: 1rem;
13956
+ }
13957
+
13958
+ body:has(.modal.show) > .modal-backdrop {
13959
+ --bs-backdrop-opacity: 1;
13960
+ background-color: color-mix(in srgb, var(--bs-black) 10%, transparent);
13961
+ -webkit-backdrop-filter: blur(4px);
13962
+ backdrop-filter: blur(4px);
13963
+ }
13964
+
13965
+ .offcanvas.sheet {
13966
+ --bs-offcanvas-width: 24rem;
13967
+ --bs-offcanvas-border-color: var(--moo-border);
13968
+ box-shadow: var(--bs-box-shadow-lg);
13969
+ }
13970
+
13971
+ .offcanvas.sheet[tabindex]:focus-visible {
13972
+ outline: none;
13973
+ box-shadow: var(--bs-box-shadow-lg);
13974
+ }
13975
+
13976
+ .offcanvas.sheet .offcanvas-title {
13977
+ font-size: 1rem;
13978
+ font-weight: 500;
13979
+ }
13980
+
13981
+ :has(> .offcanvas.sheet:is(.showing, .show, .hiding)) > .offcanvas-backdrop {
13982
+ background-color: color-mix(in srgb, var(--bs-black) 10%, transparent);
13983
+ transition: opacity 0.3s ease-in-out, -webkit-backdrop-filter 0.3s ease-in-out, backdrop-filter 0.3s ease-in-out;
13984
+ }
13985
+
13986
+ :has(> .offcanvas.sheet:is(.showing, .show)) > .offcanvas-backdrop {
13987
+ opacity: 1;
13988
+ -webkit-backdrop-filter: blur(4px);
13989
+ backdrop-filter: blur(4px);
13990
+ }
13991
+
13992
+ :has(> .offcanvas.sheet.hiding) > .offcanvas-backdrop {
13993
+ opacity: 0;
13994
+ -webkit-backdrop-filter: blur(0);
13995
+ backdrop-filter: blur(0);
13996
+ }
13997
+
13998
+ .toast {
13999
+ --bs-toast-border-radius: var(--bs-border-radius-lg);
14000
+ --bs-toast-border-color: var(--moo-border);
14001
+ --bs-toast-box-shadow: var(--bs-box-shadow-lg);
14002
+ --bs-toast-padding-x: 1rem;
14003
+ }
14004
+
14005
+ .toast-header strong {
14006
+ font-weight: 500;
14007
+ }
14008
+
14009
+ .field {
14010
+ display: flex;
14011
+ flex-direction: column;
14012
+ gap: 0.5rem;
14013
+ }
14014
+
14015
+ .field > .form-label {
14016
+ margin-bottom: 0;
14017
+ font-weight: 500;
14018
+ }
14019
+
14020
+ .field-description,
14021
+ .field-error {
14022
+ margin-top: 0;
14023
+ font-size: 0.875rem;
14024
+ }
14025
+
14026
+ .field-group {
14027
+ display: flex;
14028
+ flex-direction: column;
14029
+ gap: 1.25rem;
14030
+ }
14031
+
14032
+ .field-group > hr {
14033
+ margin-block: 0;
14034
+ }
14035
+
14036
+ .field-legend {
14037
+ font-size: 1rem;
14038
+ font-weight: 500;
14039
+ margin-bottom: 0.375rem;
14040
+ }
14041
+
14042
+ .field-fieldset > * + * {
14043
+ margin-top: 1rem;
14044
+ }
14045
+
14046
+ .field-fieldset > .field-legend + .field-description {
14047
+ margin-top: 0;
14048
+ }
14049
+
14050
+ .field-fieldset + hr {
14051
+ opacity: 0.1;
14052
+ }
14053
+
14054
+ .form-label,
14055
+ .form-check-label {
14056
+ user-select: none;
14057
+ }