summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf/settings/base.py3
-rw-r--r--core/static/css/main.css3
-rw-r--r--core/static/css/output.css2933
-rw-r--r--core/templates/core/base.html45
-rw-r--r--core/templates/core/index.html166
-rw-r--r--engagements/forms.py155
-rw-r--r--engagements/templates/engagements/engagement_create.html62
-rw-r--r--engagements/templates/engagements/engagement_detail.html167
-rw-r--r--engagements/templates/engagements/engagement_effort_create.html34
-rw-r--r--engagements/templates/engagements/engagement_form.html78
-rw-r--r--engagements/templates/engagements/ep_org.html516
-rw-r--r--engagements/templates/engagements/index.html47
-rw-r--r--engagements/templates/engagements/organisations.html90
-rw-r--r--engagements/templates/engagements/snippets/effort_summary_panel.html56
-rw-r--r--myuser/models.py19
-rw-r--r--package-lock.json1595
-rw-r--r--package.json11
-rw-r--r--postcss.config.js6
-rw-r--r--requirements.txt1
-rwxr-xr-xscripts/watch_and_build.sh6
-rw-r--r--tailwind.config.js18
21 files changed, 5179 insertions, 832 deletions
diff --git a/conf/settings/base.py b/conf/settings/base.py
index ce622eb..fb9b658 100644
--- a/conf/settings/base.py
+++ b/conf/settings/base.py
@@ -50,7 +50,6 @@ INSTALLED_APPS = [
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
- "crispy_forms",
"django_htmx",
# "debug_toolbar",
]
@@ -97,8 +96,6 @@ TEMPLATES = [
},
]
-CRISPY_ALLOWED_TEMPLATE_PACKS = ("w3",)
-CRISPY_TEMPLATE_PACK = "w3"
WSGI_APPLICATION = "ded.wsgi.application"
diff --git a/core/static/css/main.css b/core/static/css/main.css
new file mode 100644
index 0000000..5be59b4
--- /dev/null
+++ b/core/static/css/main.css
@@ -0,0 +1,3 @@
+@import 'tailwindcss/base';
+@import 'tailwindcss/components';
+@import 'tailwindcss/utilities'; \ No newline at end of file
diff --git a/core/static/css/output.css b/core/static/css/output.css
new file mode 100644
index 0000000..e25155d
--- /dev/null
+++ b/core/static/css/output.css
@@ -0,0 +1,2933 @@
+/*
+! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com
+*/
+
+/*
+1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
+2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
+*/
+
+*,
+::before,
+::after {
+ box-sizing: border-box;
+ /* 1 */
+ border-width: 0;
+ /* 2 */
+ border-style: solid;
+ /* 2 */
+ border-color: #e5e7eb;
+ /* 2 */
+}
+
+::before,
+::after {
+ --tw-content: '';
+}
+
+/*
+1. Use a consistent sensible line-height in all browsers.
+2. Prevent adjustments of font size after orientation changes in iOS.
+3. Use a more readable tab size.
+4. Use the user's configured `sans` font-family by default.
+5. Use the user's configured `sans` font-feature-settings by default.
+6. Use the user's configured `sans` font-variation-settings by default.
+7. Disable tap highlights on iOS
+*/
+
+html,
+:host {
+ line-height: 1.5;
+ /* 1 */
+ -webkit-text-size-adjust: 100%;
+ /* 2 */
+ -moz-tab-size: 4;
+ /* 3 */
+ -o-tab-size: 4;
+ tab-size: 4;
+ /* 3 */
+ font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ /* 4 */
+ font-feature-settings: normal;
+ /* 5 */
+ font-variation-settings: normal;
+ /* 6 */
+ -webkit-tap-highlight-color: transparent;
+ /* 7 */
+}
+
+/*
+1. Remove the margin in all browsers.
+2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
+*/
+
+body {
+ margin: 0;
+ /* 1 */
+ line-height: inherit;
+ /* 2 */
+}
+
+/*
+1. Add the correct height in Firefox.
+2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
+3. Ensure horizontal rules are visible by default.
+*/
+
+hr {
+ height: 0;
+ /* 1 */
+ color: inherit;
+ /* 2 */
+ border-top-width: 1px;
+ /* 3 */
+}
+
+/*
+Add the correct text decoration in Chrome, Edge, and Safari.
+*/
+
+abbr:where([title]) {
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted;
+}
+
+/*
+Remove the default font size and weight for headings.
+*/
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-size: inherit;
+ font-weight: inherit;
+}
+
+/*
+Reset links to optimize for opt-in styling instead of opt-out.
+*/
+
+a {
+ color: inherit;
+ text-decoration: inherit;
+}
+
+/*
+Add the correct font weight in Edge and Safari.
+*/
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/*
+1. Use the user's configured `mono` font-family by default.
+2. Use the user's configured `mono` font-feature-settings by default.
+3. Use the user's configured `mono` font-variation-settings by default.
+4. Correct the odd `em` font sizing in all browsers.
+*/
+
+code,
+kbd,
+samp,
+pre {
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+ /* 1 */
+ font-feature-settings: normal;
+ /* 2 */
+ font-variation-settings: normal;
+ /* 3 */
+ font-size: 1em;
+ /* 4 */
+}
+
+/*
+Add the correct font size in all browsers.
+*/
+
+small {
+ font-size: 80%;
+}
+
+/*
+Prevent `sub` and `sup` elements from affecting the line height in all browsers.
+*/
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/*
+1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
+2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
+3. Remove gaps between table borders by default.
+*/
+
+table {
+ text-indent: 0;
+ /* 1 */
+ border-color: inherit;
+ /* 2 */
+ border-collapse: collapse;
+ /* 3 */
+}
+
+/*
+1. Change the font styles in all browsers.
+2. Remove the margin in Firefox and Safari.
+3. Remove default padding in all browsers.
+*/
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit;
+ /* 1 */
+ font-feature-settings: inherit;
+ /* 1 */
+ font-variation-settings: inherit;
+ /* 1 */
+ font-size: 100%;
+ /* 1 */
+ font-weight: inherit;
+ /* 1 */
+ line-height: inherit;
+ /* 1 */
+ letter-spacing: inherit;
+ /* 1 */
+ color: inherit;
+ /* 1 */
+ margin: 0;
+ /* 2 */
+ padding: 0;
+ /* 3 */
+}
+
+/*
+Remove the inheritance of text transform in Edge and Firefox.
+*/
+
+button,
+select {
+ text-transform: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Remove default button styles.
+*/
+
+button,
+input:where([type='button']),
+input:where([type='reset']),
+input:where([type='submit']) {
+ -webkit-appearance: button;
+ /* 1 */
+ background-color: transparent;
+ /* 2 */
+ background-image: none;
+ /* 2 */
+}
+
+/*
+Use the modern Firefox focus style for all focusable elements.
+*/
+
+:-moz-focusring {
+ outline: auto;
+}
+
+/*
+Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
+*/
+
+:-moz-ui-invalid {
+ box-shadow: none;
+}
+
+/*
+Add the correct vertical alignment in Chrome and Firefox.
+*/
+
+progress {
+ vertical-align: baseline;
+}
+
+/*
+Correct the cursor style of increment and decrement buttons in Safari.
+*/
+
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/*
+1. Correct the odd appearance in Chrome and Safari.
+2. Correct the outline style in Safari.
+*/
+
+[type='search'] {
+ -webkit-appearance: textfield;
+ /* 1 */
+ outline-offset: -2px;
+ /* 2 */
+}
+
+/*
+Remove the inner padding in Chrome and Safari on macOS.
+*/
+
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Change font properties to `inherit` in Safari.
+*/
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ /* 1 */
+ font: inherit;
+ /* 2 */
+}
+
+/*
+Add the correct display in Chrome and Safari.
+*/
+
+summary {
+ display: list-item;
+}
+
+/*
+Removes the default spacing and border for appropriate elements.
+*/
+
+blockquote,
+dl,
+dd,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+figure,
+p,
+pre {
+ margin: 0;
+}
+
+fieldset {
+ margin: 0;
+ padding: 0;
+}
+
+legend {
+ padding: 0;
+}
+
+ol,
+ul,
+menu {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+/*
+Reset default styling for dialogs.
+*/
+
+dialog {
+ padding: 0;
+}
+
+/*
+Prevent resizing textareas horizontally by default.
+*/
+
+textarea {
+ resize: vertical;
+}
+
+/*
+1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
+2. Set the default placeholder color to the user's configured gray 400 color.
+*/
+
+input::-moz-placeholder, textarea::-moz-placeholder {
+ opacity: 1;
+ /* 1 */
+ color: #9ca3af;
+ /* 2 */
+}
+
+input::placeholder,
+textarea::placeholder {
+ opacity: 1;
+ /* 1 */
+ color: #9ca3af;
+ /* 2 */
+}
+
+/*
+Set the default cursor for buttons.
+*/
+
+button,
+[role="button"] {
+ cursor: pointer;
+}
+
+/*
+Make sure disabled buttons don't get the pointer cursor.
+*/
+
+:disabled {
+ cursor: default;
+}
+
+/*
+1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
+2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
+ This can trigger a poorly considered lint error in some tools but is included by design.
+*/
+
+img,
+svg,
+video,
+canvas,
+audio,
+iframe,
+embed,
+object {
+ display: block;
+ /* 1 */
+ vertical-align: middle;
+ /* 2 */
+}
+
+/*
+Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
+*/
+
+img,
+video {
+ max-width: 100%;
+ height: auto;
+}
+
+/* Make elements with the HTML hidden attribute stay hidden by default */
+
+[hidden] {
+ display: none;
+}
+
+:root,
+[data-theme] {
+ background-color: var(--fallback-b1,oklch(var(--b1)/1));
+ color: var(--fallback-bc,oklch(var(--bc)/1));
+}
+
+@supports not (color: oklch(0% 0 0)) {
+ :root {
+ color-scheme: light;
+ --fallback-p: #491eff;
+ --fallback-pc: #d4dbff;
+ --fallback-s: #ff41c7;
+ --fallback-sc: #fff9fc;
+ --fallback-a: #00cfbd;
+ --fallback-ac: #00100d;
+ --fallback-n: #2b3440;
+ --fallback-nc: #d7dde4;
+ --fallback-b1: #ffffff;
+ --fallback-b2: #e5e6e6;
+ --fallback-b3: #e5e6e6;
+ --fallback-bc: #1f2937;
+ --fallback-in: #00b3f0;
+ --fallback-inc: #000000;
+ --fallback-su: #00ca92;
+ --fallback-suc: #000000;
+ --fallback-wa: #ffc22d;
+ --fallback-wac: #000000;
+ --fallback-er: #ff6f70;
+ --fallback-erc: #000000;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ :root {
+ color-scheme: dark;
+ --fallback-p: #7582ff;
+ --fallback-pc: #050617;
+ --fallback-s: #ff71cf;
+ --fallback-sc: #190211;
+ --fallback-a: #00c7b5;
+ --fallback-ac: #000e0c;
+ --fallback-n: #2a323c;
+ --fallback-nc: #a6adbb;
+ --fallback-b1: #1d232a;
+ --fallback-b2: #191e24;
+ --fallback-b3: #15191e;
+ --fallback-bc: #a6adbb;
+ --fallback-in: #00b3f0;
+ --fallback-inc: #000000;
+ --fallback-su: #00ca92;
+ --fallback-suc: #000000;
+ --fallback-wa: #ffc22d;
+ --fallback-wac: #000000;
+ --fallback-er: #ff6f70;
+ --fallback-erc: #000000;
+ }
+ }
+}
+
+html {
+ -webkit-tap-highlight-color: transparent;
+}
+
+* {
+ scrollbar-color: color-mix(in oklch, currentColor 35%, transparent) transparent;
+}
+
+*:hover {
+ scrollbar-color: color-mix(in oklch, currentColor 60%, transparent) transparent;
+}
+
+:root {
+ color-scheme: light;
+ --in: 72.06% 0.191 231.6;
+ --su: 64.8% 0.150 160;
+ --wa: 84.71% 0.199 83.87;
+ --er: 71.76% 0.221 22.18;
+ --pc: 89.824% 0.06192 275.75;
+ --ac: 15.352% 0.0368 183.61;
+ --inc: 0% 0 0;
+ --suc: 0% 0 0;
+ --wac: 0% 0 0;
+ --erc: 0% 0 0;
+ --rounded-box: 1rem;
+ --rounded-btn: 0.5rem;
+ --rounded-badge: 1.9rem;
+ --animation-btn: 0.25s;
+ --animation-input: .2s;
+ --btn-focus-scale: 0.95;
+ --border-btn: 1px;
+ --tab-border: 1px;
+ --tab-radius: 0.5rem;
+ --p: 49.12% 0.3096 275.75;
+ --s: 69.71% 0.329 342.55;
+ --sc: 98.71% 0.0106 342.55;
+ --a: 76.76% 0.184 183.61;
+ --n: 32.1785% 0.02476 255.701624;
+ --nc: 89.4994% 0.011585 252.096176;
+ --b1: 100% 0 0;
+ --b2: 96.1151% 0 0;
+ --b3: 92.4169% 0.00108 197.137559;
+ --bc: 27.8078% 0.029596 256.847952;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ color-scheme: dark;
+ --in: 72.06% 0.191 231.6;
+ --su: 64.8% 0.150 160;
+ --wa: 84.71% 0.199 83.87;
+ --er: 71.76% 0.221 22.18;
+ --pc: 13.138% 0.0392 275.75;
+ --sc: 14.96% 0.052 342.55;
+ --ac: 14.902% 0.0334 183.61;
+ --inc: 0% 0 0;
+ --suc: 0% 0 0;
+ --wac: 0% 0 0;
+ --erc: 0% 0 0;
+ --rounded-box: 1rem;
+ --rounded-btn: 0.5rem;
+ --rounded-badge: 1.9rem;
+ --animation-btn: 0.25s;
+ --animation-input: .2s;
+ --btn-focus-scale: 0.95;
+ --border-btn: 1px;
+ --tab-border: 1px;
+ --tab-radius: 0.5rem;
+ --p: 65.69% 0.196 275.75;
+ --s: 74.8% 0.26 342.55;
+ --a: 74.51% 0.167 183.61;
+ --n: 31.3815% 0.021108 254.139175;
+ --nc: 74.6477% 0.0216 264.435964;
+ --b1: 25.3267% 0.015896 252.417568;
+ --b2: 23.2607% 0.013807 253.100675;
+ --b3: 21.1484% 0.01165 254.087939;
+ --bc: 74.6477% 0.0216 264.435964;
+ }
+}
+
+[data-theme=light] {
+ color-scheme: light;
+ --in: 72.06% 0.191 231.6;
+ --su: 64.8% 0.150 160;
+ --wa: 84.71% 0.199 83.87;
+ --er: 71.76% 0.221 22.18;
+ --pc: 89.824% 0.06192 275.75;
+ --ac: 15.352% 0.0368 183.61;
+ --inc: 0% 0 0;
+ --suc: 0% 0 0;
+ --wac: 0% 0 0;
+ --erc: 0% 0 0;
+ --rounded-box: 1rem;
+ --rounded-btn: 0.5rem;
+ --rounded-badge: 1.9rem;
+ --animation-btn: 0.25s;
+ --animation-input: .2s;
+ --btn-focus-scale: 0.95;
+ --border-btn: 1px;
+ --tab-border: 1px;
+ --tab-radius: 0.5rem;
+ --p: 49.12% 0.3096 275.75;
+ --s: 69.71% 0.329 342.55;
+ --sc: 98.71% 0.0106 342.55;
+ --a: 76.76% 0.184 183.61;
+ --n: 32.1785% 0.02476 255.701624;
+ --nc: 89.4994% 0.011585 252.096176;
+ --b1: 100% 0 0;
+ --b2: 96.1151% 0 0;
+ --b3: 92.4169% 0.00108 197.137559;
+ --bc: 27.8078% 0.029596 256.847952;
+}
+
+[data-theme=dark] {
+ color-scheme: dark;
+ --in: 72.06% 0.191 231.6;
+ --su: 64.8% 0.150 160;
+ --wa: 84.71% 0.199 83.87;
+ --er: 71.76% 0.221 22.18;
+ --pc: 13.138% 0.0392 275.75;
+ --sc: 14.96% 0.052 342.55;
+ --ac: 14.902% 0.0334 183.61;
+ --inc: 0% 0 0;
+ --suc: 0% 0 0;
+ --wac: 0% 0 0;
+ --erc: 0% 0 0;
+ --rounded-box: 1rem;
+ --rounded-btn: 0.5rem;
+ --rounded-badge: 1.9rem;
+ --animation-btn: 0.25s;
+ --animation-input: .2s;
+ --btn-focus-scale: 0.95;
+ --border-btn: 1px;
+ --tab-border: 1px;
+ --tab-radius: 0.5rem;
+ --p: 65.69% 0.196 275.75;
+ --s: 74.8% 0.26 342.55;
+ --a: 74.51% 0.167 183.61;
+ --n: 31.3815% 0.021108 254.139175;
+ --nc: 74.6477% 0.0216 264.435964;
+ --b1: 25.3267% 0.015896 252.417568;
+ --b2: 23.2607% 0.013807 253.100675;
+ --b3: 21.1484% 0.01165 254.087939;
+ --bc: 74.6477% 0.0216 264.435964;
+}
+
+[data-theme=cupcake] {
+ color-scheme: light;
+ --in: 72.06% 0.191 231.6;
+ --su: 64.8% 0.150 160;
+ --wa: 84.71% 0.199 83.87;
+ --er: 71.76% 0.221 22.18;
+ --pc: 15.2344% 0.017892 200.026556;
+ --sc: 15.787% 0.020249 356.29965;
+ --ac: 15.8762% 0.029206 78.618794;
+ --nc: 84.7148% 0.013247 313.189598;
+ --inc: 0% 0 0;
+ --suc: 0% 0 0;
+ --wac: 0% 0 0;
+ --erc: 0% 0 0;
+ --rounded-box: 1rem;
+ --rounded-badge: 1.9rem;
+ --animation-btn: 0.25s;
+ --animation-input: .2s;
+ --btn-focus-scale: 0.95;
+ --border-btn: 1px;
+ --p: 76.172% 0.089459 200.026556;
+ --s: 78.9351% 0.101246 356.29965;
+ --a: 79.3811% 0.146032 78.618794;
+ --n: 23.5742% 0.066235 313.189598;
+ --b1: 97.7882% 0.00418 56.375637;
+ --b2: 93.9822% 0.007638 61.449292;
+ --b3: 91.5861% 0.006811 53.440502;
+ --bc: 23.5742% 0.066235 313.189598;
+ --rounded-btn: 1.9rem;
+ --tab-border: 2px;
+ --tab-radius: 0.7rem;
+}
+
+*, ::before, ::after {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-gradient-from-position: ;
+ --tw-gradient-via-position: ;
+ --tw-gradient-to-position: ;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia: ;
+ --tw-contain-size: ;
+ --tw-contain-layout: ;
+ --tw-contain-paint: ;
+ --tw-contain-style: ;
+}
+
+::backdrop {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-gradient-from-position: ;
+ --tw-gradient-via-position: ;
+ --tw-gradient-to-position: ;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia: ;
+ --tw-contain-size: ;
+ --tw-contain-layout: ;
+ --tw-contain-paint: ;
+ --tw-contain-style: ;
+}
+
+.container {
+ width: 100%;
+}
+
+@media (min-width: 640px) {
+ .container {
+ max-width: 640px;
+ }
+}
+
+@media (min-width: 768px) {
+ .container {
+ max-width: 768px;
+ }
+}
+
+@media (min-width: 1024px) {
+ .container {
+ max-width: 1024px;
+ }
+}
+
+@media (min-width: 1280px) {
+ .container {
+ max-width: 1280px;
+ }
+}
+
+@media (min-width: 1536px) {
+ .container {
+ max-width: 1536px;
+ }
+}
+
+.alert {
+ display: grid;
+ width: 100%;
+ grid-auto-flow: row;
+ align-content: flex-start;
+ align-items: center;
+ justify-items: center;
+ gap: 1rem;
+ text-align: center;
+ border-radius: var(--rounded-box, 1rem);
+ border-width: 1px;
+ --tw-border-opacity: 1;
+ border-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));
+ padding: 1rem;
+ --tw-text-opacity: 1;
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
+ --alert-bg: var(--fallback-b2,oklch(var(--b2)/1));
+ --alert-bg-mix: var(--fallback-b1,oklch(var(--b1)/1));
+ background-color: var(--alert-bg);
+}
+
+@media (min-width: 640px) {
+ .alert {
+ grid-auto-flow: column;
+ grid-template-columns: auto minmax(auto,1fr);
+ justify-items: start;
+ text-align: start;
+ }
+}
+
+.avatar.placeholder > div {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.breadcrumbs {
+ max-width: 100%;
+ overflow-x: auto;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+
+.breadcrumbs > ul,
+ .breadcrumbs > ol {
+ display: flex;
+ align-items: center;
+ white-space: nowrap;
+ min-height: -moz-min-content;
+ min-height: min-content;
+}
+
+.breadcrumbs > ul > li, .breadcrumbs > ol > li {
+ display: flex;
+ align-items: center;
+}
+
+.breadcrumbs > ul > li > a, .breadcrumbs > ol > li > a {
+ display: flex;
+ cursor: pointer;
+ align-items: center;
+}
+
+@media (hover:hover) {
+ .breadcrumbs > ul > li > a:hover, .breadcrumbs > ol > li > a:hover {
+ text-decoration-line: underline;
+ }
+
+ .label a:hover {
+ --tw-text-opacity: 1;
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
+ }
+
+ .menu li > *:not(ul, .menu-title, details, .btn):active,
+.menu li > *:not(ul, .menu-title, details, .btn).active,
+.menu li > details > summary:active {
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));
+ --tw-text-opacity: 1;
+ color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity)));
+ }
+
+ .tab:hover {
+ --tw-text-opacity: 1;
+ }
+
+ .table tr.hover:hover,
+ .table tr.hover:nth-child(even):hover {
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));
+ }
+}
+
+.btn {
+ display: inline-flex;
+ height: 3rem;
+ min-height: 3rem;
+ flex-shrink: 0;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--rounded-btn, 0.5rem);
+ border-color: transparent;
+ border-color: oklch(var(--btn-color, var(--b2)) / var(--tw-border-opacity));
+ padding-left: 1rem;
+ padding-right: 1rem;
+ text-align: center;
+ font-size: 0.875rem;
+ line-height: 1em;
+ gap: 0.5rem;
+ font-weight: 600;
+ text-decoration-line: none;
+ transition-duration: 200ms;
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
+ border-width: var(--border-btn, 1px);
+ transition-property: color, background-color, border-color, opacity, box-shadow, transform;
+ --tw-text-opacity: 1;
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ outline-color: var(--fallback-bc,oklch(var(--bc)/1));
+ background-color: oklch(var(--btn-color, var(--b2)) / var(--tw-bg-opacity));
+ --tw-bg-opacity: 1;
+ --tw-border-opacity: 1;
+}
+
+.btn-disabled,
+ .btn[disabled],
+ .btn:disabled {
+ pointer-events: none;
+}
+
+:where(.btn:is(input[type="checkbox"])),
+:where(.btn:is(input[type="radio"])) {
+ width: auto;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+
+.btn:is(input[type="checkbox"]):after,
+.btn:is(input[type="radio"]):after {
+ --tw-content: attr(aria-label);
+ content: var(--tw-content);
+}
+
+.card {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ border-radius: var(--rounded-box, 1rem);
+}
+
+.card:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.card-body {
+ display: flex;
+ flex: 1 1 auto;
+ flex-direction: column;
+ padding: var(--padding-card, 2rem);
+ gap: 0.5rem;
+}
+
+.card-body :where(p) {
+ flex-grow: 1;
+}
+
+.card figure {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.card.image-full {
+ display: grid;
+}
+
+.card.image-full:before {
+ position: relative;
+ content: "";
+ z-index: 10;
+ border-radius: var(--rounded-box, 1rem);
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));
+ opacity: 0.75;
+}
+
+.card.image-full:before,
+ .card.image-full > * {
+ grid-column-start: 1;
+ grid-row-start: 1;
+}
+
+.card.image-full > figure img {
+ height: 100%;
+ -o-object-fit: cover;
+ object-fit: cover;
+}
+
+.card.image-full > .card-body {
+ position: relative;
+ z-index: 20;
+ --tw-text-opacity: 1;
+ color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity)));
+}
+
+.checkbox {
+ flex-shrink: 0;
+ --chkbg: var(--fallback-bc,oklch(var(--bc)/1));
+ --chkfg: var(--fallback-b1,oklch(var(--b1)/1));
+ height: 1.5rem;
+ width: 1.5rem;
+ cursor: pointer;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border-radius: var(--rounded-btn, 0.5rem);
+ border-width: 1px;
+ border-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-border-opacity)));
+ --tw-border-opacity: 0.2;
+}
+
+.collapse:not(td):not(tr):not(colgroup) {
+ visibility: visible;
+}
+
+.collapse {
+ position: relative;
+ display: grid;
+ overflow: hidden;
+ grid-template-rows: auto 0fr;
+ transition: grid-template-rows 0.2s;
+ width: 100%;
+ border-radius: var(--rounded-box, 1rem);
+}
+
+.collapse-title,
+.collapse > input[type="checkbox"],
+.collapse > input[type="radio"],
+.collapse-content {
+ grid-column-start: 1;
+ grid-row-start: 1;
+}
+
+.collapse > input[type="checkbox"],
+.collapse > input[type="radio"] {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ opacity: 0;
+}
+
+.collapse[open],
+.collapse-open,
+.collapse:focus:not(.collapse-close) {
+ grid-template-rows: auto 1fr;
+}
+
+.collapse:not(.collapse-close):has(> input[type="checkbox"]:checked),
+.collapse:not(.collapse-close):has(> input[type="radio"]:checked) {
+ grid-template-rows: auto 1fr;
+}
+
+.collapse[open] > .collapse-content,
+.collapse-open > .collapse-content,
+.collapse:focus:not(.collapse-close) > .collapse-content,
+.collapse:not(.collapse-close) > input[type="checkbox"]:checked ~ .collapse-content,
+.collapse:not(.collapse-close) > input[type="radio"]:checked ~ .collapse-content {
+ visibility: visible;
+ min-height: -moz-fit-content;
+ min-height: fit-content;
+}
+
+@media (hover: hover) {
+ .btm-nav > *.disabled:hover,
+ .btm-nav > *[disabled]:hover {
+ pointer-events: none;
+ --tw-border-opacity: 0;
+ background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));
+ --tw-bg-opacity: 0.1;
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
+ --tw-text-opacity: 0.2;
+ }
+
+ .btn:hover {
+ --tw-border-opacity: 1;
+ border-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-border-opacity)));
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)));
+ }
+
+ @supports (color: color-mix(in oklab, black, black)) {
+ .btn:hover {
+ background-color: color-mix(
+ in oklab,
+ oklch(var(--btn-color, var(--b2)) / var(--tw-bg-opacity, 1)) 90%,
+ black
+ );
+ border-color: color-mix(
+ in oklab,
+ oklch(var(--btn-color, var(--b2)) / var(--tw-border-opacity, 1)) 90%,
+ black
+ );
+ }
+ }
+
+ @supports not (color: oklch(0% 0 0)) {
+ .btn:hover {
+ background-color: var(--btn-color, var(--fallback-b2));
+ border-color: var(--btn-color, var(--fallback-b2));
+ }
+ }
+
+ .btn.glass:hover {
+ --glass-opacity: 25%;
+ --glass-border-opacity: 15%;
+ }
+
+ .btn-outline.btn-primary:hover {
+ --tw-text-opacity: 1;
+ color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
+ }
+
+ @supports (color: color-mix(in oklab, black, black)) {
+ .btn-outline.btn-primary:hover {
+ background-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
+ border-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
+ }
+ }
+
+ .btn-disabled:hover,
+ .btn[disabled]:hover,
+ .btn:disabled:hover {
+ --tw-border-opacity: 0;
+ background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));
+ --tw-bg-opacity: 0.2;
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
+ --tw-text-opacity: 0.2;
+ }
+
+ @supports (color: color-mix(in oklab, black, black)) {
+ .btn:is(input[type="checkbox"]:checked):hover, .btn:is(input[type="radio"]:checked):hover {
+ background-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
+ border-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
+ }
+ }
+
+ .tab[disabled],
+ .tab[disabled]:hover {
+ cursor: not-allowed;
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
+ --tw-text-opacity: 0.2;
+ }
+}
+
+.form-control {
+ display: flex;
+ flex-direction: column;
+}
+
+.label {
+ display: flex;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ align-items: center;
+ justify-content: space-between;
+ padding-left: 0.25rem;
+ padding-right: 0.25rem;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+
+.input {
+ flex-shrink: 1;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ height: 3rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ font-size: 1rem;
+ line-height: 2;
+ line-height: 1.5rem;
+ border-radius: var(--rounded-btn, 0.5rem);
+ border-width: 1px;
+ border-color: transparent;
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
+}
+
+.input[type="number"]::-webkit-inner-spin-button,
+.input-md[type="number"]::-webkit-inner-spin-button {
+ margin-top: -1rem;
+ margin-bottom: -1rem;
+ margin-inline-end: -1rem;
+}
+
+.link {
+ cursor: pointer;
+ text-decoration-line: underline;
+}
+
+.menu li.disabled {
+ cursor: not-allowed;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ color: var(--fallback-bc,oklch(var(--bc)/0.3));
+}
+
+.modal {
+ pointer-events: none;
+ position: fixed;
+ inset: 0px;
+ margin: 0px;
+ display: grid;
+ height: 100%;
+ max-height: none;
+ width: 100%;
+ max-width: none;
+ justify-items: center;
+ padding: 0px;
+ opacity: 0;
+ overscroll-behavior: contain;
+ z-index: 999;
+ background-color: transparent;
+ color: inherit;
+ transition-duration: 200ms;
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
+ transition-property: transform, opacity, visibility;
+ overflow-y: hidden;
+}
+
+:where(.modal) {
+ align-items: center;
+}
+
+.modal-open,
+.modal:target,
+.modal-toggle:checked + .modal,
+.modal[open] {
+ pointer-events: auto;
+ visibility: visible;
+ opacity: 1;
+}
+
+:root:has(:is(.modal-open, .modal:target, .modal-toggle:checked + .modal, .modal[open])) {
+ overflow: hidden;
+ scrollbar-gutter: stable;
+}
+
+.navbar {
+ display: flex;
+ align-items: center;
+ padding: var(--navbar-padding, 0.5rem);
+ min-height: 4rem;
+ width: 100%;
+}
+
+:where(.navbar > *:not(script, style)) {
+ display: inline-flex;
+ align-items: center;
+}
+
+.radio {
+ flex-shrink: 0;
+ --chkbg: var(--bc);
+ height: 1.5rem;
+ width: 1.5rem;
+ cursor: pointer;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border-radius: 9999px;
+ border-width: 1px;
+ border-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-border-opacity)));
+ --tw-border-opacity: 0.2;
+}
+
+.select {
+ display: inline-flex;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ height: 3rem;
+ min-height: 3rem;
+ padding-inline-start: 1rem;
+ padding-inline-end: 2.5rem;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ line-height: 2;
+ border-radius: var(--rounded-btn, 0.5rem);
+ border-width: 1px;
+ border-color: transparent;
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
+ background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
+ linear-gradient(135deg, currentColor 50%, transparent 50%);
+ background-position: calc(100% - 20px) calc(1px + 50%),
+ calc(100% - 16.1px) calc(1px + 50%);
+ background-size: 4px 4px,
+ 4px 4px;
+ background-repeat: no-repeat;
+}
+
+.select[multiple] {
+ height: auto;
+}
+
+.tabs {
+ display: grid;
+ align-items: flex-end;
+}
+
+.tabs-lifted:has(.tab-content[class^="rounded-"])
+ .tab:first-child:not(:is(.tab-active, [aria-selected="true"])), .tabs-lifted:has(.tab-content[class*=" rounded-"])
+ .tab:first-child:not(:is(.tab-active, [aria-selected="true"])) {
+ border-bottom-color: transparent;
+}
+
+.tab {
+ position: relative;
+ grid-row-start: 1;
+ display: inline-flex;
+ height: 2rem;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ line-height: 2;
+ --tab-padding: 1rem;
+ --tw-text-opacity: 0.5;
+ --tab-color: var(--fallback-bc,oklch(var(--bc)/1));
+ --tab-bg: var(--fallback-b1,oklch(var(--b1)/1));
+ --tab-border-color: var(--fallback-b3,oklch(var(--b3)/1));
+ color: var(--tab-color);
+ padding-inline-start: var(--tab-padding, 1rem);
+ padding-inline-end: var(--tab-padding, 1rem);
+}
+
+.tab:is(input[type="radio"]) {
+ width: auto;
+ border-bottom-right-radius: 0px;
+ border-bottom-left-radius: 0px;
+}
+
+.tab:is(input[type="radio"]):after {
+ --tw-content: attr(aria-label);
+ content: var(--tw-content);
+}
+
+.tab:not(input):empty {
+ cursor: default;
+ grid-column-start: span 9999;
+}
+
+.tab-content {
+ grid-column-start: 1;
+ grid-column-end: span 9999;
+ grid-row-start: 2;
+ margin-top: calc(var(--tab-border) * -1);
+ display: none;
+ border-color: transparent;
+ border-width: var(--tab-border, 0);
+}
+
+:checked + .tab-content:nth-child(2),
+ :is(.tab-active, [aria-selected="true"]) + .tab-content:nth-child(2) {
+ border-start-start-radius: 0px;
+}
+
+input.tab:checked + .tab-content,
+:is(.tab-active, [aria-selected="true"]) + .tab-content {
+ display: block;
+}
+
+.table {
+ position: relative;
+ width: 100%;
+ border-radius: var(--rounded-box, 1rem);
+ text-align: left;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.table :where(.table-pin-rows thead tr) {
+ position: sticky;
+ top: 0px;
+ z-index: 1;
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
+}
+
+.table :where(.table-pin-rows tfoot tr) {
+ position: sticky;
+ bottom: 0px;
+ z-index: 1;
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
+}
+
+.table :where(.table-pin-cols tr th) {
+ position: sticky;
+ left: 0px;
+ right: 0px;
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
+}
+
+.btm-nav > *:where(.active) {
+ border-top-width: 2px;
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
+}
+
+.btm-nav > *.disabled,
+ .btm-nav > *[disabled] {
+ pointer-events: none;
+ --tw-border-opacity: 0;
+ background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));
+ --tw-bg-opacity: 0.1;
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
+ --tw-text-opacity: 0.2;
+}
+
+.btm-nav > * .label {
+ font-size: 1rem;
+ line-height: 1.5rem;
+}
+
+.breadcrumbs > ul > li > a:focus, .breadcrumbs > ol > li > a:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.breadcrumbs > ul > li > a:focus-visible, .breadcrumbs > ol > li > a:focus-visible {
+ outline: 2px solid currentColor;
+ outline-offset: 2px;
+}
+
+.breadcrumbs > ul > li + *:before, .breadcrumbs > ol > li + *:before {
+ content: "";
+ margin-left: 0.5rem;
+ margin-right: 0.75rem;
+ display: block;
+ height: 0.375rem;
+ width: 0.375rem;
+ --tw-rotate: 45deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ opacity: 0.4;
+ border-top: 1px solid;
+ border-right: 1px solid;
+ background-color: transparent;
+}
+
+[dir="rtl"] .breadcrumbs > ul > li + *:before,
+[dir="rtl"] .breadcrumbs > ol > li + *:before {
+ --tw-rotate: -135deg;
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ .btn {
+ animation: button-pop var(--animation-btn, 0.25s) ease-out;
+ }
+}
+
+.btn:active:hover,
+ .btn:active:focus {
+ animation: button-pop 0s ease-out;
+ transform: scale(var(--btn-focus-scale, 0.97));
+}
+
+@supports not (color: oklch(0% 0 0)) {
+ .btn {
+ background-color: var(--btn-color, var(--fallback-b2));
+ border-color: var(--btn-color, var(--fallback-b2));
+ }
+
+ .btn-primary {
+ --btn-color: var(--fallback-p);
+ }
+}
+
+@supports (color: color-mix(in oklab, black, black)) {
+ .btn-outline.btn-primary.btn-active {
+ background-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
+ border-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
+ }
+}
+
+.btn:focus-visible {
+ outline-style: solid;
+ outline-width: 2px;
+ outline-offset: 2px;
+}
+
+.btn-primary {
+ --tw-text-opacity: 1;
+ color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
+ outline-color: var(--fallback-p,oklch(var(--p)/1));
+}
+
+@supports (color: oklch(0% 0 0)) {
+ .btn-primary {
+ --btn-color: var(--p);
+ }
+}
+
+.btn.glass {
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ outline-color: currentColor;
+}
+
+.btn.glass.btn-active {
+ --glass-opacity: 25%;
+ --glass-border-opacity: 15%;
+}
+
+.btn-outline.btn-primary {
+ --tw-text-opacity: 1;
+ color: var(--fallback-p,oklch(var(--p)/var(--tw-text-opacity)));
+}
+
+.btn-outline.btn-primary.btn-active {
+ --tw-text-opacity: 1;
+ color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
+}
+
+.btn.btn-disabled,
+ .btn[disabled],
+ .btn:disabled {
+ --tw-border-opacity: 0;
+ background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));
+ --tw-bg-opacity: 0.2;
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
+ --tw-text-opacity: 0.2;
+}
+
+.btn:is(input[type="checkbox"]:checked),
+.btn:is(input[type="radio"]:checked) {
+ --tw-border-opacity: 1;
+ border-color: var(--fallback-p,oklch(var(--p)/var(--tw-border-opacity)));
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-p,oklch(var(--p)/var(--tw-bg-opacity)));
+ --tw-text-opacity: 1;
+ color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
+}
+
+.btn:is(input[type="checkbox"]:checked):focus-visible, .btn:is(input[type="radio"]:checked):focus-visible {
+ outline-color: var(--fallback-p,oklch(var(--p)/1));
+}
+
+@keyframes button-pop {
+ 0% {
+ transform: scale(var(--btn-focus-scale, 0.98));
+ }
+
+ 40% {
+ transform: scale(1.02);
+ }
+
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.card :where(figure:first-child) {
+ overflow: hidden;
+ border-start-start-radius: inherit;
+ border-start-end-radius: inherit;
+ border-end-start-radius: unset;
+ border-end-end-radius: unset;
+}
+
+.card :where(figure:last-child) {
+ overflow: hidden;
+ border-start-start-radius: unset;
+ border-start-end-radius: unset;
+ border-end-start-radius: inherit;
+ border-end-end-radius: inherit;
+}
+
+.card:focus-visible {
+ outline: 2px solid currentColor;
+ outline-offset: 2px;
+}
+
+.card.bordered {
+ border-width: 1px;
+ --tw-border-opacity: 1;
+ border-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));
+}
+
+.card.compact .card-body {
+ padding: 1rem;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.card.image-full :where(figure) {
+ overflow: hidden;
+ border-radius: inherit;
+}
+
+.checkbox:focus {
+ box-shadow: none;
+}
+
+.checkbox:focus-visible {
+ outline-style: solid;
+ outline-width: 2px;
+ outline-offset: 2px;
+ outline-color: var(--fallback-bc,oklch(var(--bc)/1));
+}
+
+.checkbox:disabled {
+ border-width: 0px;
+ cursor: not-allowed;
+ border-color: transparent;
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity)));
+ opacity: 0.2;
+}
+
+.checkbox:checked,
+ .checkbox[aria-checked="true"] {
+ background-repeat: no-repeat;
+ animation: checkmark var(--animation-input, 0.2s) ease-out;
+ background-color: var(--chkbg);
+ background-image: linear-gradient(-45deg, transparent 65%, var(--chkbg) 65.99%),
+ linear-gradient(45deg, transparent 75%, var(--chkbg) 75.99%),
+ linear-gradient(-45deg, var(--chkbg) 40%, transparent 40.99%),
+ linear-gradient(
+ 45deg,
+ var(--chkbg) 30%,
+ var(--chkfg) 30.99%,
+ var(--chkfg) 40%,
+ transparent 40.99%
+ ),
+ linear-gradient(-45deg, var(--chkfg) 50%, var(--chkbg) 50.99%);
+}
+
+.checkbox:indeterminate {
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity)));
+ background-repeat: no-repeat;
+ animation: checkmark var(--animation-input, 0.2s) ease-out;
+ background-image: linear-gradient(90deg, transparent 80%, var(--chkbg) 80%),
+ linear-gradient(-90deg, transparent 80%, var(--chkbg) 80%),
+ linear-gradient(0deg, var(--chkbg) 43%, var(--chkfg) 43%, var(--chkfg) 57%, var(--chkbg) 57%);
+}
+
+@keyframes checkmark {
+ 0% {
+ background-position-y: 5px;
+ }
+
+ 50% {
+ background-position-y: -2px;
+ }
+
+ 100% {
+ background-position-y: 0;
+ }
+}
+
+details.collapse {
+ width: 100%;
+}
+
+details.collapse summary {
+ position: relative;
+ display: block;
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+details.collapse summary::-webkit-details-marker {
+ display: none;
+}
+
+.collapse:focus-visible {
+ outline-style: solid;
+ outline-width: 2px;
+ outline-offset: 2px;
+ outline-color: var(--fallback-bc,oklch(var(--bc)/1));
+}
+
+.collapse:has(.collapse-title:focus-visible),
+.collapse:has(> input[type="checkbox"]:focus-visible),
+.collapse:has(> input[type="radio"]:focus-visible) {
+ outline-style: solid;
+ outline-width: 2px;
+ outline-offset: 2px;
+ outline-color: var(--fallback-bc,oklch(var(--bc)/1));
+}
+
+.collapse:not(.collapse-open):not(.collapse-close) > input[type="checkbox"],
+.collapse:not(.collapse-open):not(.collapse-close) > input[type="radio"]:not(:checked),
+.collapse:not(.collapse-open):not(.collapse-close) > .collapse-title {
+ cursor: pointer;
+}
+
+.collapse:focus:not(.collapse-open):not(.collapse-close):not(.collapse[open]) > .collapse-title {
+ cursor: unset;
+}
+
+:where(.collapse > input[type="checkbox"]),
+:where(.collapse > input[type="radio"]) {
+ z-index: 1;
+}
+
+.collapse-title,
+:where(.collapse > input[type="checkbox"]),
+:where(.collapse > input[type="radio"]) {
+ width: 100%;
+ padding: 1rem;
+ padding-inline-end: 3rem;
+ min-height: 3.75rem;
+ transition: background-color 0.2s ease-out;
+}
+
+.collapse[open] > :where(.collapse-content),
+.collapse-open > :where(.collapse-content),
+.collapse:focus:not(.collapse-close) > :where(.collapse-content),
+.collapse:not(.collapse-close) > :where(input[type="checkbox"]:checked ~ .collapse-content),
+.collapse:not(.collapse-close) > :where(input[type="radio"]:checked ~ .collapse-content) {
+ padding-bottom: 1rem;
+ transition: padding 0.2s ease-out,
+ background-color 0.2s ease-out;
+}
+
+.collapse[open].collapse-arrow > .collapse-title:after,
+.collapse-open.collapse-arrow > .collapse-title:after,
+.collapse-arrow:focus:not(.collapse-close) > .collapse-title:after,
+.collapse-arrow:not(.collapse-close) > input[type="checkbox"]:checked ~ .collapse-title:after,
+.collapse-arrow:not(.collapse-close) > input[type="radio"]:checked ~ .collapse-title:after {
+ --tw-translate-y: -50%;
+ --tw-rotate: 225deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.collapse[open].collapse-plus > .collapse-title:after,
+.collapse-open.collapse-plus > .collapse-title:after,
+.collapse-plus:focus:not(.collapse-close) > .collapse-title:after,
+.collapse-plus:not(.collapse-close) > input[type="checkbox"]:checked ~ .collapse-title:after,
+.collapse-plus:not(.collapse-close) > input[type="radio"]:checked ~ .collapse-title:after {
+ content: "−";
+}
+
+.input input {
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-p,oklch(var(--p)/var(--tw-bg-opacity)));
+ background-color: transparent;
+}
+
+.input input:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.input[list]::-webkit-calendar-picker-indicator {
+ line-height: 1em;
+}
+
+.input:focus,
+ .input:focus-within {
+ box-shadow: none;
+ border-color: var(--fallback-bc,oklch(var(--bc)/0.2));
+ outline-style: solid;
+ outline-width: 2px;
+ outline-offset: 2px;
+ outline-color: var(--fallback-bc,oklch(var(--bc)/0.2));
+}
+
+.input:has(> input[disabled]),
+ .input-disabled,
+ .input:disabled,
+ .input[disabled] {
+ cursor: not-allowed;
+ --tw-border-opacity: 1;
+ border-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));
+ color: var(--fallback-bc,oklch(var(--bc)/0.4));
+}
+
+.input:has(> input[disabled])::-moz-placeholder, .input-disabled::-moz-placeholder, .input:disabled::-moz-placeholder, .input[disabled]::-moz-placeholder {
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity)));
+ --tw-placeholder-opacity: 0.2;
+}
+
+.input:has(> input[disabled])::placeholder,
+ .input-disabled::placeholder,
+ .input:disabled::placeholder,
+ .input[disabled]::placeholder {
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity)));
+ --tw-placeholder-opacity: 0.2;
+}
+
+.input:has(> input[disabled]) > input[disabled] {
+ cursor: not-allowed;
+}
+
+.input::-webkit-date-and-time-value {
+ text-align: inherit;
+}
+
+.join > :where(*:not(:first-child)):is(.btn) {
+ margin-inline-start: calc(var(--border-btn) * -1);
+}
+
+.link:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.link:focus-visible {
+ outline: 2px solid currentColor;
+ outline-offset: 2px;
+}
+
+.menu li > *:not(ul, .menu-title, details, .btn):active,
+.menu li > *:not(ul, .menu-title, details, .btn).active,
+.menu li > details > summary:active {
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity)));
+ --tw-text-opacity: 1;
+ color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity)));
+}
+
+.mockup-phone .display {
+ overflow: hidden;
+ border-radius: 40px;
+ margin-top: -25px;
+}
+
+.mockup-browser .mockup-browser-toolbar .input {
+ position: relative;
+ margin-left: auto;
+ margin-right: auto;
+ display: block;
+ height: 1.75rem;
+ width: 24rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));
+ padding-left: 2rem;
+ direction: ltr;
+}
+
+.mockup-browser .mockup-browser-toolbar .input:before {
+ content: "";
+ position: absolute;
+ left: 0.5rem;
+ top: 50%;
+ aspect-ratio: 1 / 1;
+ height: 0.75rem;
+ --tw-translate-y: -50%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ border-radius: 9999px;
+ border-width: 2px;
+ border-color: currentColor;
+ opacity: 0.6;
+}
+
+.mockup-browser .mockup-browser-toolbar .input:after {
+ content: "";
+ position: absolute;
+ left: 1.25rem;
+ top: 50%;
+ height: 0.5rem;
+ --tw-translate-y: 25%;
+ --tw-rotate: -45deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ border-radius: 9999px;
+ border-width: 1px;
+ border-color: currentColor;
+ opacity: 0.6;
+}
+
+.modal:not(dialog:not(.modal-open)),
+ .modal::backdrop {
+ background-color: #0006;
+ animation: modal-pop 0.2s ease-out;
+}
+
+.modal-open .modal-box,
+.modal-toggle:checked + .modal .modal-box,
+.modal:target .modal-box,
+.modal[open] .modal-box {
+ --tw-translate-y: 0px;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+@keyframes modal-pop {
+ 0% {
+ opacity: 0;
+ }
+}
+
+@keyframes progress-loading {
+ 50% {
+ background-position-x: -115%;
+ }
+}
+
+.radio:focus {
+ box-shadow: none;
+}
+
+.radio:focus-visible {
+ outline-style: solid;
+ outline-width: 2px;
+ outline-offset: 2px;
+ outline-color: var(--fallback-bc,oklch(var(--bc)/1));
+}
+
+.radio:checked,
+ .radio[aria-checked="true"] {
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity)));
+ background-image: none;
+ animation: radiomark var(--animation-input, 0.2s) ease-out;
+ box-shadow: 0 0 0 4px var(--fallback-b1,oklch(var(--b1)/1)) inset,
+ 0 0 0 4px var(--fallback-b1,oklch(var(--b1)/1)) inset;
+}
+
+.radio:disabled {
+ cursor: not-allowed;
+ opacity: 0.2;
+}
+
+@keyframes radiomark {
+ 0% {
+ box-shadow: 0 0 0 12px var(--fallback-b1,oklch(var(--b1)/1)) inset,
+ 0 0 0 12px var(--fallback-b1,oklch(var(--b1)/1)) inset;
+ }
+
+ 50% {
+ box-shadow: 0 0 0 3px var(--fallback-b1,oklch(var(--b1)/1)) inset,
+ 0 0 0 3px var(--fallback-b1,oklch(var(--b1)/1)) inset;
+ }
+
+ 100% {
+ box-shadow: 0 0 0 4px var(--fallback-b1,oklch(var(--b1)/1)) inset,
+ 0 0 0 4px var(--fallback-b1,oklch(var(--b1)/1)) inset;
+ }
+}
+
+@keyframes rating-pop {
+ 0% {
+ transform: translateY(-0.125em);
+ }
+
+ 40% {
+ transform: translateY(-0.125em);
+ }
+
+ 100% {
+ transform: translateY(0);
+ }
+}
+
+.select:focus {
+ box-shadow: none;
+ border-color: var(--fallback-bc,oklch(var(--bc)/0.2));
+ outline-style: solid;
+ outline-width: 2px;
+ outline-offset: 2px;
+ outline-color: var(--fallback-bc,oklch(var(--bc)/0.2));
+}
+
+.select-disabled,
+ .select:disabled,
+ .select[disabled] {
+ cursor: not-allowed;
+ --tw-border-opacity: 1;
+ border-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));
+ color: var(--fallback-bc,oklch(var(--bc)/0.4));
+}
+
+.select-disabled::-moz-placeholder, .select:disabled::-moz-placeholder, .select[disabled]::-moz-placeholder {
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity)));
+ --tw-placeholder-opacity: 0.2;
+}
+
+.select-disabled::placeholder,
+ .select:disabled::placeholder,
+ .select[disabled]::placeholder {
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity)));
+ --tw-placeholder-opacity: 0.2;
+}
+
+.select-multiple,
+ .select[multiple],
+ .select[size].select:not([size="1"]) {
+ background-image: none;
+ padding-right: 1rem;
+}
+
+[dir="rtl"] .select {
+ background-position: calc(0% + 12px) calc(1px + 50%),
+ calc(0% + 16px) calc(1px + 50%);
+}
+
+@keyframes skeleton {
+ from {
+ background-position: 150%;
+ }
+
+ to {
+ background-position: -50%;
+ }
+}
+
+.tabs-lifted > .tab:focus-visible {
+ border-end-end-radius: 0;
+ border-end-start-radius: 0;
+}
+
+.tab:is(.tab-active, [aria-selected="true"]):not(.tab-disabled):not([disabled]), .tab:is(input:checked) {
+ border-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-border-opacity)));
+ --tw-border-opacity: 1;
+ --tw-text-opacity: 1;
+}
+
+.tab:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.tab:focus-visible {
+ outline: 2px solid currentColor;
+ outline-offset: -5px;
+}
+
+.tab-disabled,
+ .tab[disabled] {
+ cursor: not-allowed;
+ color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity)));
+ --tw-text-opacity: 0.2;
+}
+
+.tabs-bordered > .tab {
+ border-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-border-opacity)));
+ --tw-border-opacity: 0.2;
+ border-style: solid;
+ border-bottom-width: calc(var(--tab-border, 1px) + 1px);
+}
+
+.tabs-lifted > .tab {
+ border: var(--tab-border, 1px) solid transparent;
+ border-width: 0 0 var(--tab-border, 1px) 0;
+ border-start-start-radius: var(--tab-radius, 0.5rem);
+ border-start-end-radius: var(--tab-radius, 0.5rem);
+ border-bottom-color: var(--tab-border-color);
+ padding-inline-start: var(--tab-padding, 1rem);
+ padding-inline-end: var(--tab-padding, 1rem);
+ padding-top: var(--tab-border, 1px);
+}
+
+.tabs-lifted > .tab:is(.tab-active, [aria-selected="true"]):not(.tab-disabled):not([disabled]), .tabs-lifted > .tab:is(input:checked) {
+ background-color: var(--tab-bg);
+ border-width: var(--tab-border, 1px) var(--tab-border, 1px) 0 var(--tab-border, 1px);
+ border-inline-start-color: var(--tab-border-color);
+ border-inline-end-color: var(--tab-border-color);
+ border-top-color: var(--tab-border-color);
+ padding-inline-start: calc(var(--tab-padding, 1rem) - var(--tab-border, 1px));
+ padding-inline-end: calc(var(--tab-padding, 1rem) - var(--tab-border, 1px));
+ padding-bottom: var(--tab-border, 1px);
+ padding-top: 0;
+}
+
+.tabs-lifted > .tab:is(.tab-active, [aria-selected="true"]):not(.tab-disabled):not([disabled]):before, .tabs-lifted > .tab:is(input:checked):before {
+ z-index: 1;
+ content: "";
+ display: block;
+ position: absolute;
+ width: calc(100% + var(--tab-radius, 0.5rem) * 2);
+ height: var(--tab-radius, 0.5rem);
+ bottom: 0;
+ background-size: var(--tab-radius, 0.5rem);
+ background-position: top left,
+ top right;
+ background-repeat: no-repeat;
+ --tab-grad: calc(69% - var(--tab-border, 1px));
+ --radius-start: radial-gradient(
+ circle at top left,
+ transparent var(--tab-grad),
+ var(--tab-border-color) calc(var(--tab-grad) + 0.25px),
+ var(--tab-border-color) calc(var(--tab-grad) + var(--tab-border, 1px)),
+ var(--tab-bg) calc(var(--tab-grad) + var(--tab-border, 1px) + 0.25px)
+ );
+ --radius-end: radial-gradient(
+ circle at top right,
+ transparent var(--tab-grad),
+ var(--tab-border-color) calc(var(--tab-grad) + 0.25px),
+ var(--tab-border-color) calc(var(--tab-grad) + var(--tab-border, 1px)),
+ var(--tab-bg) calc(var(--tab-grad) + var(--tab-border, 1px) + 0.25px)
+ );
+ background-image: var(--radius-start), var(--radius-end);
+}
+
+.tabs-lifted > .tab:is(.tab-active, [aria-selected="true"]):not(.tab-disabled):not([disabled]):first-child:before, .tabs-lifted > .tab:is(input:checked):first-child:before {
+ background-image: var(--radius-end);
+ background-position: top right;
+}
+
+[dir="rtl"] .tabs-lifted > .tab:is(.tab-active, [aria-selected="true"]):not(.tab-disabled):not([disabled]):first-child:before, [dir="rtl"] .tabs-lifted > .tab:is(input:checked):first-child:before {
+ background-image: var(--radius-start);
+ background-position: top left;
+}
+
+.tabs-lifted > .tab:is(.tab-active, [aria-selected="true"]):not(.tab-disabled):not([disabled]):last-child:before, .tabs-lifted > .tab:is(input:checked):last-child:before {
+ background-image: var(--radius-start);
+ background-position: top left;
+}
+
+[dir="rtl"] .tabs-lifted > .tab:is(.tab-active, [aria-selected="true"]):not(.tab-disabled):not([disabled]):last-child:before, [dir="rtl"] .tabs-lifted > .tab:is(input:checked):last-child:before {
+ background-image: var(--radius-end);
+ background-position: top right;
+}
+
+.tabs-lifted
+ > :is(.tab-active, [aria-selected="true"]):not(.tab-disabled):not([disabled])
+ + .tabs-lifted
+ :is(.tab-active, [aria-selected="true"]):not(.tab-disabled):not([disabled]):before, .tabs-lifted > .tab:is(input:checked) + .tabs-lifted .tab:is(input:checked):before {
+ background-image: var(--radius-end);
+ background-position: top right;
+}
+
+.tabs-boxed .tab {
+ border-radius: var(--rounded-btn, 0.5rem);
+}
+
+.table:where([dir="rtl"], [dir="rtl"] *) {
+ text-align: right;
+}
+
+.table :where(th, td) {
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem;
+ vertical-align: middle;
+}
+
+.table tr.active,
+ .table tr.active:nth-child(even),
+ .table-zebra tbody tr:nth-child(even) {
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));
+}
+
+.table-zebra tr.active,
+ .table-zebra tr.active:nth-child(even),
+ .table-zebra-zebra tbody tr:nth-child(even) {
+ --tw-bg-opacity: 1;
+ background-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)));
+}
+
+.table :where(thead tr, tbody tr:not(:last-child), tbody tr:first-child:last-child) {
+ border-bottom-width: 1px;
+ --tw-border-opacity: 1;
+ border-bottom-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));
+}
+
+.table :where(thead, tfoot) {
+ white-space: nowrap;
+ font-size: 0.75rem;
+ line-height: 1rem;
+ font-weight: 700;
+ color: var(--fallback-bc,oklch(var(--bc)/0.6));
+}
+
+.table :where(tfoot) {
+ border-top-width: 1px;
+ --tw-border-opacity: 1;
+ border-top-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity)));
+}
+
+@keyframes toast-pop {
+ 0% {
+ transform: scale(0.9);
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+
+.btm-nav-xs > *:where(.active) {
+ border-top-width: 1px;
+}
+
+.btm-nav-sm > *:where(.active) {
+ border-top-width: 2px;
+}
+
+.btm-nav-md > *:where(.active) {
+ border-top-width: 2px;
+}
+
+.btm-nav-lg > *:where(.active) {
+ border-top-width: 4px;
+}
+
+.tabs-md :where(.tab) {
+ height: 2rem;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ line-height: 2;
+ --tab-padding: 1rem;
+}
+
+.tabs-lg :where(.tab) {
+ height: 3rem;
+ font-size: 1.125rem;
+ line-height: 1.75rem;
+ line-height: 2;
+ --tab-padding: 1.25rem;
+}
+
+.tabs-sm :where(.tab) {
+ height: 1.5rem;
+ font-size: 0.875rem;
+ line-height: .75rem;
+ --tab-padding: 0.75rem;
+}
+
+.tabs-xs :where(.tab) {
+ height: 1.25rem;
+ font-size: 0.75rem;
+ line-height: .75rem;
+ --tab-padding: 0.5rem;
+}
+
+.card-compact .card-body {
+ padding: 1rem;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.card-normal .card-body {
+ padding: var(--padding-card, 2rem);
+ font-size: 1rem;
+ line-height: 1.5rem;
+}
+
+.join.join-vertical > :where(*:not(:first-child)):is(.btn) {
+ margin-top: calc(var(--border-btn) * -1);
+}
+
+.join.join-horizontal > :where(*:not(:first-child)):is(.btn) {
+ margin-inline-start: calc(var(--border-btn) * -1);
+}
+
+.table-sm :not(thead):not(tfoot) tr {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.table-sm :where(th, td) {
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border-width: 0;
+}
+
+.collapse {
+ visibility: collapse;
+}
+
+.static {
+ position: static;
+}
+
+.m-0 {
+ margin: 0px;
+}
+
+.mx-auto {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.my-8 {
+ margin-top: 2rem;
+ margin-bottom: 2rem;
+}
+
+.mb-0 {
+ margin-bottom: 0px;
+}
+
+.mb-1 {
+ margin-bottom: 0.25rem;
+}
+
+.mb-12 {
+ margin-bottom: 3rem;
+}
+
+.mb-2 {
+ margin-bottom: 0.5rem;
+}
+
+.mb-4 {
+ margin-bottom: 1rem;
+}
+
+.mb-6 {
+ margin-bottom: 1.5rem;
+}
+
+.mb-8 {
+ margin-bottom: 2rem;
+}
+
+.ml-2 {
+ margin-left: 0.5rem;
+}
+
+.ml-4 {
+ margin-left: 1rem;
+}
+
+.mt-1 {
+ margin-top: 0.25rem;
+}
+
+.mt-2 {
+ margin-top: 0.5rem;
+}
+
+.mt-4 {
+ margin-top: 1rem;
+}
+
+.mt-6 {
+ margin-top: 1.5rem;
+}
+
+.mt-8 {
+ margin-top: 2rem;
+}
+
+.block {
+ display: block;
+}
+
+.flex {
+ display: flex;
+}
+
+.table {
+ display: table;
+}
+
+.grid {
+ display: grid;
+}
+
+.hidden {
+ display: none;
+}
+
+.h-4 {
+ height: 1rem;
+}
+
+.h-auto {
+ height: auto;
+}
+
+.w-4 {
+ width: 1rem;
+}
+
+.w-full {
+ width: 100%;
+}
+
+.min-w-full {
+ min-width: 100%;
+}
+
+.max-w-2xl {
+ max-width: 42rem;
+}
+
+.list-inside {
+ list-style-position: inside;
+}
+
+.list-disc {
+ list-style-type: disc;
+}
+
+.grid-cols-1 {
+ grid-template-columns: repeat(1, minmax(0, 1fr));
+}
+
+.items-center {
+ align-items: center;
+}
+
+.justify-center {
+ justify-content: center;
+}
+
+.justify-between {
+ justify-content: space-between;
+}
+
+.gap-8 {
+ gap: 2rem;
+}
+
+.space-x-4 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(1rem * var(--tw-space-x-reverse));
+ margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
+}
+
+.space-y-4 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(1rem * var(--tw-space-y-reverse));
+}
+
+.space-y-6 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
+}
+
+.divide-y > :not([hidden]) ~ :not([hidden]) {
+ --tw-divide-y-reverse: 0;
+ border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
+ border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
+}
+
+.divide-gray-200 > :not([hidden]) ~ :not([hidden]) {
+ --tw-divide-opacity: 1;
+ border-color: rgb(229 231 235 / var(--tw-divide-opacity));
+}
+
+.overflow-hidden {
+ overflow: hidden;
+}
+
+.overflow-x-auto {
+ overflow-x: auto;
+}
+
+.whitespace-nowrap {
+ white-space: nowrap;
+}
+
+.rounded {
+ border-radius: 0.25rem;
+}
+
+.rounded-lg {
+ border-radius: 0.5rem;
+}
+
+.rounded-md {
+ border-radius: 0.375rem;
+}
+
+.border {
+ border-width: 1px;
+}
+
+.border-b {
+ border-bottom-width: 1px;
+}
+
+.border-l-4 {
+ border-left-width: 4px;
+}
+
+.border-t {
+ border-top-width: 1px;
+}
+
+.border-blue-500 {
+ --tw-border-opacity: 1;
+ border-color: rgb(59 130 246 / var(--tw-border-opacity));
+}
+
+.border-gray-200 {
+ --tw-border-opacity: 1;
+ border-color: rgb(229 231 235 / var(--tw-border-opacity));
+}
+
+.border-gray-300 {
+ --tw-border-opacity: 1;
+ border-color: rgb(209 213 219 / var(--tw-border-opacity));
+}
+
+.border-green-500 {
+ --tw-border-opacity: 1;
+ border-color: rgb(34 197 94 / var(--tw-border-opacity));
+}
+
+.border-transparent {
+ border-color: transparent;
+}
+
+.border-yellow-500 {
+ --tw-border-opacity: 1;
+ border-color: rgb(234 179 8 / var(--tw-border-opacity));
+}
+
+.bg-blue-100 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(219 234 254 / var(--tw-bg-opacity));
+}
+
+.bg-blue-50 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(239 246 255 / var(--tw-bg-opacity));
+}
+
+.bg-blue-500 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(59 130 246 / var(--tw-bg-opacity));
+}
+
+.bg-blue-600 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(37 99 235 / var(--tw-bg-opacity));
+}
+
+.bg-gray-100 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 244 246 / var(--tw-bg-opacity));
+}
+
+.bg-gray-200 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(229 231 235 / var(--tw-bg-opacity));
+}
+
+.bg-gray-50 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(249 250 251 / var(--tw-bg-opacity));
+}
+
+.bg-indigo-600 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(79 70 229 / var(--tw-bg-opacity));
+}
+
+.bg-white {
+ --tw-bg-opacity: 1;
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity));
+}
+
+.bg-yellow-100 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(254 249 195 / var(--tw-bg-opacity));
+}
+
+.p-2 {
+ padding: 0.5rem;
+}
+
+.p-4 {
+ padding: 1rem;
+}
+
+.p-6 {
+ padding: 1.5rem;
+}
+
+.px-2 {
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+}
+
+.px-3 {
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+}
+
+.px-4 {
+ padding-left: 1rem;
+ padding-right: 1rem;
+}
+
+.px-6 {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem;
+}
+
+.px-8 {
+ padding-left: 2rem;
+ padding-right: 2rem;
+}
+
+.py-1 {
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+}
+
+.py-2 {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+
+.py-3 {
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem;
+}
+
+.py-4 {
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+}
+
+.py-5 {
+ padding-top: 1.25rem;
+ padding-bottom: 1.25rem;
+}
+
+.py-8 {
+ padding-top: 2rem;
+ padding-bottom: 2rem;
+}
+
+.pb-8 {
+ padding-bottom: 2rem;
+}
+
+.pt-6 {
+ padding-top: 1.5rem;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.text-2xl {
+ font-size: 1.5rem;
+ line-height: 2rem;
+}
+
+.text-3xl {
+ font-size: 1.875rem;
+ line-height: 2.25rem;
+}
+
+.text-4xl {
+ font-size: 2.25rem;
+ line-height: 2.5rem;
+}
+
+.text-base {
+ font-size: 1rem;
+ line-height: 1.5rem;
+}
+
+.text-lg {
+ font-size: 1.125rem;
+ line-height: 1.75rem;
+}
+
+.text-sm {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.text-xl {
+ font-size: 1.25rem;
+ line-height: 1.75rem;
+}
+
+.text-xs {
+ font-size: 0.75rem;
+ line-height: 1rem;
+}
+
+.font-bold {
+ font-weight: 700;
+}
+
+.font-medium {
+ font-weight: 500;
+}
+
+.font-semibold {
+ font-weight: 600;
+}
+
+.uppercase {
+ text-transform: uppercase;
+}
+
+.tracking-wider {
+ letter-spacing: 0.05em;
+}
+
+.text-black {
+ --tw-text-opacity: 1;
+ color: rgb(0 0 0 / var(--tw-text-opacity));
+}
+
+.text-blue-600 {
+ --tw-text-opacity: 1;
+ color: rgb(37 99 235 / var(--tw-text-opacity));
+}
+
+.text-gray-500 {
+ --tw-text-opacity: 1;
+ color: rgb(107 114 128 / var(--tw-text-opacity));
+}
+
+.text-gray-600 {
+ --tw-text-opacity: 1;
+ color: rgb(75 85 99 / var(--tw-text-opacity));
+}
+
+.text-gray-700 {
+ --tw-text-opacity: 1;
+ color: rgb(55 65 81 / var(--tw-text-opacity));
+}
+
+.text-gray-900 {
+ --tw-text-opacity: 1;
+ color: rgb(17 24 39 / var(--tw-text-opacity));
+}
+
+.text-red-600 {
+ --tw-text-opacity: 1;
+ color: rgb(220 38 38 / var(--tw-text-opacity));
+}
+
+.text-white {
+ --tw-text-opacity: 1;
+ color: rgb(255 255 255 / var(--tw-text-opacity));
+}
+
+.shadow {
+ --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-md {
+ --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-sm {
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.hover\:bg-blue-600:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(37 99 235 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-blue-700:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(29 78 216 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-indigo-700:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(67 56 202 / var(--tw-bg-opacity));
+}
+
+.hover\:text-blue-200:hover {
+ --tw-text-opacity: 1;
+ color: rgb(191 219 254 / var(--tw-text-opacity));
+}
+
+.hover\:text-blue-900:hover {
+ --tw-text-opacity: 1;
+ color: rgb(30 58 138 / var(--tw-text-opacity));
+}
+
+.hover\:text-gray-800:hover {
+ --tw-text-opacity: 1;
+ color: rgb(31 41 55 / var(--tw-text-opacity));
+}
+
+.hover\:underline:hover {
+ text-decoration-line: underline;
+}
+
+.focus\:border-blue-500:focus {
+ --tw-border-opacity: 1;
+ border-color: rgb(59 130 246 / var(--tw-border-opacity));
+}
+
+.focus\:outline-none:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.focus\:ring-2:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
+}
+
+.focus\:ring-blue-500:focus {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity));
+}
+
+.focus\:ring-indigo-500:focus {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity));
+}
+
+.focus\:ring-offset-2:focus {
+ --tw-ring-offset-width: 2px;
+}
+
+@media (min-width: 640px) {
+ .sm\:rounded-lg {
+ border-radius: 0.5rem;
+ }
+
+ .sm\:p-6 {
+ padding: 1.5rem;
+ }
+
+ .sm\:px-6 {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem;
+ }
+
+ .sm\:text-sm {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ }
+}
+
+@media (min-width: 768px) {
+ .md\:grid-cols-2 {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+} \ No newline at end of file
diff --git a/core/templates/core/base.html b/core/templates/core/base.html
index 1c2bfe0..682395f 100644
--- a/core/templates/core/base.html
+++ b/core/templates/core/base.html
@@ -5,10 +5,11 @@
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
- <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
+{# <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">#}
+ <link rel="stylesheet" href="{% static 'css/output.css' %}">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700' rel='stylesheet' type='text/css'/>
- <link rel="stylesheet" href="{% static 'css/styles.css' %}"/>
+{# <link rel="stylesheet" href="{% static 'css/styles.css' %}"/>#}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://unpkg.com/htmx.org@1.9.0" integrity="sha384-aOxz9UdWG0yBiyrTwPeMibmaoq07/d3a96GCbb9x60f3mOt5zwkjdbcHFnKH8qls" crossorigin="anonymous"></script>
<title>{% block title %}{% endblock title %}</title>
@@ -26,31 +27,29 @@
</head>
<body>
{% block navbar %}
-<div class="w3-bar w3-border w3-blue w3-padding-16">
- <!-- <a href="/" class="w3-bar-item w3-button w3-dark-gray w3-xxlarge"><i class="fa fa-home"></i></a> -->
- <a href="#" class="w3-bar-item w3-button w3-large">Home</a>
- <a href="{% url 'engagements:home' %}" class="w3-bar-item w3-button w3-large">Engagement Plans</a>
- <a href="{% url 'engagements:regulatedentities' %}" class="w3-bar-item w3-button w3-large">Regulated Entities</a>
- <a href="#" class="w3-bar-item w3-button w3-large">Reporting</a>
- <a href="#" class="w3-bar-item w3-button w3-large">Dashboards</a>
- <div class="w3-dropdown-hover">
- <button class="w3-button w3-large">Teams</button>
- <div class="w3-dropdown-content w3-bar-block w3-card-4">
- <a href="#" class="w3-bar-item w3-button">Submarines and Propulsion</a>
- <a href="#" class="w3-bar-item w3-button">Transport</a>
+<nav class="bg-blue-600 p-4">
+ <div class="container mx-auto flex items-center justify-between">
+ <div class="flex items-center space-x-4">
+ <a href="#" class="text-white text-xl font-semibold">Home</a>
+ <a href="{% url 'engagements:home' %}" class="text-white hover:text-blue-200">Engagement Plans</a>
+ <a href="{% url 'engagements:regulatedentities' %}" class="text-white hover:text-blue-200">Regulated Entities</a>
+ <a href="#" class="text-white hover:text-blue-200">Reporting</a>
+ <a href="#" class="text-white hover:text-blue-200">Dashboards</a>
+ </div>
+ <div class="flex items-center space-x-4">
+ {% if request.user.is_authenticated %}
+ <span class="text-white">{{ user }}</span>
+ <a href="{% url 'logout' %}" class="text-white hover:text-blue-200">Log Out</a>
+ {% else %}
+ <a href="{% url 'login' %}" class="text-white hover:text-blue-200">Log In</a>
+ {% endif %}
+ <a href="#" class="text-white hover:text-blue-200">Help</a>
</div>
</div>
- {% if request.user.is_authenticated %}
- <a class="w3-bar-item w3-right w3-button w3-large" href="#">{{ user }}</a>
- <a class="w3-bar-item w3-right w3-button w3-large" href="{% url 'logout' %}">Log Out</a>
- {% else %}
- <a class="w3-bar-item w3-right w3-button w3-large" href="{% url 'login' %}">Log In</a>
- {% endif %}
- <a href="#" class="w3-right w3-bar-item w3-button w3-large">Help</a>
-</div>
+</nav>
{% endblock navbar %}
- <div class="w3-container">
+ <div class="container mx-auto">
{% block content %}
{% endblock content %}
</div>
diff --git a/core/templates/core/index.html b/core/templates/core/index.html
index 1914c50..ae25fbd 100644
--- a/core/templates/core/index.html
+++ b/core/templates/core/index.html
@@ -4,97 +4,103 @@
{% block title %}DefNucSyR Engagement Database (DED) - Information Management for DefNucSyR{% endblock title %}
{% block content %}
+ <div class="container mx-auto px-4 py-8">
+ <h1 class="text-4xl font-bold mb-8">DED - Information Management for DefNucSyR</h1>
-<div class="w3-container">
- <h2>DED - Information Management for DefNucSyR</h2>
- <div class="w3-panel w3-leftbar w3-sand w3-xlarge w3-serif w3-display-container">
- <span onclick="this.parentElement.style.display='none'"
- class="w3-button w3-display-topright">&times;</span>
- <h3>Quote of the day</h3>
- <p>This is a placeholder for some interesting test. Use of lose.</p>
- </div>
+ <div class="bg-yellow-100 border-l-4 border-yellow-500 p-4 mb-8">
+ <div class="flex justify-between items-center">
+ <h3 class="text-xl font-semibold">Quote of the day</h3>
+ <button class="text-gray-600 hover:text-gray-800"
+ onclick="this.parentElement.parentElement.style.display='none'">&times;
+ </button>
+ </div>
+ <p class="mt-2">This is a placeholder for some interesting test. Use or lose.</p>
+ </div>
- <p>{% lorem %}</p>
+ <p class="mb-8">{% lorem %}</p>
- <div class="w3-card-2 w3-margin-top">
- <header class="w3-container w3-light-blue">
- <h3>Submarines and Propulsion</h3>
+ <div class="mb-12">
+ <div class="bg-white shadow-md rounded-lg overflow-hidden">
+ <header class="bg-blue-100 p-4">
+ <h2 class="text-3xl font-bold">Submarines and Propulsion</h2>
</header>
- <div class="w3-container">
-
- <h3>Assessments & Inspections:</h3>
- <table class="w3-table w3-bordered w3-margin-bottom">
- <tr class="w3-light-blue">
- <th>Start Date</th>
- <th>End Date</th>
- <th>Event</th>
- <th>Site</th>
- <th>Inspectors</th>
- </tr>
- {% for s in subs_regulatory %}
- <tr>
- <td>{{ s.proposed_start_date|date:'j M y' }}</td>
- <td>{{ s.proposed_end_date|date:'j M y' }}</td>
- <td><a href="{% url 'engagements:engagement_detail' s.pk %}">{{ s }}</a></td>
- <td>{{ s.external_party }}</td>
- <td>
- {% if s.officers.all %}
- {{ s.officers.all|commalist }}
- {% endif %}
- </td>
- </tr>
- {% endfor %}
+ <div class="p-4">
+ <h3 class="text-2xl font-semibold mb-4">Assessments & Inspections:</h3>
+ <table class="w-full mb-4">
+ <thead>
+ <tr class="bg-gray-200">
+ <th class="p-2 text-left">Start Date</th>
+ <th class="p-2 text-left">End Date</th>
+ <th class="p-2 text-left">Event</th>
+ <th class="p-2 text-left">Site</th>
+ <th class="p-2 text-left">Inspectors</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for s in subs_regulatory %}
+ <tr class="{% cycle 'bg-white' 'bg-gray-100' %}">
+ <td class="p-2">{{ s.proposed_start_date|date:'j M y' }}</td>
+ <td class="p-2">{{ s.proposed_end_date|date:'j M y' }}</td>
+ <td class="p-2"><a href="{% url 'engagements:engagement_detail' s.pk %}" class="text-blue-600 hover:underline">{{ s }}</a></td>
+ <td class="p-2">{{ s.external_party }}</td>
+ <td class="p-2">
+ {% if s.officers.all %}
+ {{ s.officers.all|commalist }}
+ {% endif %}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
</table>
- <div class="w3-cell-row">
- <div class="w3-cell w3-left">
- <a href="{% url 'engagements:create' 'reg' %}" class="w3-button w3-round w3-blue">Add New</a>
- </div>
- <div class="w3-cell w3-right">
- <small>See <a href="#">Enagements</a> for full list</small>
- </div>
- </div>
- <hr>
- <h4>Non-regulatory events:</h4>
- <table class="w3-table w3-bordered w3-margin-bottom">
- <tr class="w3-light-blue">
- <th>Start Date</th>
- <th>End Date</th>
- <th>Summary</th>
- </tr>
- {% if not subs %}
- <tr>
- <td>None</td>
- <td>None</td>
- <td>None</td>
- </tr>
- {% else %}
- {% for s in subs %}
- <tr>
- <td>{{ s.proposed_start_date|date:'j M y' }}</td>
- <td>{{ s.proposed_end_date|date:'j M y' }}</td>
- <td><a href="#">{{ s }}</a></td>
- </tr>
- {% endfor %}
- {% endif %}
- </table>
- <div>
- <button class="w3-button w3-round w3-blue">Add New</button>
+
+ <div class="flex justify-between items-center mb-8">
+ <a href="{% url 'engagements:create' 'reg' %}" class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">Add New</a>
+ <small>See <a href="#" class="text-blue-600 hover:underline">Engagements</a> for full list</small>
</div>
- <p>{% lorem %}</p>
+ <div class="border-b border-gray-300 my-8"></div>
- </div>
- </div>
+ <h4 class="text-xl font-semibold mb-4">Non-regulatory events:</h4>
+ <table class="w-full mb-4">
+ <thead>
+ <tr class="bg-gray-200">
+ <th class="p-2 text-left">Start Date</th>
+ <th class="p-2 text-left">End Date</th>
+ <th class="p-2 text-left">Summary</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% if not subs %}
+ <tr>
+ <td class="p-2" colspan="3">No events found</td>
+ </tr>
+ {% else %}
+ {% for s in subs %}
+ <tr class="{% cycle 'bg-white' 'bg-gray-100' %}">
+ <td class="p-2">{{ s.proposed_start_date|date:'j M y' }}</td>
+ <td class="p-2">{{ s.proposed_end_date|date:'j M y' }}</td>
+ <td class="p-2"><a href="#" class="text-blue-600 hover:underline">{{ s }}</a></td>
+ </tr>
+ {% endfor %}
+ {% endif %}
+ </tbody>
+ </table>
- <div class="w3-card-2 w3-margin-top">
- <header class="w3-container w3-light-blue">
- <h3>Transport</h3>
- </header>
- <div class="w3-container">
- <p>{% lorem %}</p>
+ <div class="mt-4">
+ <button class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">Add New</button>
+ </div>
</div>
</div>
-
</div>
+
+ <div class="bg-white shadow-md rounded-lg overflow-hidden">
+ <header class="bg-blue-100 p-4">
+ <h3 class="text-2xl font-bold">Transport</h3>
+ </header>
+ <div class="p-4">
+ <p>{% lorem %}</p>
+ </div>
+ </div>
+ </div>
{% endblock content %}
diff --git a/engagements/forms.py b/engagements/forms.py
index ae01916..a1c3c44 100644
--- a/engagements/forms.py
+++ b/engagements/forms.py
@@ -1,74 +1,56 @@
-from crispy_forms.helper import FormHelper
-from crispy_forms.layout import Field, Fieldset, Layout, Submit
from django import forms
from django.forms.widgets import HiddenInput
from .models import Engagement, EngagementEffort
+
# TODO - need to handle errors correctly in this form and in the template
class EngagementEffortReportingCreateForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
- self.helper = FormHelper()
- self.helper.layout = Layout(
- Fieldset(
- "This is a form",
- Field("is_planned"),
- Field("proposed_start_date", css_class="w3-input w3-border w3-round", type="date"),
- Field("proposed_end_date", css_class="w3-input w3-border w3-round"),
- "officers",
- "notes",
- ),
- Submit("submit", "Submit", css_class="w3-button w3-green"),
- )
+ self.fields['is_planned'].widget.attrs.update({"class": "select-lg"})
+ # for field in self.fields.values():
+ # field.widget.attrs['class'] = 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'
class Meta:
model = EngagementEffort
fields = [
- "is_planned",
- "proposed_start_date",
- "proposed_end_date",
- "officers",
- "notes",
+ 'is_planned',
+ 'proposed_start_date',
+ 'proposed_end_date',
+ 'officers',
+ 'notes',
]
- help_texts = {
- "is_planned": ("<br><small><em>To distinguish planned events from retrospective recording</em></small>")
- }
widgets = {
- "proposed_start_date": forms.DateTimeInput(
+ # 'is_planned': forms.Select(
+ # choices=(
+ # (True, "YES"),
+ # (False, "NO"),
+ # ),
+ # attrs={'class': 'select-lg w-full max-w-xs'}
+ # ),
+ 'proposed_start_date': forms.DateTimeInput(
attrs={
- "class": "w3-input w3-border w3-round",
- "type": "datetime-local",
+ 'type': 'datetime-local',
+ 'class': 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'
},
- format="j M y H:i",
+ format='j M y H:i',
),
- "proposed_end_date": forms.DateTimeInput(
+ 'proposed_end_date': forms.DateTimeInput(
attrs={
- "class": "w3-input w3-border w3-round",
- "type": "datetime-local",
+ 'type': 'datetime-local',
+ 'class': 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'
},
- format="j M y H:i",
+ format='j M y H:i',
),
+ 'officers': forms.SelectMultiple(attrs={'class': 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'}),
+ 'notes': forms.Textarea(attrs={'class': 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50', 'rows': 3}),
}
class EngagementEffortRegulationCreateForm(forms.ModelForm):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.helper = FormHelper()
- self.helper.layout = Layout(
- Fieldset(
- "This is a form",
- Field("is_planned"),
- Field("proposed_start_date", css_class="w3-input w3-border w3-round", type="date"),
- Field("proposed_end_date", css_class="w3-input w3-border w3-round"),
- "sub_instruments",
- "officers",
- ),
- Submit("submit", "Submit", css_class="w3-button w3-green"),
- )
class Meta:
model = EngagementEffort
@@ -86,14 +68,12 @@ class EngagementEffortRegulationCreateForm(forms.ModelForm):
widgets = {
"proposed_start_date": forms.DateTimeInput(
attrs={
- "class": "w3-input w3-border w3-round",
"type": "datetime-local",
},
format="j M y H:i",
),
"proposed_end_date": forms.DateTimeInput(
attrs={
- "class": "w3-input w3-border w3-round",
"type": "datetime-local",
},
format="j M y H:i",
@@ -102,20 +82,6 @@ class EngagementEffortRegulationCreateForm(forms.ModelForm):
class EngagementEffortPlanningCreateForm(forms.ModelForm):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.helper = FormHelper()
- self.helper.layout = Layout(
- Fieldset(
- "This is a form",
- Field("is_planned"),
- Field("proposed_start_date", css_class="w3-input w3-border w3-round", type="date"),
- Field("proposed_end_date", css_class="w3-input w3-border w3-round"),
- "officers",
- "notes",
- ),
- Submit("submit", "Submit", css_class="w3-button w3-green"),
- )
class Meta:
model = EngagementEffort
@@ -132,14 +98,12 @@ class EngagementEffortPlanningCreateForm(forms.ModelForm):
widgets = {
"proposed_start_date": forms.DateTimeInput(
attrs={
- "class": "w3-input w3-border w3-round",
"type": "datetime-local",
},
format="j M y H:i",
),
"proposed_end_date": forms.DateTimeInput(
attrs={
- "class": "w3-input w3-border w3-round",
"type": "datetime-local",
},
format="j M y H:i",
@@ -150,22 +114,15 @@ class EngagementEffortPlanningCreateForm(forms.ModelForm):
class EngagementEffortTravelCreateForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
- self.helper = FormHelper()
- self.helper.layout = Layout(
- Fieldset(
- "This is a form",
- Field("is_planned"),
- Field("proposed_start_date", css_class="w3-input w3-border w3-round", type="date"),
- Field("proposed_end_date", css_class="w3-input w3-border w3-round"),
- "officers",
- ),
- Submit("submit", "Submit", css_class="w3-button w3-green"),
- )
+ self.fields['is_planned'].widget.attrs.update({"class": "select-lg"})
+ for field in self.fields.values():
+ field.widget.attrs['class'] = 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'
class Meta:
model = EngagementEffort
fields = ["is_planned", "proposed_start_date", "proposed_end_date", "officers"]
widgets = {
+ "is_planned": forms.Select(choices=((True, "YES"), (False, "NO")), attrs={"class": "select select-bordered w-full max-w-xs"}),
"proposed_start_date": forms.DateTimeInput(attrs={"type": "datetime-local"}),
"proposed_end_date": forms.DateTimeInput(attrs={"type": "datetime-local"}),
}
@@ -174,40 +131,44 @@ class EngagementEffortTravelCreateForm(forms.ModelForm):
class EngagementEffortCreateForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
- self.fields["engagement"].widget = HiddenInput()
- self.fields["effort_type"].widget = HiddenInput()
+ self.fields['engagement'].widget = HiddenInput()
+ self.fields['effort_type'].widget = HiddenInput()
if kwargs.get("initial"):
if not kwargs["initial"]["effort_type"] == "REGULATION":
self.fields["sub_instruments"].widget = HiddenInput()
+ # Apply Tailwind classes to all visible fields
+ # for field in self.visible_fields():
+ # field.widget.attrs['class'] = 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'
+
class Meta:
model = EngagementEffort
fields = "__all__"
widgets = {
- "is_planned": forms.Select(
- choices=(
- (True, "YES"),
- (False, "NO"),
- ),
- attrs={"class": "w3-border"},
- ),
+ # "is_planned": forms.Select(
+ # choices=(
+ # (True, "YES"),
+ # (False, "NO"),
+ # ),
+ # attrs={'class': 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'}
+ # ),
"proposed_start_date": forms.DateTimeInput(
- attrs={"class": "w3-input w3-border w3-round", "type": "date"},
+ attrs={
+ "type": "datetime-local",
+ "class": "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
+ },
format="j M y H:i",
),
"proposed_end_date": forms.DateTimeInput(
- attrs={"class": "w3-input w3-border w3-round", "type": "date"},
+ attrs={
+ "type": "datetime-local",
+ "class": "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
+ },
format="j M y H:i",
),
- "effort_type": forms.Select(attrs={"class": "w3-select w3-border w3-round"}),
- "officers": forms.SelectMultiple(attrs={"class": "w3-select w3-border w3-round"}),
- "sub_instruments": forms.SelectMultiple(attrs={"class": "w3-select w3-border w3-round"}),
- }
- help_texts = {
- "proposed_start_date": "<small><em>YYYY-MM-DD HH:MM</em> "
- "(<strong>Please include time here</strong>)</small>",
- "proposed_end_date": "<small><em>YYYY-MM-DD HH:MM</em> "
- "(<strong>Please include time here</strong>)</small>",
+ "effort_type": forms.Select(attrs={'class': 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'}),
+ "officers": forms.SelectMultiple(attrs={'class': 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'}),
+ "sub_instruments": forms.SelectMultiple(attrs={'class': 'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50'}),
}
@@ -235,8 +196,8 @@ class EngagementCreateForm(forms.ModelForm):
"proposed_end_date": "<small><em>YYYY-MM-DD</em></small>",
}
widgets = {
- "proposed_start_date": forms.DateInput(attrs={"class": "w3-input w3-border w3-round", "type": "date"}),
- "proposed_end_date": forms.DateInput(attrs={"class": "w3-input w3-border w3-round", "type": "date"}),
- "engagement_type": forms.Select(attrs={"class": "w3-select w3-input w3-border w3-round"}),
- "officers": forms.SelectMultiple(attrs={"class": "w3-input w3-border w3-round"}),
+ "proposed_start_date": forms.DateInput(attrs={"type": "date"}),
+ "proposed_end_date": forms.DateInput(attrs={"type": "date"}),
+ "engagement_type": forms.Select(),
+ "officers": forms.SelectMultiple(),
}
diff --git a/engagements/templates/engagements/engagement_create.html b/engagements/templates/engagements/engagement_create.html
index 1e72ca0..e4aeee6 100644
--- a/engagements/templates/engagements/engagement_create.html
+++ b/engagements/templates/engagements/engagement_create.html
@@ -3,27 +3,49 @@
{% block title %}Create new engagement{% endblock title %}
{% block content %}
+<div class="container mx-auto px-4 py-8">
+ <div class="bg-white shadow-md rounded-lg overflow-hidden">
+ <header class="bg-blue-100 p-4">
+ <h2 class="text-3xl font-bold text-center">{{ title }}</h2>
+ </header>
+ <div class="p-6">
+ <div class="mb-8">
+ <div class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-lg">
+ <h4 class="text-lg font-semibold mb-2">Step 1</h4>
+ <p class="mb-4">To roughly plan out future events, you provide the minimal details here: <strong>start date</strong>, <strong>end date</strong> (optional), the <strong>type of Engagement</strong> (Assessment, Inspection or Sampling), the <strong>external site</strong> or operation and finally the <strong>inspectors</strong> who are carrying out the work.</p>
+ <h4 class="text-lg font-semibold mb-2">Step 2</h4>
+ <p>So that we can track the finer details involved with an Assessment or Inspection, each Engagement comprises additional <em>components</em>, such as <strong>Planning</strong>, <strong>On-site</strong> and <strong>Reporting</strong>. Inspector time can be allocated to these components. In addition, each component can be associated with <strong>Instruments</strong>, such as <strong>DSCs</strong>, etc. After you create the overarching Engagement using this form, you will have the opportunity to add components.</p>
+ </div>
+ </div>
-<div class="w3-container w3-cell-row w3-margin-bottom">
- <h2>{{ title }}</h2>
- <div class="w3-panel w3-light-blue w3-round w3-leftbar w3-border-blue w3-display-container">
-
- <span onclick="this.parentElement.style.display='none'"
- class="w3-button w3-display-topright">&times;</span>
- <h4>Step 1</h4>
- <p>To roughly plan out future events, you provide the minimal details here: <strong>start date</strong>, <strong>end date</strong> (optional),the <strong>type of Engagement</strong> (Assessment, Inspection or Sampling), the <strong>external site</strong> or operation and finally the <strong>inspectors</strong> who are carrying out the work.</p>
- <h4>Step 2</h4>
- <p>So that we can track the finer details involved with an Assessment or Inspection, each Engagement comprises additional <em>components</em>, such as <strong>Planning</strong>, <strong>On-site</strong> and <strong>Reporting</strong>. Inspector time can be allocated to these components. In addition, each compontent can be associated with <strong>Instruments</strong>, such as <strong>DSCs</strong>, etc. After you create the overarching Engagement using this form, you will have the opportunity to add components.</p>
- </div>
-
- <hr>
- <div class="w3-container w3-cell-middle">
- <h4>Enter main details:</h4>
- <form method="post">{% csrf_token %}
- {{ form.as_p }}
- <input type="submit" class="w3-btn w3-green" value="Save">
- </form>
+ <div class="mt-8">
+ <h4 class="text-xl font-semibold mb-4">Enter main details:</h4>
+ <form method="post" class="space-y-6">
+ {% csrf_token %}
+ {% for field in form %}
+ <div>
+ <label for="{{ field.id_for_label }}" class="block text-sm font-medium text-gray-700">
+ {{ field.label }}
+ </label>
+ <div class="mt-1">
+ {{ field }}
+ </div>
+ {% if field.help_text %}
+ <p class="mt-2 text-sm text-gray-500">{{ field.help_text|safe }}</p>
+ {% endif %}
+ {% for error in field.errors %}
+ <p class="mt-2 text-sm text-red-600">{{ error }}</p>
+ {% endfor %}
+ </div>
+ {% endfor %}
+ <div>
+ <button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
+ Save
+ </button>
+ </div>
+ </form>
+ </div>
+ </div>
</div>
</div>
-
{% endblock content %}
diff --git a/engagements/templates/engagements/engagement_detail.html b/engagements/templates/engagements/engagement_detail.html
index 85ef220..c75523b 100644
--- a/engagements/templates/engagements/engagement_detail.html
+++ b/engagements/templates/engagements/engagement_detail.html
@@ -4,75 +4,110 @@
{% block title %}{{ engagement }}{% endblock title %}
{% block content %}
+ <div class="container mx-auto px-4 py-8">
+ <div class="bg-white shadow-md rounded-lg overflow-hidden">
+ <header class="bg-blue-100 p-4">
+ <h2 class="text-3xl font-bold text-center">{{ engagement.friendly_type }}
+ at {{ engagement.external_party }}</h2>
+ </header>
+ <div class="p-4">
+ <div class="mb-4">
+ <a href="{% url 'engagements:edit' engagement.pk %}" class="text-blue-600 hover:underline">Edit
+ Engagement</a>
+ </div>
-<div class="w3-container">
- <div class="w3-container w3-center">
- <h2>{{ engagement.friendly_type }} at {{ engagement.external_party }}</h2>
- </div>
- <div class="w3-row">
- <div class="w3-container">
- <div>
- <a href="{% url 'engagements:edit' engagement.pk %}">Edit Engagement</a>
- </div>
- <section class="w3-container w3-blue">
- <h3>Details</h3>
- </section>
- <table class="w3-table w3-border w3-light-gray w3-bordered">
- <tr>
- <td><strong>Date</strong></td>
- <td>{{ engagement.proposed_start_date|date:'l' }} - {{ engagement.proposed_start_date|date:'j M Y' }}</td>
- </tr>
- <tr>
- <td><strong>Site/Operation:</strong></td>
- <td>{{ engagement.external_party }} </td>
- </tr>
- <tr>
- <td><strong>Subject of Activity</strong></td>
- <td>
- <p>Summmary text</p>
- <ul class="w3-ul">
- {% for t in dscs %}
- <li><a href='#'>{{ t }}</a></li>
- {% endfor %}
- </ul>
- </td>
- </tr>
- <tr>
- <td><strong>Inspectors:</strong></td>
- <td>{{ engagement.officers.all|commalist }}</td>
- </tr>
- <tr>
- <td><strong>Planned Effort:</strong></td>
- <td>{{ effort_planned|floatformat }} hrs</td>
- </tr>
- <tr>
- <td><strong>Actual Effort:</strong></td>
- <td>{{ effort_actual|floatformat }} hrs</td>
- </tr>
- <tr>
- <td><strong>Total Effort:</strong></td>
- <td>{{ effort_total|floatformat }} hrs</td>
- </tr>
- </table>
- <hr>
- </div>
+ <h3 class="text-2xl font-semibold mb-4">Details</h3>
+ <div class="bg-white shadow-sm rounded-lg overflow-hidden">
+ <table class="min-w-full divide-y divide-gray-200 text-sm">
+ <tbody>
+ <tr class="bg-gray-50">
+ <td class="px-4 py-2 font-semibold text-gray-700">Date</td>
+ <td class="px-4 py-2 text-gray-900">
+ {{ engagement.proposed_start_date|date:'l' }} -
+ {{ engagement.proposed_start_date|date:'j M Y' }}
+ </td>
+ </tr>
+ <tr>
+ <td class="px-4 py-2 font-semibold text-gray-700">Site/Operation</td>
+ <td class="px-4 py-2 text-gray-900">{{ engagement.external_party }}</td>
+ </tr>
+ <tr class="bg-gray-50">
+ <td class="px-4 py-2 font-semibold text-gray-700">Subject of Activity</td>
+ <td class="px-4 py-2 text-gray-900">
+ <p class="mb-2">Summary text</p>
+ <table class="min-w-full divide-y divide-gray-200">
+ <thead class="bg-gray-50">
+ <tr>
+ <th scope="col"
+ class="px-3 py-2 text-left text-sm font-medium text-gray-700 uppercase tracking-wider">
+ DSC
+ </th>
+ </tr>
+ </thead>
+ <tbody class="bg-white divide-y divide-gray-200">
+ {% for t in dscs %}
+ <tr>
+ <td class="px-3 py-2 whitespace-nowrap text-base">
+ <a href='#' class="text-blue-600 hover:underline">{{ t }}</a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td class="px-4 py-2 font-semibold text-gray-700">Inspectors</td>
+ <td class="px-4 py-2 text-gray-900">{{ engagement.officers.all|commalist }}</td>
+ </tr>
+ <tr class="bg-gray-50">
+ <td class="px-4 py-2 font-semibold text-gray-700">Planned Effort</td>
+ <td class="px-4 py-2 text-gray-900">{{ effort_planned|floatformat }} hrs</td>
+ </tr>
+ <tr>
+ <td class="px-4 py-2 font-semibold text-gray-700">Actual Effort</td>
+ <td class="px-4 py-2 text-gray-900">{{ effort_actual|floatformat }} hrs</td>
+ </tr>
+ <tr class="bg-gray-50">
+ <td class="px-4 py-2 font-semibold text-gray-700">Total Effort</td>
+ <td class="px-4 py-2 text-gray-900">{{ effort_total|floatformat }} hrs</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
- <div class="w3-container w3-light-gray">
- <h3>Effort for this engagement</h3>
- Add:
- <a href="{% url 'engagements:effort_create' engagement.pk "TRAVEL" %}">Travel</a> |
- <a href="{% url 'engagements:effort_create' engagement.pk "PLANNING" %}">Planning</a> |
- <a href="{% url 'engagements:effort_create' engagement.pk "REGULATION" %}">Regulation</a> |
- <a href="{% url 'engagements:effort_create' engagement.pk "REPORTING" %}">Reporting</a>
+ <div class="bg-white shadow overflow-hidden sm:rounded-lg mt-8">
+ <div class="px-4 py-5 sm:px-6 bg-blue-100">
+ <h3 class="text-2xl font-semibold text-black">Effort for this engagement</h3>
+ </div>
+ <div class="border-t border-gray-200">
+ <div class="px-4 py-5 sm:p-6">
+ <div class="mb-4">
+ <span class="font-medium">Add:</span>
+ <a href="{% url 'engagements:effort_create' engagement.pk 'TRAVEL' %}"
+ class="text-blue-600 hover:underline ml-2">Travel</a>
+ <a href="{% url 'engagements:effort_create' engagement.pk 'PLANNING' %}" class="text-blue-600 hover:underline ml-2">Planning</a>
+ <a href="{% url 'engagements:effort_create' engagement.pk "REGULATION" %}"
+ class="text-blue-600 hover:underline ml-2">Regulation</a>
+ <a href="{% url 'engagements:effort_create' engagement.pk "REPORTING" %}"
+ class="text-blue-600 hover:underline ml-2">Reporting</a>
+ </div>
- {% if effort %}
- {% for e in effort.all %}
- <div id="planned_swap_{{ e.id }}">
- {% include "engagements/snippets/effort_summary_panel.html" with e=e %}
+ {% if effort %}
+ <div class="space-y-4">
+ {% for e in effort.all %}
+ <div id="planned_swap_{{ e.id }}" class="bg-gray-50 p-4 rounded-lg">
+ {% include "engagements/snippets/effort_summary_panel.html" with e=e %}
+ </div>
+ {% endfor %}
+ </div>
+ {% else %}
+ <p class="text-gray-500">No effort records found for this engagement.</p>
+ {% endif %}
+ </div>
+ </div>
+ </div>
</div>
- {% endfor %}
- {% endif %}
</div>
</div>
-
- {% endblock content %}
+{% endblock content %}
diff --git a/engagements/templates/engagements/engagement_effort_create.html b/engagements/templates/engagements/engagement_effort_create.html
index 65e2e21..b776fd8 100644
--- a/engagements/templates/engagements/engagement_effort_create.html
+++ b/engagements/templates/engagements/engagement_effort_create.html
@@ -1,20 +1,34 @@
{% extends "core/base.html" %}
-{% load crispy_forms_tags %}
-
{% block title %}Add {{ etype }} effort to Engagement{% endblock title %}
{% block content %}
- <div class="w3-container w3-cell-row w3-margin-bottom">
- <h2>Register your {{ etype|lower }} effort for the {{ engagement.engagement_type.name|title }} event at {{ engagement.external_party }} on {{ engagement.proposed_start_date }}</h2>
+ <div class="container mx-auto max-w-2xl mt-8">
+ <div class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
+ <h2 class="text-2xl font-bold mb-6">Register your {{ etype|lower }} effort for the {{ engagement.engagement_type.name|title }} event</h2>
+ <p class="mb-6">{{ engagement.external_party }} on {{ engagement.proposed_start_date }}</p>
- <div class="w3-container w3-cell-middle">
- <h4>Enter details:</h4>
- <form method="post">{% csrf_token %}
- {% crispy form form.helper %}
- </form>
- </div>
+ <form method="post" class="space-y-6">
+ {% csrf_token %}
+ {% for field in form %}
+ <div class="mb-4">
+ <label for="{{ field.id_for_label }}" class="block text-sm font-medium text-gray-700 mb-2">
+ {{ field.label }}
+ </label>
+ {{ field }}
+ {% if field.help_text %}
+ <p class="mt-2 text-sm text-gray-500">{{ field.help_text }}</p>
+ {% endif %}
+ </div>
+ {% endfor %}
+ <div class="mt-6">
+ <button type="submit" class="w-full py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
+ Submit
+ </button>
+ </div>
+ </form>
</div>
+</div>
{% endblock content %}
diff --git a/engagements/templates/engagements/engagement_form.html b/engagements/templates/engagements/engagement_form.html
index e05c639..3dfe249 100644
--- a/engagements/templates/engagements/engagement_form.html
+++ b/engagements/templates/engagements/engagement_form.html
@@ -3,30 +3,66 @@
{% load static %}
{% block title %}Create new engagement{% endblock title %}
-{% block extra_head_tags %}
-<link rel="stylesheet" href="{% static 'css/styles.css' %}"/>
-{% endblock extra_head_tags %}
{% block content %}
+<div class="container mx-auto px-4 py-8">
+ <div class="bg-white shadow-md rounded-lg overflow-hidden">
+ <header class="bg-blue-100 p-4">
+ <h2 class="text-3xl font-bold text-center">{{ title }}</h2>
+ </header>
+ <div class="p-6">
+ <div class="mb-8">
+ <div class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-lg">
+ <h4 class="text-lg font-semibold mb-2">Step 1</h4>
+ <p class="mb-4">To roughly plan out future events, you provide the minimal details here: <strong>start date</strong>, <strong>end date</strong> (optional), the <strong>type of Engagement</strong> (Assessment, Inspection or Sampling), the <strong>external site</strong> or operation and finally the <strong>inspectors</strong> who are carrying out the work.</p>
+ <h4 class="text-lg font-semibold mb-2">Step 2</h4>
+ <p>So that we can track the finer details involved with an Assessment or Inspection, each Engagement comprises additional <em>components</em>, such as <strong>Planning</strong>, <strong>On-site</strong> and <strong>Reporting</strong>. Inspector time can be allocated to these components. In addition, each component can be associated with <strong>Instruments</strong>, such as <strong>DSCs</strong>, etc. After you create the overarching Engagement using this form, you will have the opportunity to add components.</p>
+ </div>
+ </div>
-<div class="format-container">
- <div class="form-thing">
- <h2>{{ title }}</h2>
- <p>TAKE THIS OUT</p>
- <span onclick="this.parentElement.style.display='none'"
- class="w3-button w3-display-topright">&times;</span>
- <h4>Step 1</h4>
- <p>To roughly plan out future events, you provide the minimal details here: <strong>start date</strong>, <strong>end date</strong> (optional),the <strong>type of Engagement</strong> (Assessment, Inspection or Sampling), the <strong>external site</strong> or operation and finally the <strong>inspectors</strong> who are carrying out the work.</p>
- <h4>Step 2</h4>
- <p>So that we can track the finer details involved with an Assessment or Inspection, each Engagement comprises additional <em>components</em>, such as <strong>Planning</strong>, <strong>On-site</strong> and <strong>Reporting</strong>. Inspector time can be allocated to these components. In addition, each compontent can be associated with <strong>Instruments</strong>, such as <strong>DSCs</strong>, etc. After you create the overarching Engagement using this form, you will have the opportunity to add components.</p>
- </div>
- <div class="form-thing">
- <h4>Enter main details:</h4>
- <form method="post">{% csrf_token %}
- {{ form.as_p }}
- <input type="submit" class="w3-btn w3-green" value="Save">
- </form>
+ <div class="mt-8">
+ <h4 class="text-xl font-semibold mb-4">Enter main details:</h4>
+ <div class="bg-white shadow overflow-hidden sm:rounded-lg">
+ <div class="px-4 py-5 sm:p-6">
+ <form method="post" class="space-y-6">
+ {% csrf_token %}
+ {% for field in form %}
+ <div class="mb-4">
+ <label for="{{ field.id_for_label }}" class="block text-sm font-medium text-gray-700 mb-1">
+ {{ field.label }}
+ </label>
+ {% if field.field.widget.input_type == 'checkbox' %}
+ <div class="flex items-center">
+ <input type="checkbox" name="{{ field.name }}" id="{{ field.id_for_label }}" {% if field.value %}checked{% endif %} class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
+ <span class="ml-2 text-gray-700">{{ field.help_text|safe }}</span>
+ </div>
+ {% elif field.field.widget.input_type == 'select' %}
+ <select name="{{ field.name }}" id="{{ field.id_for_label }}" class="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
+ {% for choice in field.field.choices %}
+ <option value="{{ choice.0 }}" {% if choice.0 == field.value %}selected{% endif %}>{{ choice.1 }}</option>
+ {% endfor %}
+ </select>
+ {% else %}
+ <input type="{{ field.field.widget.input_type }}" name="{{ field.name }}" id="{{ field.id_for_label }}" value="{{ field.value|default:'' }}" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
+ {% endif %}
+ {% if field.help_text and field.field.widget.input_type != 'checkbox' %}
+ <p class="mt-2 text-sm text-gray-500">{{ field.help_text|safe }}</p>
+ {% endif %}
+ {% for error in field.errors %}
+ <p class="mt-2 text-sm text-red-600">{{ error }}</p>
+ {% endfor %}
+ </div>
+ {% endfor %}
+ <div>
+ <button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
+ Save
+ </button>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
</div>
</div>
-
{% endblock content %}
diff --git a/engagements/templates/engagements/ep_org.html b/engagements/templates/engagements/ep_org.html
index 202100a..9fbb9dd 100644
--- a/engagements/templates/engagements/ep_org.html
+++ b/engagements/templates/engagements/ep_org.html
@@ -1,427 +1,111 @@
{% extends "core/base.html" %}
-
{% block title %}Create new engagement{% endblock title %}
-
{% load table_extras %}
-
{% load static %}
{% block content %}
-
-<div class="w3-container">
- <h2>Engagement Plans for {{ entity.name }}</h2>
- <a href="{% url 'engagements:create' entity.slug 'reg' %}">Add New Regulatory Engagement</a> | <a href="{% url 'engagements:create' entity.slug %}">Add New Engagement</a>
-</div>
-
-<div class="w3-container">
- <h3>2023</h3>
- <table class="ep-table">
- <thead>
- <tr>
- <th>Start Date</th>
- <th>End Date</th>
- <th>Engagement</th>
- <th>Engagement Type</th>
- <th>Area/Theme</th>
- <th>Inspectors Involved</th>
- <th>DSCs</th>
- <th>Travel Effort</th>
- <th>Planning and Regulation Effort</th>
- <th>Completion Status</th>
- </tr>
- </thead>
- <tbody>
- {% for e in engagements %}
- <tr>
- <td>{{ e.proposed_start_date|date:'j M Y' }}</td>
- <td>{{ e.proposed_end_date|date:'j M Y' }}</td>
- <td><a href="{% url 'engagements:engagement_detail' e.pk %}">{{ e }}</a></td>
- <td>{{ e.friendly_type }}</td>
- <td>Area Theme</td>
- <td>
- <ul class="w3-ul">
- {% for inspector in e.officers.all %}
- <li>{{ inspector }} </li>
- {% endfor %}
- </ul>
- </td>
- <td>
- <ul class="w3-ul">
- {% for dsc in e.dscs %}
- <li><a href="#">{{ dsc.short }}</a></li>
+<div class="container mx-auto px-4 py-8">
+ <div class="bg-white shadow-md rounded-lg overflow-hidden">
+ <header class="bg-blue-100 p-4">
+ <h2 class="text-3xl font-bold">Engagement Plans for {{ entity.name }}</h2>
+ </header>
+ <div class="p-4">
+ <div class="mb-4">
+ <a href="{% url 'engagements:create' entity.slug 'reg' %}" class="text-blue-600 hover:underline">Add New Regulatory Engagement</a> |
+ <a href="{% url 'engagements:create' entity.slug %}" class="text-blue-600 hover:underline">Add New Engagement</a>
+ </div>
+
+ <h3 class="text-2xl font-semibold mb-4">2023</h3>
+ <div class="overflow-x-auto">
+ <table class="min-w-full divide-y divide-gray-200">
+ <thead class="bg-gray-50">
+ <tr>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Start Date</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">End Date</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Engagement</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Engagement Type</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Area/Theme</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Inspectors Involved</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">DSCs</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Travel Effort</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Planning and Regulation Effort</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Completion Status</th>
+ </tr>
+ </thead>
+ <tbody class="bg-white divide-y divide-gray-200">
+ {% for e in engagements %}
+ <tr class="{% cycle 'bg-white' 'bg-gray-50' %}">
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ e.proposed_start_date|date:'j M Y' }}</td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ e.proposed_end_date|date:'j M Y' }}</td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-blue-600 hover:underline">
+ <a href="{% url 'engagements:engagement_detail' e.pk %}">{{ e }}</a>
+ </td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ e.friendly_type }}</td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">Area Theme</td>
+ <td class="px-6 py-4 text-sm text-gray-500">
+ <ul class="list-disc list-inside">
+ {% for inspector in e.officers.all %}
+ <li>{{ inspector }}</li>
+ {% endfor %}
+ </ul>
+ </td>
+ <td class="px-6 py-4 text-sm text-gray-500">
+ <ul class="list-disc list-inside">
+ {% for dsc in e.dscs %}
+ <li><a href="#" class="text-blue-600 hover:underline">{{ dsc.short }}</a></li>
+ {% endfor %}
+ </ul>
+ </td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">TBC</td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">TBC</td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">Incomplete</td>
+ </tr>
{% endfor %}
- </ul>
- </td>
- <td>TBC</td>
- <td>TBC</td>
- <td class="ep-table">Incomplete</td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
-
-</div>
-
-<hr>
-
-<div class="w3-container">
- <div class="w3-cell-row">
- <div class="w3-container w3-cell">
- <h3>Total DSC coverage</h3>
- <table class="summary-table">
- <tr>
- <th>DSC</th>
- <th>Allocated time</th>
- </tr>
- {% for dsc in dscs %}
- <tr>
- <td>{{ dsc }} </td>
- <td>{{ dsc | effort_for_org:entity }}</td>
- </tr>
- {% endfor %}
- </table>
- </div>
- <div class="w3-container w3-cell">
- <h3>Another table of data</h3>
- <table class="summary-table">
- <tr>
- <th>DSC</th>
- <th>Allocated time</th>
- </tr>
- {% for dsc in dscs %}
- <tr>
- <td>{{ dsc }} </td>
- <td>{{ dsc | effort_for_org:entity }}</td>
- </tr>
- {% endfor %}
- </table>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-8">
+ <div>
+ <h3 class="text-xl font-semibold mb-4">Total DSC coverage</h3>
+ <table class="min-w-full divide-y divide-gray-200">
+ <thead class="bg-gray-50">
+ <tr>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">DSC</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Allocated time</th>
+ </tr>
+ </thead>
+ <tbody class="bg-white divide-y divide-gray-200">
+ {% for dsc in dscs %}
+ <tr class="{% cycle 'bg-white' 'bg-gray-50' %}">
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ dsc }}</td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ dsc | effort_for_org:entity }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ <div>
+ <h3 class="text-xl font-semibold mb-4">Another table of data</h3>
+ <table class="min-w-full divide-y divide-gray-200">
+ <thead class="bg-gray-50">
+ <tr>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">DSC</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Allocated time</th>
+ </tr>
+ </thead>
+ <tbody class="bg-white divide-y divide-gray-200">
+ {% for dsc in dscs %}
+ <tr class="{% cycle 'bg-white' 'bg-gray-50' %}">
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ dsc }}</td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ dsc | effort_for_org:entity }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
</div>
-
</div>
</div>
-
-<style type="text/css" media="screen">
-
- /* (A) CONTAINER */
- /* https://code-boxx.com/beginner-create-grid-html-css/ */
- #grid-col {
-
- /* (A1) GRID LAYOUT */
- display: grid;
-
- /* (A2) SPECIFY COLUMNS */
- grid-template-columns: 75px repeat(31, 40px);
-
- /* we can also specify exact pixels, percentage, repeat
- grid-template-columns: 50px 100px 150px;
- grid-template-columns: 25% 50% 25%;
- grid-template-columns: 100px 20% auto;
- grih-template-columns: repeat(3, auto); */
- }
-
- /* (B) GRID CELLS */
- div.cell {
- background: white;
- border: 1px solid lightgray;
- padding: 10px;
- }
-
- div.cellred{
- background: red;
- border: 1px solid lightgray;
- padding: 10px;
- }
-
- div.cellyellow{
- background: yellow;
- border: 1px solid lightgray;
- padding: 10px;
- }
- div.cellorange{
- background: orange;
- border: 1px solid lightgray;
- padding: 10px;
- }
- /* (C) RESPONSIVE - 1 COLUMN ON SMALL SCREENS */
- /* @media screen and (max-width: 640px) {
- #grid-col { grid-template-columns: 100%; }
- }
- */
-/* </style>
-<!-- <div class="w3-container w3-padding-16"> -->
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell"></div><div class="cell">1</div> -->
-<!-- <div class="cell">2</div><div class="cell">3</div> -->
-<!-- <div class="cell">4</div><div class="cell">5</div> -->
-<!-- <div class="cell">6</div><div class="cell">7</div> -->
-<!-- <div class="cell">8</div><div class="cell">9</div> -->
-<!-- <div class="cell">10</div><div class="cell">11</div> -->
-<!-- <div class="cell">12</div><div class="cell">13</div> -->
-<!-- <div class="cell">14</div><div class="cell">15</div> -->
-<!-- <div class="cell">16</div><div class="cell">17</div> -->
-<!-- <div class="cell">18</div><div class="cell">19</div> -->
-<!-- <div class="cell">20</div><div class="cell">21</div> -->
-<!-- <div class="cell">22</div><div class="cell">23</div> -->
-<!-- <div class="cell">24</div><div class="cell">25</div> -->
-<!-- <div class="cell">26</div><div class="cell">27</div> -->
-<!-- <div class="cell">28</div><div class="cell">29</div> -->
-<!-- <div class="cell">30</div><div class="cell">31</div> -->
-<!-- </div> -->
-<!-- </div> -->
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Jan</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cellred"><small></small></div><div class="cellred"><small></small></div> -->
-<!-- <div class="cellred"><small></small></div><div class="cellred"><small></small></div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Feb</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cellyellow"><small></small></div><div class="cellyellow"><small></small></div> -->
-<!-- <div class="cellyellow"><small></small></div><div class="cellyellow"><small></small></div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Mar</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cellorange"><small></small></div><div class="cellorange"><small></small></div> -->
-<!-- <div class="cellorange"><small></small></div><div class="cellorange"><small></small></div> -->
-<!-- <div class="cellorange"><small></small></div><div class="cellorange"><small></small></div> -->
-<!-- <div class="cellorange"><small></small></div><div class="cellorange"><small></small></div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- <div class="cell">-</div><div class="cell">-</div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Apr</div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">May</div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Jun</div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Jul</div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Aug</div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Sep</div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Oct</div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Nov</div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-<!-- <div class="grid"> -->
-<!-- <div id="grid-col"> -->
-<!-- <div class="cell">Dec</div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- <div class="cell"></div><div class="cell"></div> -->
-<!-- </div> -->
-<!-- </div> -->
-
-
-<script src="{% static 'js/yoap.js' %}"></script>
-
{% endblock content %}
diff --git a/engagements/templates/engagements/index.html b/engagements/templates/engagements/index.html
index 8d5df36..a63aceb 100644
--- a/engagements/templates/engagements/index.html
+++ b/engagements/templates/engagements/index.html
@@ -3,28 +3,33 @@
{% block title %}Engagements{% endblock title %}
{% block content %}
+<div class="container mx-auto px-4 py-8">
+ <div class="bg-white shadow-md rounded-lg overflow-hidden">
+ <header class="bg-blue-100 p-4">
+ <h2 class="text-3xl font-bold">Engagement Planning</h2>
+ </header>
+ <div class="p-4">
+ <h3 class="text-2xl font-semibold mb-4">Your entities</h3>
-<div class="w3-container">
- <h2>Engagement Planning</h2>
- <div class="w3-container">
-
- <h3>Your entities</h3>
-
- <table class="w3-table w3-bordered">
- <tr>
- <th>Engagement Plan</th>
- <th>Scheduled Engagements</th>
- <th>Total time</th>
- </tr>
- {% for e in entities %}
- <tr>
- <td><a href="{% url 'engagements:plan_for_org' e.slug %}">{{ e.name }}</a></td>
- <td>{{ e.engagement_set.all.count }}</td>
- <td>NA</td>
- </tr>
- {% endfor %}
- </table>
+ <table class="w-full mb-4">
+ <thead>
+ <tr class="bg-gray-200">
+ <th class="p-2 text-left">Engagement Plan</th>
+ <th class="p-2 text-left">Scheduled Engagements</th>
+ <th class="p-2 text-left">Total time</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for e in entities %}
+ <tr class="{% cycle 'bg-white' 'bg-gray-100' %}">
+ <td class="p-2"><a href="{% url 'engagements:plan_for_org' e.slug %}" class="text-blue-600 hover:underline">{{ e.name }}</a></td>
+ <td class="p-2">{{ e.engagement_set.all.count }}</td>
+ <td class="p-2">NA</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
</div>
</div>
-
{% endblock content %}
diff --git a/engagements/templates/engagements/organisations.html b/engagements/templates/engagements/organisations.html
index 5bbd1b5..f2605c4 100644
--- a/engagements/templates/engagements/organisations.html
+++ b/engagements/templates/engagements/organisations.html
@@ -4,47 +4,53 @@
{% block title %}Regulated Entities{% endblock title %}
{% block content %}
-
-<div class="w3-container">
- <h1>Regulated Entities</h1>
- <div class="w3-container">
- <table class="w3-table w3-bordered w3-striped">
- <tr>
- <th>Entity</th>
- <th>Team</th>
- <th>Lead Inspector[s]</th>
- <th>Responsible Person[s]</th>
- <th>Accountable Person[s]</th>
- </tr>
- {% for e in entities %}
- <tr>
- <td>{{ e.name }}</td>
- <td>{{ e.lead_team }}</td>
- <td>
- {% if e.lead_inspector.all %}
- {{ e.lead_inspector.all|commalist }}
- {% endif %}
- </td>
- <td>
- <!-- rp -->
- {% if e.rp.all %}
- {% for p in e.rp.all %}
- {{ p }}
- {% endfor %}
- {% endif %}
- </td>
- <td>
- <!-- ap -->
- {% if e.ap.all %}
- {% for p in e.ap.all %}
- {{ p }}
- {% endfor %}
- {% endif %}
- </td>
- </tr>
- {% endfor %}
- </table>
- </div>
+<div class="container mx-auto px-4 py-8">
+ <div class="bg-white shadow-md rounded-lg overflow-hidden">
+ <header class="bg-blue-100 p-4">
+ <h1 class="text-3xl font-bold">Regulated Entities</h1>
+ </header>
+ <div class="p-4">
+ <div class="overflow-x-auto">
+ <table class="min-w-full divide-y divide-gray-200">
+ <thead class="bg-gray-50">
+ <tr>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Entity</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Team</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Lead Inspector[s]</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Responsible Person[s]</th>
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Accountable Person[s]</th>
+ </tr>
+ </thead>
+ <tbody class="bg-white divide-y divide-gray-200">
+ {% for e in entities %}
+ <tr class="{% cycle 'bg-white' 'bg-gray-50' %}">
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"><a href="#" class="text-blue-600 hover:text-blue-900">{{ e.name }}</a></td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ e.lead_team }}</td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
+ {% if e.lead_inspector.all %}
+ {{ e.lead_inspector.all|commalist }}
+ {% endif %}
+ </td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
+ {% if e.rp.all %}
+ {% for p in e.rp.all %}
+ {{ p }}{% if not forloop.last %}, {% endif %}
+ {% endfor %}
+ {% endif %}
+ </td>
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
+ {% if e.ap.all %}
+ {% for p in e.ap.all %}
+ {{ p }}{% if not forloop.last %}, {% endif %}
+ {% endfor %}
+ {% endif %}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
</div>
-
{% endblock content %}
diff --git a/engagements/templates/engagements/snippets/effort_summary_panel.html b/engagements/templates/engagements/snippets/effort_summary_panel.html
index 235a67a..d0dc256 100644
--- a/engagements/templates/engagements/snippets/effort_summary_panel.html
+++ b/engagements/templates/engagements/snippets/effort_summary_panel.html
@@ -1,41 +1,33 @@
{% load table_extras %}
-{% if e.is_planned %}
- <div class="w3-panel w3-pale-green w3-topbar w3-border-green">
-{% else %}
- <div class="w3-panel w3-light-gray w3-topbar w3-border-green">
-{% endif %}
- <div class="w3-cell-row">
- <div class="w3-cell w3-align-left">
- <h5>{{ e.proposed_start_date|date:'j M Y' }} - {{ e.effort_type }}</h5>
- </div>
- <div class="w3-cell w3-right-align">
- <p> {{ e.effort_total_hours|floatformat }} hrs</p>
- Planned: {{ e.is_planned }}
- <button hx-get="{% url 'engagements:htmx-effort-planned' e.id %}" hx-target="#planned_swap_{{ e.id }}">
- Flip
+<div class="bg-white shadow-sm rounded-lg overflow-hidden border {% if e.is_planned %}border-green-500{% else %}border-gray-300{% endif %} mb-4">
+ <div class="px-4 py-3 bg-gray-50 flex justify-between items-center">
+ <h5 class="text-lg font-semibold">{{ e.proposed_start_date|date:'j M Y' }} - {{ e.effort_type }}</h5>
+ <div class="text-right">
+ <p class="text-sm font-medium">{{ e.effort_total_hours|floatformat }} hrs</p>
+ <span class="text-sm text-gray-500">Planned: {{ e.is_planned|yesno:"Yes,No" }}</span>
+ <button hx-get="{% url 'engagements:htmx-effort-planned' e.id %}" hx-target="#planned_swap_{{ e.id }}" class="ml-2 px-2 py-1 text-sm bg-blue-500 text-white rounded hover:bg-blue-600">
+ Flip
</button>
</div>
</div>
- <div>
- <strong>Inspectors:</strong> {{ e.officers.all|commalist }}
- </div>
- <div>
- <strong>Start time</strong>: {{ e.proposed_start_date|date:'H:i' }}
- {% if e.proposed_end_date %}
- - {{ e.proposed_end_date|date:'H:i' }}
- {% endif %}
- </div>
-
- <div>
+ <div class="px-4 py-3">
+ <p class="mb-2"><strong class="font-medium">Inspectors:</strong> {{ e.officers.all|commalist }}</p>
+ <p class="mb-2">
+ <strong class="font-medium">Start time:</strong> {{ e.proposed_start_date|date:'H:i' }}
+ {% if e.proposed_end_date %}
+ - {{ e.proposed_end_date|date:'H:i' }}
+ {% endif %}
+ </p>
{% if e.sub_instruments.all %}
- <strong>DSCs</strong>:
- <ul>
- {% for dsc in e.sub_instruments.all %}
- <li><a href="#">{{ dsc.title }}</a></li>
- {% endfor %}
- </ul>
+ <div>
+ <strong class="font-medium">DSCs:</strong>
+ <ul class="list-disc list-inside mt-1 ml-4">
+ {% for dsc in e.sub_instruments.all %}
+ <li><a href="#" class="text-blue-600 hover:underline">{{ dsc.title }}</a></li>
+ {% endfor %}
+ </ul>
+ </div>
{% endif %}
-
</div>
</div>
diff --git a/myuser/models.py b/myuser/models.py
index 1236ba6..d9f8aba 100644
--- a/myuser/models.py
+++ b/myuser/models.py
@@ -41,6 +41,25 @@ class Team(Common):
class TeamUser(AbstractBaseUser, PermissionsMixin):
+ """
+ The `TeamUser` class is a custom user model that extends the `AbstractBaseUser` and `PermissionsMixin` classes from Django's built-in authentication system. It provides a user model with the following fields:
+
+ - `email`: The user's email address, which is used as the unique identifier for the user.
+ - `first_name`: The user's first name (optional).
+ - `last_name`: The user's last name (optional).
+ - `dapsy`: A boolean field indicating whether the user is a DAPSY user.
+ - `is_active`: A boolean field indicating whether the user is active.
+ - `is_admin`: A boolean field indicating whether the user is an admin.
+ - `team`: A foreign key relationship to the `Team` model, indicating the team the user belongs to.
+ - `lead_for`: A many-to-many relationship to the `engagements.Organisation` model, indicating the organizations the user is a lead inspector for.
+ - `designation`: The user's designation (optional).
+
+ The `TeamUser` class also overrides the default user manager with the `TeamMgr` class, which provides custom methods for creating regular and superuser accounts.
+
+ The `__str__` method returns the user's email address, and the `fullname` method returns the user's full name (first and last name).
+
+ The `has_perm` and `has_module_perms` methods are placeholders that always return `True`, indicating that the user has all permissions. The `is_staff` property is also a placeholder that returns the value of `is_admin`.
+ """
email = EmailField(verbose_name="email address", max_length=255, unique=True)
first_name = CharField(max_length=20, null=True, blank=True)
last_name = CharField(max_length=20, null=True, blank=True)
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..c4603f3
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1595 @@
+{
+ "name": "ded-web",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "devDependencies": {
+ "autoprefixer": "^10.4.20",
+ "daisyui": "^4.12.10",
+ "postcss": "^8.4.41",
+ "tailwindcss": "^3.4.10"
+ }
+ },
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "dev": true
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.4.20",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
+ "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "browserslist": "^4.23.3",
+ "caniuse-lite": "^1.0.30001646",
+ "fraction.js": "^4.3.7",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.0.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.23.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
+ "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001646",
+ "electron-to-chromium": "^1.5.4",
+ "node-releases": "^2.0.18",
+ "update-browserslist-db": "^1.1.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001653",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz",
+ "integrity": "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css-selector-tokenizer": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz",
+ "integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "fastparse": "^1.1.2"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/culori": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz",
+ "integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/daisyui": {
+ "version": "4.12.10",
+ "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.12.10.tgz",
+ "integrity": "sha512-jp1RAuzbHhGdXmn957Z2XsTZStXGHzFfF0FgIOZj3Wv9sH7OZgLfXTRZNfKVYxltGUOBsG1kbWAdF5SrqjebvA==",
+ "dev": true,
+ "dependencies": {
+ "css-selector-tokenizer": "^0.8",
+ "culori": "^3",
+ "picocolors": "^1",
+ "postcss-js": "^4"
+ },
+ "engines": {
+ "node": ">=16.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/daisyui"
+ }
+ },
+ "node_modules/didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "dev": true
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "dev": true
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.13",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz",
+ "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==",
+ "dev": true
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true
+ },
+ "node_modules/escalade": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+ "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fastparse": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
+ "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
+ "dev": true
+ },
+ "node_modules/fastq": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
+ "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
+ "dev": true,
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "1.21.6",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
+ "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
+ "dev": true,
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
+ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
+ "dev": true
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
+ "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
+ "dev": true
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+ "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
+ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.41",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
+ "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.1",
+ "source-map-js": "^1.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-import": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-js": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
+ "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
+ "dev": true,
+ "dependencies": {
+ "camelcase-css": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >= 16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.21"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
+ "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "lilconfig": "^3.0.0",
+ "yaml": "^2.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-load-config/node_modules/lilconfig": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
+ "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/postcss-nested": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "postcss-selector-parser": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "dev": true,
+ "dependencies": {
+ "pify": "^2.3.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sucrase": {
+ "version": "3.35.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "glob": "^10.3.10",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "3.4.10",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz",
+ "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==",
+ "dev": true,
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.5.3",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.0",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.0",
+ "lilconfig": "^2.1.0",
+ "micromatch": "^4.0.5",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.0.0",
+ "postcss": "^8.4.23",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.1",
+ "postcss-nested": "^6.0.1",
+ "postcss-selector-parser": "^6.0.11",
+ "resolve": "^1.22.2",
+ "sucrase": "^3.32.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "dev": true
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
+ "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.2",
+ "picocolors": "^1.0.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yaml": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
+ "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==",
+ "dev": true,
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..05633ad
--- /dev/null
+++ b/package.json
@@ -0,0 +1,11 @@
+{
+ "devDependencies": {
+ "autoprefixer": "^10.4.20",
+ "daisyui": "^4.12.10",
+ "postcss": "^8.4.41",
+ "tailwindcss": "^3.4.10"
+ },
+ "scripts": {
+ "build": "tailwindcss build core/static/css/main.css -o core/static/css/output.css"
+ }
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..e2dc478
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ }
+} \ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 601c07a..468d422 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,4 @@
Django>=4.2.11,<5.0.0
-django-crispy-forms
#django-extensions
#faker>=13.14.0,<14.0.0
django-htmx==1.17.3
diff --git a/scripts/watch_and_build.sh b/scripts/watch_and_build.sh
new file mode 100755
index 0000000..14f6f2e
--- /dev/null
+++ b/scripts/watch_and_build.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+while inotifywait -e modify,create,delete -r ./templates ./core/templates ./engagements/templates
+do
+ npm run build
+done \ No newline at end of file
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..cec0756
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,18 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [
+ './templates/**/*.html',
+ './core/templates/**/*.html',
+ './engagements/templates/**/*.html',
+ './instruments/templates/**/*.html',
+ './myuser/templates/**/*.html',
+ ],
+ theme: {
+ extend: {},
+ },
+ plugins: [require("daisyui")],
+ daisyui: {
+ themes: ["light", "dark", "cupcake"],
+ },
+}
+