* [yocto-autobuilder-helper][PATCH 0/4] Update dashboard, Bugzilla stats, bug triage page and autobuilder issues page
@ 2026-01-28 14:02 Alba Herrerias
2026-01-28 14:02 ` [yocto-autobuilder-helper][PATCH 1/4] dashboard: update to unify styles with CVE/Patch Metrics pages Alba Herrerias
2026-01-28 14:02 ` [yocto-autobuilder-helper][PATCH 3/4] dashboard/bugtriage: " Alba Herrerias
0 siblings, 2 replies; 3+ messages in thread
From: Alba Herrerias @ 2026-01-28 14:02 UTC (permalink / raw)
To: yocto-patches; +Cc: engineering, Alba Herrerias
This branch constitutes the entirety of the work on the STA Milestones 2
and 3 for Yocto in 2025: Improved design and unified website pages,
concerning Yocto’s dashboard page, the Bugzilla stats page, the bug
triage page, and the Autobuilder Issues page (abint). In general, the
work consisted of: unifying all pages to a common design that matches
our previous work on the CVE/Metrics pages, and also unifying the rendering
of charts to use Apache eCharts. Also: adding proper support for small
screens and dark mode, as well as general refactoring, optimisation and
simplification where possible. More details and screenshots are available
at: https://github.com/neighbourhoodie/yocto-autobuilder-helper/pull/11.
Alex Feyerke (4):
dashboard: update to unify styles with CVE/Patch Metrics pages
dashboard/bugzilla: update to unify styles with CVE/Patch Metrics
pages
dashboard/bugtriage: update to unify styles with CVE/Patch Metrics
pages
abint: update to unify styles with CVE/Patch Metrics pages
scripts/abint/abint.html.j2 | 87 -
scripts/abint/abint.py | 46 +-
scripts/abint/index.html | 290 ++
scripts/abint/requirements.txt | 2 -
scripts/abint/resources/apple-touch-icon.png | Bin 0 -> 7683 bytes
scripts/abint/resources/dark.js | 76 +
scripts/abint/resources/date_helper.js | 36 +
scripts/abint/resources/favicon-16x16.png | Bin 0 -> 792 bytes
scripts/abint/resources/favicon-32x32.png | Bin 0 -> 1246 bytes
.../resources/pico.fluid.classless.min.css | 4 +
scripts/abint/resources/shared-styles.css | 75 +
scripts/abint/resources/tablesort.date.js | 23 +
scripts/abint/resources/tablesort.min.js | 6 +
scripts/abint/resources/tablesort.number.js | 26 +
...to.echarts.with_heatmap_single-axis.min.js | 1 +
scripts/abint/sorttable.js | 495 ---
scripts/dashboard/bugtriage/index.html | 588 ++-
scripts/dashboard/bugtriage/tablesort.min.js | 6 +
.../dashboard/bugtriage/tablesort.number.js | 26 +
scripts/dashboard/bugzilla_stats.html | 256 ++
scripts/dashboard/data/wdd-weekly-recent.txt | 3490 +++++++++++++++++
scripts/dashboard/index.html | 77 +-
.../dashboard/resources/apple-touch-icon.png | Bin 0 -> 7683 bytes
scripts/dashboard/resources/dark.js | 76 +
scripts/dashboard/resources/favicon-16x16.png | Bin 0 -> 792 bytes
scripts/dashboard/resources/favicon-32x32.png | Bin 0 -> 1246 bytes
.../resources/pico.fluid.classless.min.css | 4 +
scripts/dashboard/resources/shared-styles.css | 75 +
.../dashboard/resources/yocto.echarts.min.js | 1 +
scripts/run-abint | 2 +-
30 files changed, 4958 insertions(+), 810 deletions(-)
delete mode 100644 scripts/abint/abint.html.j2
create mode 100644 scripts/abint/index.html
create mode 100644 scripts/abint/resources/apple-touch-icon.png
create mode 100644 scripts/abint/resources/dark.js
create mode 100644 scripts/abint/resources/date_helper.js
create mode 100644 scripts/abint/resources/favicon-16x16.png
create mode 100644 scripts/abint/resources/favicon-32x32.png
create mode 100644 scripts/abint/resources/pico.fluid.classless.min.css
create mode 100644 scripts/abint/resources/shared-styles.css
create mode 100644 scripts/abint/resources/tablesort.date.js
create mode 100644 scripts/abint/resources/tablesort.min.js
create mode 100644 scripts/abint/resources/tablesort.number.js
create mode 100644 scripts/abint/resources/yocto.echarts.with_heatmap_single-axis.min.js
delete mode 100644 scripts/abint/sorttable.js
create mode 100644 scripts/dashboard/bugtriage/tablesort.min.js
create mode 100644 scripts/dashboard/bugtriage/tablesort.number.js
create mode 100644 scripts/dashboard/bugzilla_stats.html
create mode 100644 scripts/dashboard/data/wdd-weekly-recent.txt
create mode 100644 scripts/dashboard/resources/apple-touch-icon.png
create mode 100644 scripts/dashboard/resources/dark.js
create mode 100644 scripts/dashboard/resources/favicon-16x16.png
create mode 100644 scripts/dashboard/resources/favicon-32x32.png
create mode 100644 scripts/dashboard/resources/pico.fluid.classless.min.css
create mode 100644 scripts/dashboard/resources/shared-styles.css
create mode 100644 scripts/dashboard/resources/yocto.echarts.min.js
--
2.40.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [yocto-autobuilder-helper][PATCH 1/4] dashboard: update to unify styles with CVE/Patch Metrics pages
2026-01-28 14:02 [yocto-autobuilder-helper][PATCH 0/4] Update dashboard, Bugzilla stats, bug triage page and autobuilder issues page Alba Herrerias
@ 2026-01-28 14:02 ` Alba Herrerias
2026-01-28 14:02 ` [yocto-autobuilder-helper][PATCH 3/4] dashboard/bugtriage: " Alba Herrerias
1 sibling, 0 replies; 3+ messages in thread
From: Alba Herrerias @ 2026-01-28 14:02 UTC (permalink / raw)
To: yocto-patches; +Cc: engineering, Alex Feyerke
From: Alex Feyerke <alex@neighbourhood.ie>
Signed-off-by: Alex Feyerke <alex@neighbourhood.ie>
---
scripts/dashboard/index.html | 77 ++++++++++--------
.../dashboard/resources/apple-touch-icon.png | Bin 0 -> 7683 bytes
scripts/dashboard/resources/favicon-16x16.png | Bin 0 -> 792 bytes
scripts/dashboard/resources/favicon-32x32.png | Bin 0 -> 1246 bytes
.../resources/pico.fluid.classless.min.css | 4 +
scripts/dashboard/resources/shared-styles.css | 75 +++++++++++++++++
6 files changed, 123 insertions(+), 33 deletions(-)
create mode 100644 scripts/dashboard/resources/apple-touch-icon.png
create mode 100644 scripts/dashboard/resources/favicon-16x16.png
create mode 100644 scripts/dashboard/resources/favicon-32x32.png
create mode 100644 scripts/dashboard/resources/pico.fluid.classless.min.css
create mode 100644 scripts/dashboard/resources/shared-styles.css
diff --git a/scripts/dashboard/index.html b/scripts/dashboard/index.html
index 5cff80a..86b4cb8 100644
--- a/scripts/dashboard/index.html
+++ b/scripts/dashboard/index.html
@@ -1,39 +1,50 @@
<!DOCTYPE html>
<html>
+
<head>
-<title>Yocto Project Dashboard</title>
-<style>
-html { color-scheme: light dark; }
-body { width: 35em; margin: 0 auto;
-font-family: Tahoma, Verdana, Arial, sans-serif; }
-</style>
+ <title>Yocto Project Dashboard</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" href="resources/pico.fluid.classless.min.css">
+ <link rel="stylesheet" href="resources/shared-styles.css">
+ <link rel="apple-touch-icon" sizes="144x144" href="resources/apple-touch-icon.png">
+ <link rel="icon" type="image/png" sizes="32x32" href="resources/favicon-32x32.png">
+ <link rel="icon" type="image/png" sizes="16x16" href="resources/favicon-16x16.png">
</head>
+
<body>
-<h1>Yocto Project Dashboard</h1>
-<p>Current project status is included in the <a href="https://wiki.yoctoproject.org/wiki/Weekly_Status">Weekly Status Report</a></p>
-<p>Links to our commonly used tools and the data they generate:</p>
-<ul>
-<li><a href="https://autobuilder.yoctoproject.org/valkyrie/#/console">CI Main Console (Valkyrie autobuilder)</a></li>
-<li><a href="https://valkyrie.yocto.io/pub/non-release/">Autobuilder results index</a> (build performance, buildhistory, ptest and test result reports)</li>
-<li><a href="https://valkyrie.yocto.io/pub/non-release/abint/">Autobuilder Intermittent Issue Heatmap/Summary</a></li>
-<li>CVE Status and Patch Metrics: <a href="https://valkyrie.yocto.io/pub/non-release/patchmetrics/">OE-Core</a> <a href="https://valkyrie.yocto.io/pub/non-release/patchmetrics-meta-oe/">Meta-OpenEmbedded</a></li>
-<li>Git Repository Statistics: <a href="https://dashboard.yoctoproject.org/gitstats/poky/">Poky</a> <a href="https://dashboard.yoctoproject.org/gitstats/oecore/">OE-Core</a> <a href="https://dashboard.yoctoproject.org/gitstats/bitbake/">Bitbake</a> <a href="https://dashboard.yoctoproject.org/gitstats/meta-openembedded/">Meta-OE</a></li>
-<li><a href="bugtriage/">Bug Triage</a></li>
-</ul>
-<p>Other useful links:</p>
-</p>
-<ul>
-<li><a href="https://www.yoctoproject.org/development/releases/">Release Information</a></li>
-<li><a href="https://valkyrie.yocto.io/pub/">Autobuilder unreleased build output</a></li>
-<li><a href="https://swatbot.yoctoproject.org/">Swatbot - CI failure triage system</a></li>
-<li><a href="https://errors.yoctoproject.org/">Error Reporting System</a></li>
-<li><a href="https://layers.openembedded.org/">Layer Index</a></li>
-<li><a href="https://git.yoctoproject.org/">Yocto Project Source Code Repositories (git)</a></li>
-<li><a href="https://git.openembedded.org/">OpenEmbedded Source Code Repositories (git)</a></li>
-<li><a href="https://bugzilla.yoctoproject.org/">Yocto Project Bugzilla</a></li>
-<li><a href="https://www.yoctoproject.org/development/yocto-project-compatible-layers/">Yocto Project Compatible Layers</a></li>
-<li><a href="https://www.yoctoproject.org/reproducible-build-results/">Reproducibile Build Status</a></li>
-<li><a href="https://lore.kernel.org/">Lore Public Inbox for mailing lists</a></li>
-</ul>
+ <main>
+ <h1 class="with-logo">Yocto Project Dashboard</h1>
+ <section>
+ <p>Current project status is included in the <a href="https://wiki.yoctoproject.org/wiki/Weekly_Status">Weekly Status Report</a></p>
+ <ul>
+ <li><a href="bugzilla_stats.html">BugZilla Statistics</a></li>
+ </ul>
+ <p>Links to our commonly used tools and the data they generate:</p>
+ <ul>
+ <li><a href="https://autobuilder.yoctoproject.org/valkyrie/#/console">CI Main Console (Valkyrie autobuilder)</a></li>
+ <li><a href="https://valkyrie.yocto.io/pub/non-release/">Autobuilder results index</a> (build performance, buildhistory, ptest and test result reports)</li>
+ <li><a href="https://valkyrie.yocto.io/pub/non-release/abint/">Autobuilder Intermittent Issue Heatmap/Summary</a></li>
+ <li>CVE Status and Patch Metrics: <a href="https://valkyrie.yocto.io/pub/non-release/patchmetrics/">OE-Core</a> <a href="https://valkyrie.yocto.io/pub/non-release/patchmetrics-meta-oe/">Meta-OpenEmbedded</a></li>
+ <li>Git Repository Statistics: <a href="https://dashboard.yoctoproject.org/gitstats/poky/">Poky</a> <a href="https://dashboard.yoctoproject.org/gitstats/oecore/">OE-Core</a> <a href="https://dashboard.yoctoproject.org/gitstats/bitbake/">Bitbake</a> <a href="https://dashboard.yoctoproject.org/gitstats/meta-openembedded/">Meta-OE</a></li>
+ <li><a href="bugtriage/">Bug Triage</a></li>
+ </ul>
+ <p>Other useful links:</p>
+ </p>
+ <ul>
+ <li><a href="https://www.yoctoproject.org/development/releases/">Release Information</a></li>
+ <li><a href="https://valkyrie.yocto.io/pub/">Autobuilder unreleased build output</a></li>
+ <li><a href="https://swatbot.yoctoproject.org/">Swatbot - CI failure triage system</a></li>
+ <li><a href="https://errors.yoctoproject.org/">Error Reporting System</a></li>
+ <li><a href="https://layers.openembedded.org/">Layer Index</a></li>
+ <li><a href="https://git.yoctoproject.org/">Yocto Project Source Code Repositories (git)</a></li>
+ <li><a href="https://git.openembedded.org/">OpenEmbedded Source Code Repositories (git)</a></li>
+ <li><a href="https://bugzilla.yoctoproject.org/">Yocto Project Bugzilla</a></li>
+ <li><a href="https://www.yoctoproject.org/development/yocto-project-compatible-layers/">Yocto Project Compatible Layers</a></li>
+ <li><a href="https://www.yoctoproject.org/reproducible-build-results/">Reproducibile Build Status</a></li>
+ <li><a href="https://lore.kernel.org/">Lore Public Inbox for mailing lists</a></li>
+ </ul>
+ </section>
+ </main>
</body>
-</html>
+
+</html>
\ No newline at end of file
diff --git a/scripts/dashboard/resources/apple-touch-icon.png b/scripts/dashboard/resources/apple-touch-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d11f8bd0f9c0d6a765c815986199c36504bdaf20
GIT binary patch
literal 7683
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
literal 0
HcmV?d00001
diff --git a/scripts/dashboard/resources/favicon-16x16.png b/scripts/dashboard/resources/favicon-16x16.png
new file mode 100644
index 0000000000000000000000000000000000000000..ba9765fb51ae810cab294ca1d695f691c7e18c1a
GIT binary patch
literal 792
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F
z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a><Y92O1uj232`;15->6{%E-tl
zEiJXSwr*{0_4D&HG&HQOt-X5ns=mH{c6Rp7n>WM5!yOzPjvP5MW5x_CE32J5cP?47
z#KgqJz`&rmxVX2s_xkng5fKrF2Ktu1Nsj3gO)PATjg7v3{km}BLL(zXE5BsN%&8_8
zw)OS(PoF-GjEpokHrcv$>+<ExO-)T*TwJD4pML4mrI3&iM@Pqv8#kUjc`_v>#mvmi
z)z$U?|Nk#zBd-E|EnX7j7t9iQ>Gz*o8SGK7KIUJ1`s>D<Zw=4i*7K?_vo8iJVNCLN
zckyk=P)G%G*h@TpUD;o-a&Yi+^nElI2MR6qba4!kxa`}{F4W|}<GNT$<3@DYL{U*u
zmg@I=tN(xIIK?&7^Jl(Vy-<ULK}%jiVqAlVNUfrmz-DR1H3>38-y(DrC!Rhvy<zT_
zMOs&*Vi)sFaNE38I#*cIVfEs&>c0mIOy>PznArRB%pCn`+Tshg-pk2tmyKTd>t8{M
zeqlqURs6au%umYdZ8&#}S{#}F?O%4wlE)8UihNk~e`g6Bi{|T>G5bC+W~`H8Irr(a
z7tq0~C9V-ADTyViR>?)FK#IZ0z{o_`z*N`3BE-PL%Fx)#z(U)=z{<cN?xWl}6b-rg
zDVb@NxHagnSylwp5MC7$Q4*9`u24{vpO%@Es!&o{kgAYbP?F5RP%-E6CmxQ%Fb$1U
z{-@7)J`G}ER_4}A<`z~K_MR-lEUe(tU~)KxS$T7a!s#1VP8>ONMCJ(l=?0GlUV03#
X#05(}IhjrcTEXDy>gTe~DWM4fR(cu)
literal 0
HcmV?d00001
diff --git a/scripts/dashboard/resources/favicon-32x32.png b/scripts/dashboard/resources/favicon-32x32.png
new file mode 100644
index 0000000000000000000000000000000000000000..244edb606d7cfdd1c8bca17416d1911ff06d80f8
GIT binary patch
literal 1246
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50
z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+081LOVxpAc7|0^<P%hK7bl
zMn)zkCf?rOv9Yn1mX^W6!66|bhYlUOd-rZ?YO1ZR?V2@f?%%&(S6Aof=Xd`6`Tzg_
zuUoe+BO~L*ix=O&e{XGVZEtUX{rYuYUY?DO&6zW2JUu;+A3wfz>sEVv`)}XA)z;R2
z{`~pfyLY9frKeAy_VV&FGBPwaGIDly-nVbx{{8!%oSf3r)6HChY$Hm|U4lzWO5VSJ
z|MBC;_3PLF`}fbp%F(rao!_jtZdIF2teqVk9G*RU*3#1AR<Y54_Ivl5?WQ&^+1c4I
zU%s?(3$u%@v+#&CHZk3>VS}*|&}#-378c8vExUN}qQAd?e0==9d-s0+{MpynXKHG?
zcJ11~fByyq1ax+Ge)#a=)2B~OO-<(J=2NFm{q^hD>eZ_q9Ua}=+@?>Te);m{A3uJ$
zxVYT9b!)<e35kh`RaI4HW@efpCk=s7s8tf=7tFvQU3UEazb}`&v>6?a{<#sua{puU
z;RjZwzgNDy^nLI3z}ObnN4%?k>|^^-Sbhhni!sUD-Nj~kR^oXehrPtp*OmPRD+dQJ
z=g)7<jX>#UPZ!4!i_^7}p9VWQiX45fwWy_Y?u}i$HIg1XA3UV@=9u4`cX=ECC5W@8
z#?AFlfA;6woxQ)GF)D}%tl$Vr+SlY9lEuq3E!+9<h80sD3QpvhV8-R`CElx`z;;^0
zjPH@~6NWh)T=P|rWNUn6E}8J8w5`eM@p^47lS}nXdwvTB7kaLIuA!^Fe#Mv74DsuC
zc5R-raq^N~$FdeXF-T{vE&a-JnT`8;gaTVYwea;jPLYnQdAoZOT%xPp)e~7`@4nI7
za$J$2>i3R+jgI*TFMQyTKTuMVbH~i^rDlP}@@461vNZ|oDvRpYlr~1T7Z+w$w(=)z
zdiCfAZ(UeK^!*!8`V;cE9Q_$~<KDsujyLZLf3yFKZ?b>%;l+<9BHm0}p1!I1-{irR
z^8M4RU&k7jHbj4(`}*I*iCzp}UjBS~HESdHC;J1jIkna0+@JRgw)Oj8p6=17cw;-W
zYJ|^(p46#KT1#~%aJ@3wY2(SS5vx8|Jtc*ytLNOLQ_V)3Z1-<h({taVV(ve`|ADmM
z`8}rExtg}X7*Z{9jVMV;EJ?LWE=mPb3`Pb<Cb|Zux&{^@1{PL^##RQF+6D$z1_nRc
zM5|CV<mRVjrd8tB(0O|;s5A+$3W+EQN-S3>D9TUE%t=)!sVqoU$Sf#HW?-n8^Y{}F
zM`4(T#wq{PXFQ(<F)%B0>m_pwD+_y17GV}vaA`0(oWiWUIYi;~jVmXPoH-(Mg#C1b
d#{w@shF9W(C7+y3rvj~D@O1TaS?83{1ORK00eJub
literal 0
HcmV?d00001
diff --git a/scripts/dashboard/resources/pico.fluid.classless.min.css b/scripts/dashboard/resources/pico.fluid.classless.min.css
new file mode 100644
index 0000000..de403a2
--- /dev/null
+++ b/scripts/dashboard/resources/pico.fluid.classless.min.css
@@ -0,0 +1,4 @@
+@charset "UTF-8";/*!
+ * Pico CSS ✨ v2.1.1 (https://picocss.com)
+ * Copyright 2019-2025 - Licensed under MIT
+ */:host,:root{--pico-font-family-emoji:"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--pico-font-family-sans-serif:system-ui,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,Helvetica,Arial,"Helvetica Neue",sans-serif,var(--pico-font-family-emoji);--pico-font-family-monospace:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace,var(--pico-font-family-emoji);--pico-font-family:var(--pico-font-family-sans-serif);--pico-line-height:1.5;--pico-font-weight:400;--pico-font-size:100%;--pico-text-underline-offset:0.1rem;--pico-border-radius:0.25rem;--pico-border-width:0.0625rem;--pico-outline-width:0.125rem;--pico-transition:0.2s ease-in-out;--pico-spacing:1rem;--pico-typography-spacing-vertical:1rem;--pico-block-spacing-vertical:var(--pico-spacing);--pico-block-spacing-horizontal:var(--pico-spacing);--pico-form-element-spacing-vertical:0.75rem;--pico-form-element-spacing-horizontal:1rem;--pico-group-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-group-box-shadow-focus-with-button:0 0 0 var(--pico-outline-width) var(--pico-primary-focus);--pico-group-box-shadow-focus-with-input:0 0 0 0.0625rem var(--pico-form-element-border-color);--pico-modal-overlay-backdrop-filter:blur(0.375rem);--pico-nav-element-spacing-vertical:1rem;--pico-nav-element-spacing-horizontal:0.5rem;--pico-nav-link-spacing-vertical:0.5rem;--pico-nav-link-spacing-horizontal:0.5rem;--pico-nav-breadcrumb-divider:">";--pico-icon-checkbox:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-minus:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E");--pico-icon-chevron:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-date:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");--pico-icon-time:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-search:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E");--pico-icon-close:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");--pico-icon-loading:url("data:image/svg+xml,%3Csvg fill='none' height='24' width='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' %3E%3Cstyle%3E g %7B animation: rotate 2s linear infinite; transform-origin: center center; %7D circle %7B stroke-dasharray: 75,100; stroke-dashoffset: -5; animation: dash 1.5s ease-in-out infinite; stroke-linecap: round; %7D @keyframes rotate %7B 0%25 %7B transform: rotate(0deg); %7D 100%25 %7B transform: rotate(360deg); %7D %7D @keyframes dash %7B 0%25 %7B stroke-dasharray: 1,100; stroke-dashoffset: 0; %7D 50%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -17.5; %7D 100%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -62; %7D %7D %3C/style%3E%3Cg%3E%3Ccircle cx='12' cy='12' r='10' fill='none' stroke='rgb(136, 145, 164)' stroke-width='4' /%3E%3C/g%3E%3C/svg%3E")}@media (min-width:576px){:host,:root{--pico-font-size:106.25%}}@media (min-width:768px){:host,:root{--pico-font-size:112.5%}}@media (min-width:1024px){:host,:root{--pico-font-size:118.75%}}@media (min-width:1280px){:host,:root{--pico-font-size:125%}}@media (min-width:1536px){:host,:root{--pico-font-size:131.25%}}a{--pico-text-decoration:underline}small{--pico-font-size:0.875em}h1,h2,h3,h4,h5,h6{--pico-font-weight:700}h1{--pico-font-size:2rem;--pico-line-height:1.125;--pico-typography-spacing-top:3rem}h2{--pico-font-size:1.75rem;--pico-line-height:1.15;--pico-typography-spacing-top:2.625rem}h3{--pico-font-size:1.5rem;--pico-line-height:1.175;--pico-typography-spacing-top:2.25rem}h4{--pico-font-size:1.25rem;--pico-line-height:1.2;--pico-typography-spacing-top:1.874rem}h5{--pico-font-size:1.125rem;--pico-line-height:1.225;--pico-typography-spacing-top:1.6875rem}h6{--pico-font-size:1rem;--pico-line-height:1.25;--pico-typography-spacing-top:1.5rem}tfoot td,tfoot th,thead td,thead th{--pico-font-weight:600;--pico-border-width:0.1875rem}code,kbd,pre,samp{--pico-font-family:var(--pico-font-family-monospace)}kbd{--pico-font-weight:bolder}:where(select,textarea),input:not([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]){--pico-outline-width:0.0625rem}[type=search]{--pico-border-radius:5rem}[type=checkbox],[type=radio]{--pico-border-width:0.125rem}[type=checkbox][role=switch]{--pico-border-width:0.1875rem}[role=search]{--pico-border-radius:5rem}[role=group] [role=button],[role=group] [type=button],[role=group] [type=submit],[role=group] button,[role=search] [role=button],[role=search] [type=button],[role=search] [type=submit],[role=search] button{--pico-form-element-spacing-horizontal:2rem}details summary[role=button]::after{filter:brightness(0) invert(1)}[aria-busy=true]:not(input,select,textarea):is(button,[type=submit],[type=button],[type=reset],[role=button])::before{filter:brightness(0) invert(1)}:host(:not([data-theme=dark])),:root:not([data-theme=dark]),[data-theme=light]{color-scheme:light;--pico-background-color:#fff;--pico-color:#373c44;--pico-text-selection-color:rgba(2, 154, 232, 0.25);--pico-muted-color:#646b79;--pico-muted-border-color:rgb(231, 234, 239.5);--pico-primary:#0172ad;--pico-primary-background:#0172ad;--pico-primary-border:var(--pico-primary-background);--pico-primary-underline:rgba(1, 114, 173, 0.5);--pico-primary-hover:#015887;--pico-primary-hover-background:#02659a;--pico-primary-hover-border:var(--pico-primary-hover-background);--pico-primary-hover-underline:var(--pico-primary-hover);--pico-primary-focus:rgba(2, 154, 232, 0.5);--pico-primary-inverse:#fff;--pico-secondary:#5d6b89;--pico-secondary-background:#525f7a;--pico-secondary-border:var(--pico-secondary-background);--pico-secondary-underline:rgba(93, 107, 137, 0.5);--pico-secondary-hover:#48536b;--pico-secondary-hover-background:#48536b;--pico-secondary-hover-border:var(--pico-secondary-hover-background);--pico-secondary-hover-underline:var(--pico-secondary-hover);--pico-secondary-focus:rgba(93, 107, 137, 0.25);--pico-secondary-inverse:#fff;--pico-contrast:#181c25;--pico-contrast-background:#181c25;--pico-contrast-border:var(--pico-contrast-background);--pico-contrast-underline:rgba(24, 28, 37, 0.5);--pico-contrast-hover:#000;--pico-contrast-hover-background:#000;--pico-contrast-hover-border:var(--pico-contrast-hover-background);--pico-contrast-hover-underline:var(--pico-secondary-hover);--pico-contrast-focus:rgba(93, 107, 137, 0.25);--pico-contrast-inverse:#fff;--pico-box-shadow:0.0145rem 0.029rem 0.174rem rgba(129, 145, 181, 0.01698),0.0335rem 0.067rem 0.402rem rgba(129, 145, 181, 0.024),0.0625rem 0.125rem 0.75rem rgba(129, 145, 181, 0.03),0.1125rem 0.225rem 1.35rem rgba(129, 145, 181, 0.036),0.2085rem 0.417rem 2.502rem rgba(129, 145, 181, 0.04302),0.5rem 1rem 6rem rgba(129, 145, 181, 0.06),0 0 0 0.0625rem rgba(129, 145, 181, 0.015);--pico-h1-color:#2d3138;--pico-h2-color:#373c44;--pico-h3-color:#424751;--pico-h4-color:#4d535e;--pico-h5-color:#5c6370;--pico-h6-color:#646b79;--pico-mark-background-color:rgb(252.5, 230.5, 191.5);--pico-mark-color:#0f1114;--pico-ins-color:rgb(28.5, 105.5, 84);--pico-del-color:rgb(136, 56.5, 53);--pico-blockquote-border-color:var(--pico-muted-border-color);--pico-blockquote-footer-color:var(--pico-muted-color);--pico-button-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-button-hover-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-table-border-color:var(--pico-muted-border-color);--pico-table-row-stripped-background-color:rgba(111, 120, 135, 0.0375);--pico-code-background-color:rgb(243, 244.5, 246.75);--pico-code-color:#646b79;--pico-code-kbd-background-color:var(--pico-color);--pico-code-kbd-color:var(--pico-background-color);--pico-form-element-background-color:rgb(251, 251.5, 252.25);--pico-form-element-selected-background-color:#dfe3eb;--pico-form-element-border-color:#cfd5e2;--pico-form-element-color:#23262c;--pico-form-element-placeholder-color:var(--pico-muted-color);--pico-form-element-active-background-color:#fff;--pico-form-element-active-border-color:var(--pico-primary-border);--pico-form-element-focus-color:var(--pico-primary-border);--pico-form-element-disabled-opacity:0.5;--pico-form-element-invalid-border-color:rgb(183.5, 105.5, 106.5);--pico-form-element-invalid-active-border-color:rgb(200.25, 79.25, 72.25);--pico-form-element-invalid-focus-color:var(--pico-form-element-invalid-active-border-color);--pico-form-element-valid-border-color:rgb(76, 154.5, 137.5);--pico-form-element-valid-active-border-color:rgb(39, 152.75, 118.75);--pico-form-element-valid-focus-color:var(--pico-form-element-valid-active-border-color);--pico-switch-background-color:#bfc7d9;--pico-switch-checked-background-color:var(--pico-primary-background);--pico-switch-color:#fff;--pico-switch-thumb-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-range-border-color:#dfe3eb;--pico-range-active-border-color:#bfc7d9;--pico-range-thumb-border-color:var(--pico-background-color);--pico-range-thumb-color:var(--pico-secondary-background);--pico-range-thumb-active-color:var(--pico-primary-background);--pico-accordion-border-color:var(--pico-muted-border-color);--pico-accordion-active-summary-color:var(--pico-primary-hover);--pico-accordion-close-summary-color:var(--pico-color);--pico-accordion-open-summary-color:var(--pico-muted-color);--pico-card-background-color:var(--pico-background-color);--pico-card-border-color:var(--pico-muted-border-color);--pico-card-box-shadow:var(--pico-box-shadow);--pico-card-sectioning-background-color:rgb(251, 251.5, 252.25);--pico-loading-spinner-opacity:0.5;--pico-modal-overlay-background-color:rgba(232, 234, 237, 0.75);--pico-progress-background-color:#dfe3eb;--pico-progress-color:var(--pico-primary-background);--pico-tooltip-background-color:var(--pico-contrast-background);--pico-tooltip-color:var(--pico-contrast-inverse);--pico-icon-valid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(76, 154.5, 137.5)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-invalid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(200.25, 79.25, 72.25)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E")}:host(:not([data-theme=dark])) input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]),:root:not([data-theme=dark]) input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]),[data-theme=light] input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]){--pico-form-element-focus-color:var(--pico-primary-focus)}@media only screen and (prefers-color-scheme:dark){:host(:not([data-theme])),:root:not([data-theme]){color-scheme:dark;--pico-background-color:rgb(19, 22.5, 30.5);--pico-color:#c2c7d0;--pico-text-selection-color:rgba(1, 170, 255, 0.1875);--pico-muted-color:#7b8495;--pico-muted-border-color:#202632;--pico-primary:#01aaff;--pico-primary-background:#0172ad;--pico-primary-border:var(--pico-primary-background);--pico-primary-underline:rgba(1, 170, 255, 0.5);--pico-primary-hover:#79c0ff;--pico-primary-hover-background:#017fc0;--pico-primary-hover-border:var(--pico-primary-hover-background);--pico-primary-hover-underline:var(--pico-primary-hover);--pico-primary-focus:rgba(1, 170, 255, 0.375);--pico-primary-inverse:#fff;--pico-secondary:#969eaf;--pico-secondary-background:#525f7a;--pico-secondary-border:var(--pico-secondary-background);--pico-secondary-underline:rgba(150, 158, 175, 0.5);--pico-secondary-hover:#b3b9c5;--pico-secondary-hover-background:#5d6b89;--pico-secondary-hover-border:var(--pico-secondary-hover-background);--pico-secondary-hover-underline:var(--pico-secondary-hover);--pico-secondary-focus:rgba(144, 158, 190, 0.25);--pico-secondary-inverse:#fff;--pico-contrast:#dfe3eb;--pico-contrast-background:#eff1f4;--pico-contrast-border:var(--pico-contrast-background);--pico-contrast-underline:rgba(223, 227, 235, 0.5);--pico-contrast-hover:#fff;--pico-contrast-hover-background:#fff;--pico-contrast-hover-border:var(--pico-contrast-hover-background);--pico-contrast-hover-underline:var(--pico-contrast-hover);--pico-contrast-focus:rgba(207, 213, 226, 0.25);--pico-contrast-inverse:#000;--pico-box-shadow:0.0145rem 0.029rem 0.174rem rgba(7, 8.5, 12, 0.01698),0.0335rem 0.067rem 0.402rem rgba(7, 8.5, 12, 0.024),0.0625rem 0.125rem 0.75rem rgba(7, 8.5, 12, 0.03),0.1125rem 0.225rem 1.35rem rgba(7, 8.5, 12, 0.036),0.2085rem 0.417rem 2.502rem rgba(7, 8.5, 12, 0.04302),0.5rem 1rem 6rem rgba(7, 8.5, 12, 0.06),0 0 0 0.0625rem rgba(7, 8.5, 12, 0.015);--pico-h1-color:#f0f1f3;--pico-h2-color:#e0e3e7;--pico-h3-color:#c2c7d0;--pico-h4-color:#b3b9c5;--pico-h5-color:#a4acba;--pico-h6-color:#8891a4;--pico-mark-background-color:#014063;--pico-mark-color:#fff;--pico-ins-color:#62af9a;--pico-del-color:rgb(205.5, 126, 123);--pico-blockquote-border-color:var(--pico-muted-border-color);--pico-blockquote-footer-color:var(--pico-muted-color);--pico-button-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-button-hover-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-table-border-color:var(--pico-muted-border-color);--pico-table-row-stripped-background-color:rgba(111, 120, 135, 0.0375);--pico-code-background-color:rgb(26, 30.5, 40.25);--pico-code-color:#8891a4;--pico-code-kbd-background-color:var(--pico-color);--pico-code-kbd-color:var(--pico-background-color);--pico-form-element-background-color:rgb(28, 33, 43.5);--pico-form-element-selected-background-color:#2a3140;--pico-form-element-border-color:#2a3140;--pico-form-element-color:#e0e3e7;--pico-form-element-placeholder-color:#8891a4;--pico-form-element-active-background-color:rgb(26, 30.5, 40.25);--pico-form-element-active-border-color:var(--pico-primary-border);--pico-form-element-focus-color:var(--pico-primary-border);--pico-form-element-disabled-opacity:0.5;--pico-form-element-invalid-border-color:rgb(149.5, 74, 80);--pico-form-element-invalid-active-border-color:rgb(183.25, 63.5, 59);--pico-form-element-invalid-focus-color:var(--pico-form-element-invalid-active-border-color);--pico-form-element-valid-border-color:#2a7b6f;--pico-form-element-valid-active-border-color:rgb(22, 137, 105.5);--pico-form-element-valid-focus-color:var(--pico-form-element-valid-active-border-color);--pico-switch-background-color:#333c4e;--pico-switch-checked-background-color:var(--pico-primary-background);--pico-switch-color:#fff;--pico-switch-thumb-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-range-border-color:#202632;--pico-range-active-border-color:#2a3140;--pico-range-thumb-border-color:var(--pico-background-color);--pico-range-thumb-color:var(--pico-secondary-background);--pico-range-thumb-active-color:var(--pico-primary-background);--pico-accordion-border-color:var(--pico-muted-border-color);--pico-accordion-active-summary-color:var(--pico-primary-hover);--pico-accordion-close-summary-color:var(--pico-color);--pico-accordion-open-summary-color:var(--pico-muted-color);--pico-card-background-color:#181c25;--pico-card-border-color:var(--pico-card-background-color);--pico-card-box-shadow:var(--pico-box-shadow);--pico-card-sectioning-background-color:rgb(26, 30.5, 40.25);--pico-loading-spinner-opacity:0.5;--pico-modal-overlay-background-color:rgba(7.5, 8.5, 10, 0.75);--pico-progress-background-color:#202632;--pico-progress-color:var(--pico-primary-background);--pico-tooltip-background-color:var(--pico-contrast-background);--pico-tooltip-color:var(--pico-contrast-inverse);--pico-icon-valid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-invalid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(149.5, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E")}:host(:not([data-theme])) input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]),:root:not([data-theme]) input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]){--pico-form-element-focus-color:var(--pico-primary-focus)}}[data-theme=dark]{color-scheme:dark;--pico-background-color:rgb(19, 22.5, 30.5);--pico-color:#c2c7d0;--pico-text-selection-color:rgba(1, 170, 255, 0.1875);--pico-muted-color:#7b8495;--pico-muted-border-color:#202632;--pico-primary:#01aaff;--pico-primary-background:#0172ad;--pico-primary-border:var(--pico-primary-background);--pico-primary-underline:rgba(1, 170, 255, 0.5);--pico-primary-hover:#79c0ff;--pico-primary-hover-background:#017fc0;--pico-primary-hover-border:var(--pico-primary-hover-background);--pico-primary-hover-underline:var(--pico-primary-hover);--pico-primary-focus:rgba(1, 170, 255, 0.375);--pico-primary-inverse:#fff;--pico-secondary:#969eaf;--pico-secondary-background:#525f7a;--pico-secondary-border:var(--pico-secondary-background);--pico-secondary-underline:rgba(150, 158, 175, 0.5);--pico-secondary-hover:#b3b9c5;--pico-secondary-hover-background:#5d6b89;--pico-secondary-hover-border:var(--pico-secondary-hover-background);--pico-secondary-hover-underline:var(--pico-secondary-hover);--pico-secondary-focus:rgba(144, 158, 190, 0.25);--pico-secondary-inverse:#fff;--pico-contrast:#dfe3eb;--pico-contrast-background:#eff1f4;--pico-contrast-border:var(--pico-contrast-background);--pico-contrast-underline:rgba(223, 227, 235, 0.5);--pico-contrast-hover:#fff;--pico-contrast-hover-background:#fff;--pico-contrast-hover-border:var(--pico-contrast-hover-background);--pico-contrast-hover-underline:var(--pico-contrast-hover);--pico-contrast-focus:rgba(207, 213, 226, 0.25);--pico-contrast-inverse:#000;--pico-box-shadow:0.0145rem 0.029rem 0.174rem rgba(7, 8.5, 12, 0.01698),0.0335rem 0.067rem 0.402rem rgba(7, 8.5, 12, 0.024),0.0625rem 0.125rem 0.75rem rgba(7, 8.5, 12, 0.03),0.1125rem 0.225rem 1.35rem rgba(7, 8.5, 12, 0.036),0.2085rem 0.417rem 2.502rem rgba(7, 8.5, 12, 0.04302),0.5rem 1rem 6rem rgba(7, 8.5, 12, 0.06),0 0 0 0.0625rem rgba(7, 8.5, 12, 0.015);--pico-h1-color:#f0f1f3;--pico-h2-color:#e0e3e7;--pico-h3-color:#c2c7d0;--pico-h4-color:#b3b9c5;--pico-h5-color:#a4acba;--pico-h6-color:#8891a4;--pico-mark-background-color:#014063;--pico-mark-color:#fff;--pico-ins-color:#62af9a;--pico-del-color:rgb(205.5, 126, 123);--pico-blockquote-border-color:var(--pico-muted-border-color);--pico-blockquote-footer-color:var(--pico-muted-color);--pico-button-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-button-hover-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-table-border-color:var(--pico-muted-border-color);--pico-table-row-stripped-background-color:rgba(111, 120, 135, 0.0375);--pico-code-background-color:rgb(26, 30.5, 40.25);--pico-code-color:#8891a4;--pico-code-kbd-background-color:var(--pico-color);--pico-code-kbd-color:var(--pico-background-color);--pico-form-element-background-color:rgb(28, 33, 43.5);--pico-form-element-selected-background-color:#2a3140;--pico-form-element-border-color:#2a3140;--pico-form-element-color:#e0e3e7;--pico-form-element-placeholder-color:#8891a4;--pico-form-element-active-background-color:rgb(26, 30.5, 40.25);--pico-form-element-active-border-color:var(--pico-primary-border);--pico-form-element-focus-color:var(--pico-primary-border);--pico-form-element-disabled-opacity:0.5;--pico-form-element-invalid-border-color:rgb(149.5, 74, 80);--pico-form-element-invalid-active-border-color:rgb(183.25, 63.5, 59);--pico-form-element-invalid-focus-color:var(--pico-form-element-invalid-active-border-color);--pico-form-element-valid-border-color:#2a7b6f;--pico-form-element-valid-active-border-color:rgb(22, 137, 105.5);--pico-form-element-valid-focus-color:var(--pico-form-element-valid-active-border-color);--pico-switch-background-color:#333c4e;--pico-switch-checked-background-color:var(--pico-primary-background);--pico-switch-color:#fff;--pico-switch-thumb-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-range-border-color:#202632;--pico-range-active-border-color:#2a3140;--pico-range-thumb-border-color:var(--pico-background-color);--pico-range-thumb-color:var(--pico-secondary-background);--pico-range-thumb-active-color:var(--pico-primary-background);--pico-accordion-border-color:var(--pico-muted-border-color);--pico-accordion-active-summary-color:var(--pico-primary-hover);--pico-accordion-close-summary-color:var(--pico-color);--pico-accordion-open-summary-color:var(--pico-muted-color);--pico-card-background-color:#181c25;--pico-card-border-color:var(--pico-card-background-color);--pico-card-box-shadow:var(--pico-box-shadow);--pico-card-sectioning-background-color:rgb(26, 30.5, 40.25);--pico-loading-spinner-opacity:0.5;--pico-modal-overlay-background-color:rgba(7.5, 8.5, 10, 0.75);--pico-progress-background-color:#202632;--pico-progress-color:var(--pico-primary-background);--pico-tooltip-background-color:var(--pico-contrast-background);--pico-tooltip-color:var(--pico-contrast-inverse);--pico-icon-valid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-invalid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(149.5, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E")}[data-theme=dark] input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]){--pico-form-element-focus-color:var(--pico-primary-focus)}[type=checkbox],[type=radio],[type=range],progress{accent-color:var(--pico-primary)}*,::after,::before{box-sizing:border-box;background-repeat:no-repeat}::after,::before{text-decoration:inherit;vertical-align:inherit}:where(:host),:where(:root){-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--pico-background-color);color:var(--pico-color);font-weight:var(--pico-font-weight);font-size:var(--pico-font-size);line-height:var(--pico-line-height);font-family:var(--pico-font-family);text-underline-offset:var(--pico-text-underline-offset);text-rendering:optimizeLegibility;overflow-wrap:break-word;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{width:100%;margin:0}main{display:block}body>footer,body>header,body>main{width:100%;margin-right:auto;margin-left:auto;padding:var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal)}section{margin-bottom:var(--pico-block-spacing-vertical)}b,strong{font-weight:bolder}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}address,blockquote,dl,ol,p,pre,table,ul{margin-top:0;margin-bottom:var(--pico-typography-spacing-vertical);color:var(--pico-color);font-style:normal;font-weight:var(--pico-font-weight)}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:var(--pico-typography-spacing-vertical);color:var(--pico-color);font-weight:var(--pico-font-weight);font-size:var(--pico-font-size);line-height:var(--pico-line-height);font-family:var(--pico-font-family)}h1{--pico-color:var(--pico-h1-color)}h2{--pico-color:var(--pico-h2-color)}h3{--pico-color:var(--pico-h3-color)}h4{--pico-color:var(--pico-h4-color)}h5{--pico-color:var(--pico-h5-color)}h6{--pico-color:var(--pico-h6-color)}:where(article,address,blockquote,dl,figure,form,ol,p,pre,table,ul)~:is(h1,h2,h3,h4,h5,h6){margin-top:var(--pico-typography-spacing-top)}p{margin-bottom:var(--pico-typography-spacing-vertical)}hgroup{margin-bottom:var(--pico-typography-spacing-vertical)}hgroup>*{margin-top:0;margin-bottom:0}hgroup>:not(:first-child):last-child{--pico-color:var(--pico-muted-color);--pico-font-weight:unset;font-size:1rem}:where(ol,ul) li{margin-bottom:calc(var(--pico-typography-spacing-vertical) * .25)}:where(dl,ol,ul) :where(dl,ol,ul){margin:0;margin-top:calc(var(--pico-typography-spacing-vertical) * .25)}ul li{list-style:square}mark{padding:.125rem .25rem;background-color:var(--pico-mark-background-color);color:var(--pico-mark-color);vertical-align:baseline}blockquote{display:block;margin:var(--pico-typography-spacing-vertical) 0;padding:var(--pico-spacing);border-right:none;border-left:.25rem solid var(--pico-blockquote-border-color);border-inline-start:0.25rem solid var(--pico-blockquote-border-color);border-inline-end:none}blockquote footer{margin-top:calc(var(--pico-typography-spacing-vertical) * .5);color:var(--pico-blockquote-footer-color)}abbr[title]{border-bottom:1px dotted;text-decoration:none;cursor:help}ins{color:var(--pico-ins-color);text-decoration:none}del{color:var(--pico-del-color)}::-moz-selection{background-color:var(--pico-text-selection-color)}::selection{background-color:var(--pico-text-selection-color)}:where(a:not([role=button])),[role=link]{--pico-color:var(--pico-primary);--pico-background-color:transparent;--pico-underline:var(--pico-primary-underline);outline:0;background-color:var(--pico-background-color);color:var(--pico-color);-webkit-text-decoration:var(--pico-text-decoration);text-decoration:var(--pico-text-decoration);text-decoration-color:var(--pico-underline);text-underline-offset:0.125em;transition:background-color var(--pico-transition),color var(--pico-transition),box-shadow var(--pico-transition),-webkit-text-decoration var(--pico-transition);transition:background-color var(--pico-transition),color var(--pico-transition),text-decoration var(--pico-transition),box-shadow var(--pico-transition);transition:background-color var(--pico-transition),color var(--pico-transition),text-decoration var(--pico-transition),box-shadow var(--pico-transition),-webkit-text-decoration var(--pico-transition)}:where(a:not([role=button])):is([aria-current]:not([aria-current=false]),:hover,:active,:focus),[role=link]:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-color:var(--pico-primary-hover);--pico-underline:var(--pico-primary-hover-underline);--pico-text-decoration:underline}:where(a:not([role=button])):focus-visible,[role=link]:focus-visible{box-shadow:0 0 0 var(--pico-outline-width) var(--pico-primary-focus)}a[role=button]{display:inline-block}button{margin:0;overflow:visible;font-family:inherit;text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[role=button],[type=button],[type=file]::file-selector-button,[type=reset],[type=submit],button{--pico-background-color:var(--pico-primary-background);--pico-border-color:var(--pico-primary-border);--pico-color:var(--pico-primary-inverse);--pico-box-shadow:var(--pico-button-box-shadow, 0 0 0 rgba(0, 0, 0, 0));padding:var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal);border:var(--pico-border-width) solid var(--pico-border-color);border-radius:var(--pico-border-radius);outline:0;background-color:var(--pico-background-color);box-shadow:var(--pico-box-shadow);color:var(--pico-color);font-weight:var(--pico-font-weight);font-size:1rem;line-height:var(--pico-line-height);text-align:center;text-decoration:none;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;transition:background-color var(--pico-transition),border-color var(--pico-transition),color var(--pico-transition),box-shadow var(--pico-transition)}[role=button]:is(:hover,:active,:focus),[role=button]:is([aria-current]:not([aria-current=false])),[type=button]:is(:hover,:active,:focus),[type=button]:is([aria-current]:not([aria-current=false])),[type=file]::file-selector-button:is(:hover,:active,:focus),[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])),[type=reset]:is(:hover,:active,:focus),[type=reset]:is([aria-current]:not([aria-current=false])),[type=submit]:is(:hover,:active,:focus),[type=submit]:is([aria-current]:not([aria-current=false])),button:is(:hover,:active,:focus),button:is([aria-current]:not([aria-current=false])){--pico-background-color:var(--pico-primary-hover-background);--pico-border-color:var(--pico-primary-hover-border);--pico-box-shadow:var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0));--pico-color:var(--pico-primary-inverse)}[role=button]:focus,[role=button]:is([aria-current]:not([aria-current=false])):focus,[type=button]:focus,[type=button]:is([aria-current]:not([aria-current=false])):focus,[type=file]::file-selector-button:focus,[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus,[type=reset]:focus,[type=reset]:is([aria-current]:not([aria-current=false])):focus,[type=submit]:focus,[type=submit]:is([aria-current]:not([aria-current=false])):focus,button:focus,button:is([aria-current]:not([aria-current=false])):focus{--pico-box-shadow:var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),0 0 0 var(--pico-outline-width) var(--pico-primary-focus)}[type=button],[type=reset],[type=submit]{margin-bottom:var(--pico-spacing)}[type=file]::file-selector-button,[type=reset]{--pico-background-color:var(--pico-secondary-background);--pico-border-color:var(--pico-secondary-border);--pico-color:var(--pico-secondary-inverse);cursor:pointer}[type=file]::file-selector-button:is([aria-current]:not([aria-current=false]),:hover,:active,:focus),[type=reset]:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-background-color:var(--pico-secondary-hover-background);--pico-border-color:var(--pico-secondary-hover-border);--pico-color:var(--pico-secondary-inverse)}[type=file]::file-selector-button:focus,[type=reset]:focus{--pico-box-shadow:var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),0 0 0 var(--pico-outline-width) var(--pico-secondary-focus)}:where(button,[type=submit],[type=reset],[type=button],[role=button])[disabled],:where(fieldset[disabled]) :is(button,[type=submit],[type=button],[type=reset],[role=button]){opacity:.5;pointer-events:none}:where(table){width:100%;border-collapse:collapse;border-spacing:0;text-indent:0}td,th{padding:calc(var(--pico-spacing)/ 2) var(--pico-spacing);border-bottom:var(--pico-border-width) solid var(--pico-table-border-color);background-color:var(--pico-background-color);color:var(--pico-color);font-weight:var(--pico-font-weight);text-align:left;text-align:start}tfoot td,tfoot th{border-top:var(--pico-border-width) solid var(--pico-table-border-color);border-bottom:0}table.striped tbody tr:nth-child(odd) td,table.striped tbody tr:nth-child(odd) th{background-color:var(--pico-table-row-stripped-background-color)}:where(audio,canvas,iframe,img,svg,video){vertical-align:middle}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}:where(iframe){border-style:none}img{max-width:100%;height:auto;border-style:none}:where(svg:not([fill])){fill:currentColor}svg:not(:host),svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-size:.875em;font-family:var(--pico-font-family)}pre code,pre samp{font-size:inherit;font-family:inherit}pre{-ms-overflow-style:scrollbar;overflow:auto}code,kbd,pre,samp{border-radius:var(--pico-border-radius);background:var(--pico-code-background-color);color:var(--pico-code-color);font-weight:var(--pico-font-weight);line-height:initial}code,kbd,samp{display:inline-block;padding:.375rem}pre{display:block;margin-bottom:var(--pico-spacing);overflow-x:auto}pre>code,pre>samp{display:block;padding:var(--pico-spacing);background:0 0;line-height:var(--pico-line-height)}kbd{background-color:var(--pico-code-kbd-background-color);color:var(--pico-code-kbd-color);vertical-align:baseline}figure{display:block;margin:0;padding:0}figure figcaption{padding:calc(var(--pico-spacing) * .5) 0;color:var(--pico-muted-color)}hr{height:0;margin:var(--pico-typography-spacing-vertical) 0;border:0;border-top:1px solid var(--pico-muted-border-color);color:inherit}[hidden],template{display:none!important}canvas{display:inline-block}input,optgroup,select,textarea{margin:0;font-size:1rem;line-height:var(--pico-line-height);font-family:inherit;letter-spacing:inherit}input{overflow:visible}select{text-transform:none}legend{max-width:100%;padding:0;color:inherit;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{padding:0}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}::-moz-focus-inner{padding:0;border-style:none}:-moz-focusring{outline:0}:-moz-ui-invalid{box-shadow:none}::-ms-expand{display:none}[type=file],[type=range]{padding:0;border-width:0}input:not([type=checkbox],[type=radio],[type=range]){height:calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2)}fieldset{width:100%;margin:0;margin-bottom:var(--pico-spacing);padding:0;border:0}fieldset legend,label{display:block;margin-bottom:calc(var(--pico-spacing) * .375);color:var(--pico-color);font-weight:var(--pico-form-label-font-weight,var(--pico-font-weight))}fieldset legend{margin-bottom:calc(var(--pico-spacing) * .5)}button[type=submit],input:not([type=checkbox],[type=radio]),select,textarea{width:100%}input:not([type=checkbox],[type=radio],[type=range],[type=file]),select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal)}input,select,textarea{--pico-background-color:var(--pico-form-element-background-color);--pico-border-color:var(--pico-form-element-border-color);--pico-color:var(--pico-form-element-color);--pico-box-shadow:none;border:var(--pico-border-width) solid var(--pico-border-color);border-radius:var(--pico-border-radius);outline:0;background-color:var(--pico-background-color);box-shadow:var(--pico-box-shadow);color:var(--pico-color);font-weight:var(--pico-font-weight);transition:background-color var(--pico-transition),border-color var(--pico-transition),color var(--pico-transition),box-shadow var(--pico-transition)}:where(select,textarea):not([readonly]):is(:active,:focus),input:not([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[readonly]):is(:active,:focus){--pico-background-color:var(--pico-form-element-active-background-color)}:where(select,textarea):not([readonly]):is(:active,:focus),input:not([type=submit],[type=button],[type=reset],[role=switch],[readonly]):is(:active,:focus){--pico-border-color:var(--pico-form-element-active-border-color)}:where(select,textarea):not([readonly]):focus,input:not([type=submit],[type=button],[type=reset],[type=range],[type=file],[readonly]):focus{--pico-box-shadow:0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color)}:where(fieldset[disabled]) :is(input:not([type=submit],[type=button],[type=reset]),select,textarea),input:not([type=submit],[type=button],[type=reset])[disabled],label[aria-disabled=true],select[disabled],textarea[disabled]{opacity:var(--pico-form-element-disabled-opacity);pointer-events:none}label[aria-disabled=true] input[disabled]{opacity:1}:where(input,select,textarea):not([type=checkbox],[type=radio],[type=date],[type=datetime-local],[type=month],[type=time],[type=week],[type=range])[aria-invalid]{padding-right:calc(var(--pico-form-element-spacing-horizontal) + 1.5rem)!important;padding-left:var(--pico-form-element-spacing-horizontal);padding-inline-start:var(--pico-form-element-spacing-horizontal)!important;padding-inline-end:calc(var(--pico-form-element-spacing-horizontal) + 1.5rem)!important;background-position:center right .75rem;background-size:1rem auto;background-repeat:no-repeat}:where(input,select,textarea):not([type=checkbox],[type=radio],[type=date],[type=datetime-local],[type=month],[type=time],[type=week],[type=range])[aria-invalid=false]:not(select){background-image:var(--pico-icon-valid)}:where(input,select,textarea):not([type=checkbox],[type=radio],[type=date],[type=datetime-local],[type=month],[type=time],[type=week],[type=range])[aria-invalid=true]:not(select){background-image:var(--pico-icon-invalid)}:where(input,select,textarea)[aria-invalid=false]{--pico-border-color:var(--pico-form-element-valid-border-color)}:where(input,select,textarea)[aria-invalid=false]:is(:active,:focus){--pico-border-color:var(--pico-form-element-valid-active-border-color)!important}:where(input,select,textarea)[aria-invalid=false]:is(:active,:focus):not([type=checkbox],[type=radio]){--pico-box-shadow:0 0 0 var(--pico-outline-width) var(--pico-form-element-valid-focus-color)!important}:where(input,select,textarea)[aria-invalid=true]{--pico-border-color:var(--pico-form-element-invalid-border-color)}:where(input,select,textarea)[aria-invalid=true]:is(:active,:focus){--pico-border-color:var(--pico-form-element-invalid-active-border-color)!important}:where(input,select,textarea)[aria-invalid=true]:is(:active,:focus):not([type=checkbox],[type=radio]){--pico-box-shadow:0 0 0 var(--pico-outline-width) var(--pico-form-element-invalid-focus-color)!important}[dir=rtl] :where(input,select,textarea):not([type=checkbox],[type=radio]):is([aria-invalid],[aria-invalid=true],[aria-invalid=false]){background-position:center left .75rem}input::-webkit-input-placeholder,input::placeholder,select:invalid,textarea::-webkit-input-placeholder,textarea::placeholder{color:var(--pico-form-element-placeholder-color);opacity:1}input:not([type=checkbox],[type=radio]),select,textarea{margin-bottom:var(--pico-spacing)}select::-ms-expand{border:0;background-color:transparent}select:not([multiple],[size]){padding-right:calc(var(--pico-form-element-spacing-horizontal) + 1.5rem);padding-left:var(--pico-form-element-spacing-horizontal);padding-inline-start:var(--pico-form-element-spacing-horizontal);padding-inline-end:calc(var(--pico-form-element-spacing-horizontal) + 1.5rem);background-image:var(--pico-icon-chevron);background-position:center right .75rem;background-size:1rem auto;background-repeat:no-repeat}select[multiple] option:checked{background:var(--pico-form-element-selected-background-color);color:var(--pico-form-element-color)}[dir=rtl] select:not([multiple],[size]){background-position:center left .75rem}textarea{display:block;resize:vertical}textarea[aria-invalid]{--pico-icon-height:calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2);background-position:top right .75rem!important;background-size:1rem var(--pico-icon-height)!important}:where(input,select,textarea,fieldset)+small{display:block;width:100%;margin-top:calc(var(--pico-spacing) * -.75);margin-bottom:var(--pico-spacing);color:var(--pico-muted-color)}:where(input,select,textarea,fieldset)[aria-invalid=false]+small{color:var(--pico-ins-color)}:where(input,select,textarea,fieldset)[aria-invalid=true]+small{color:var(--pico-del-color)}label>:where(input,select,textarea){margin-top:calc(var(--pico-spacing) * .25)}label:has([type=checkbox],[type=radio]){width:-moz-fit-content;width:fit-content;cursor:pointer}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:1.25em;height:1.25em;margin-top:-.125em;margin-inline-end:.5em;border-width:var(--pico-border-width);vertical-align:middle;cursor:pointer}[type=checkbox]::-ms-check,[type=radio]::-ms-check{display:none}[type=checkbox]:checked,[type=checkbox]:checked:active,[type=checkbox]:checked:focus,[type=radio]:checked,[type=radio]:checked:active,[type=radio]:checked:focus{--pico-background-color:var(--pico-primary-background);--pico-border-color:var(--pico-primary-border);background-image:var(--pico-icon-checkbox);background-position:center;background-size:.75em auto;background-repeat:no-repeat}[type=checkbox]~label,[type=radio]~label{display:inline-block;margin-bottom:0;cursor:pointer}[type=checkbox]~label:not(:last-of-type),[type=radio]~label:not(:last-of-type){margin-inline-end:1em}[type=checkbox]:indeterminate{--pico-background-color:var(--pico-primary-background);--pico-border-color:var(--pico-primary-border);background-image:var(--pico-icon-minus);background-position:center;background-size:.75em auto;background-repeat:no-repeat}[type=radio]{border-radius:50%}[type=radio]:checked,[type=radio]:checked:active,[type=radio]:checked:focus{--pico-background-color:var(--pico-primary-inverse);border-width:.35em;background-image:none}[type=checkbox][role=switch]{--pico-background-color:var(--pico-switch-background-color);--pico-color:var(--pico-switch-color);width:2.25em;height:1.25em;border:var(--pico-border-width) solid var(--pico-border-color);border-radius:1.25em;background-color:var(--pico-background-color);line-height:1.25em}[type=checkbox][role=switch]:not([aria-invalid]){--pico-border-color:var(--pico-switch-background-color)}[type=checkbox][role=switch]:before{display:block;aspect-ratio:1;height:100%;border-radius:50%;background-color:var(--pico-color);box-shadow:var(--pico-switch-thumb-box-shadow);content:"";transition:margin .1s ease-in-out}[type=checkbox][role=switch]:focus{--pico-background-color:var(--pico-switch-background-color);--pico-border-color:var(--pico-switch-background-color)}[type=checkbox][role=switch]:checked{--pico-background-color:var(--pico-switch-checked-background-color);--pico-border-color:var(--pico-switch-checked-background-color);background-image:none}[type=checkbox][role=switch]:checked::before{margin-inline-start:calc(2.25em - 1.25em)}[type=checkbox][role=switch][disabled]{--pico-background-color:var(--pico-border-color)}[type=checkbox][aria-invalid=false]:checked,[type=checkbox][aria-invalid=false]:checked:active,[type=checkbox][aria-invalid=false]:checked:focus,[type=checkbox][role=switch][aria-invalid=false]:checked,[type=checkbox][role=switch][aria-invalid=false]:checked:active,[type=checkbox][role=switch][aria-invalid=false]:checked:focus{--pico-background-color:var(--pico-form-element-valid-border-color)}[type=checkbox]:checked:active[aria-invalid=true],[type=checkbox]:checked:focus[aria-invalid=true],[type=checkbox]:checked[aria-invalid=true],[type=checkbox][role=switch]:checked:active[aria-invalid=true],[type=checkbox][role=switch]:checked:focus[aria-invalid=true],[type=checkbox][role=switch]:checked[aria-invalid=true]{--pico-background-color:var(--pico-form-element-invalid-border-color)}[type=checkbox][aria-invalid=false]:checked,[type=checkbox][aria-invalid=false]:checked:active,[type=checkbox][aria-invalid=false]:checked:focus,[type=checkbox][role=switch][aria-invalid=false]:checked,[type=checkbox][role=switch][aria-invalid=false]:checked:active,[type=checkbox][role=switch][aria-invalid=false]:checked:focus,[type=radio][aria-invalid=false]:checked,[type=radio][aria-invalid=false]:checked:active,[type=radio][aria-invalid=false]:checked:focus{--pico-border-color:var(--pico-form-element-valid-border-color)}[type=checkbox]:checked:active[aria-invalid=true],[type=checkbox]:checked:focus[aria-invalid=true],[type=checkbox]:checked[aria-invalid=true],[type=checkbox][role=switch]:checked:active[aria-invalid=true],[type=checkbox][role=switch]:checked:focus[aria-invalid=true],[type=checkbox][role=switch]:checked[aria-invalid=true],[type=radio]:checked:active[aria-invalid=true],[type=radio]:checked:focus[aria-invalid=true],[type=radio]:checked[aria-invalid=true]{--pico-border-color:var(--pico-form-element-invalid-border-color)}[type=color]::-webkit-color-swatch-wrapper{padding:0}[type=color]::-moz-focus-inner{padding:0}[type=color]::-webkit-color-swatch{border:0;border-radius:calc(var(--pico-border-radius) * .5)}[type=color]::-moz-color-swatch{border:0;border-radius:calc(var(--pico-border-radius) * .5)}input:not([type=checkbox],[type=radio],[type=range],[type=file]):is([type=date],[type=datetime-local],[type=month],[type=time],[type=week]){--pico-icon-position:0.75rem;--pico-icon-width:1rem;padding-right:calc(var(--pico-icon-width) + var(--pico-icon-position));background-image:var(--pico-icon-date);background-position:center right var(--pico-icon-position);background-size:var(--pico-icon-width) auto;background-repeat:no-repeat}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=time]{background-image:var(--pico-icon-time)}[type=date]::-webkit-calendar-picker-indicator,[type=datetime-local]::-webkit-calendar-picker-indicator,[type=month]::-webkit-calendar-picker-indicator,[type=time]::-webkit-calendar-picker-indicator,[type=week]::-webkit-calendar-picker-indicator{width:var(--pico-icon-width);margin-right:calc(var(--pico-icon-width) * -1);margin-left:var(--pico-icon-position);opacity:0}@-moz-document url-prefix(){[type=date],[type=datetime-local],[type=month],[type=time],[type=week]{padding-right:var(--pico-form-element-spacing-horizontal)!important;background-image:none!important}}[dir=rtl] :is([type=date],[type=datetime-local],[type=month],[type=time],[type=week]){text-align:right}[type=file]{--pico-color:var(--pico-muted-color);margin-left:calc(var(--pico-outline-width) * -1);padding:calc(var(--pico-form-element-spacing-vertical) * .5) 0;padding-left:var(--pico-outline-width);border:0;border-radius:0;background:0 0}[type=file]::file-selector-button{margin-right:calc(var(--pico-spacing)/ 2);padding:calc(var(--pico-form-element-spacing-vertical) * .5) var(--pico-form-element-spacing-horizontal)}[type=file]:is(:hover,:active,:focus)::file-selector-button{--pico-background-color:var(--pico-secondary-hover-background);--pico-border-color:var(--pico-secondary-hover-border)}[type=file]:focus::file-selector-button{--pico-box-shadow:var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),0 0 0 var(--pico-outline-width) var(--pico-secondary-focus)}[type=range]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;height:1.25rem;background:0 0}[type=range]::-webkit-slider-runnable-track{width:100%;height:.375rem;border-radius:var(--pico-border-radius);background-color:var(--pico-range-border-color);-webkit-transition:background-color var(--pico-transition),box-shadow var(--pico-transition);transition:background-color var(--pico-transition),box-shadow var(--pico-transition)}[type=range]::-moz-range-track{width:100%;height:.375rem;border-radius:var(--pico-border-radius);background-color:var(--pico-range-border-color);-moz-transition:background-color var(--pico-transition),box-shadow var(--pico-transition);transition:background-color var(--pico-transition),box-shadow var(--pico-transition)}[type=range]::-ms-track{width:100%;height:.375rem;border-radius:var(--pico-border-radius);background-color:var(--pico-range-border-color);-ms-transition:background-color var(--pico-transition),box-shadow var(--pico-transition);transition:background-color var(--pico-transition),box-shadow var(--pico-transition)}[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:1.25rem;height:1.25rem;margin-top:-.4375rem;border:2px solid var(--pico-range-thumb-border-color);border-radius:50%;background-color:var(--pico-range-thumb-color);cursor:pointer;-webkit-transition:background-color var(--pico-transition),transform var(--pico-transition);transition:background-color var(--pico-transition),transform var(--pico-transition)}[type=range]::-moz-range-thumb{-webkit-appearance:none;width:1.25rem;height:1.25rem;margin-top:-.4375rem;border:2px solid var(--pico-range-thumb-border-color);border-radius:50%;background-color:var(--pico-range-thumb-color);cursor:pointer;-moz-transition:background-color var(--pico-transition),transform var(--pico-transition);transition:background-color var(--pico-transition),transform var(--pico-transition)}[type=range]::-ms-thumb{-webkit-appearance:none;width:1.25rem;height:1.25rem;margin-top:-.4375rem;border:2px solid var(--pico-range-thumb-border-color);border-radius:50%;background-color:var(--pico-range-thumb-color);cursor:pointer;-ms-transition:background-color var(--pico-transition),transform var(--pico-transition);transition:background-color var(--pico-transition),transform var(--pico-transition)}[type=range]:active,[type=range]:focus-within{--pico-range-border-color:var(--pico-range-active-border-color);--pico-range-thumb-color:var(--pico-range-thumb-active-color)}[type=range]:active::-webkit-slider-thumb{transform:scale(1.25)}[type=range]:active::-moz-range-thumb{transform:scale(1.25)}[type=range]:active::-ms-thumb{transform:scale(1.25)}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search]{padding-inline-start:calc(var(--pico-form-element-spacing-horizontal) + 1.75rem);background-image:var(--pico-icon-search);background-position:center left calc(var(--pico-form-element-spacing-horizontal) + .125rem);background-size:1rem auto;background-repeat:no-repeat}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid]{padding-inline-start:calc(var(--pico-form-element-spacing-horizontal) + 1.75rem)!important;background-position:center left 1.125rem,center right .75rem}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid=false]{background-image:var(--pico-icon-search),var(--pico-icon-valid)}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid=true]{background-image:var(--pico-icon-search),var(--pico-icon-invalid)}[dir=rtl] :where(input):not([type=checkbox],[type=radio],[type=range],[type=file])[type=search]{background-position:center right 1.125rem}[dir=rtl] :where(input):not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid]{background-position:center right 1.125rem,center left .75rem}details{display:block;margin-bottom:var(--pico-spacing)}details summary{line-height:1rem;list-style-type:none;cursor:pointer;transition:color var(--pico-transition)}details summary:not([role]){color:var(--pico-accordion-close-summary-color)}details summary::-webkit-details-marker{display:none}details summary::marker{display:none}details summary::-moz-list-bullet{list-style-type:none}details summary::after{display:block;width:1rem;height:1rem;margin-inline-start:calc(var(--pico-spacing,1rem) * .5);float:right;transform:rotate(-90deg);background-image:var(--pico-icon-chevron);background-position:right center;background-size:1rem auto;background-repeat:no-repeat;content:"";transition:transform var(--pico-transition)}details summary:focus{outline:0}details summary:focus:not([role]){color:var(--pico-accordion-active-summary-color)}details summary:focus-visible:not([role]){outline:var(--pico-outline-width) solid var(--pico-primary-focus);outline-offset:calc(var(--pico-spacing,1rem) * 0.5);color:var(--pico-primary)}details summary[role=button]{width:100%;text-align:left}details summary[role=button]::after{height:calc(1rem * var(--pico-line-height,1.5))}details[open]>summary{margin-bottom:var(--pico-spacing)}details[open]>summary:not([role]):not(:focus){color:var(--pico-accordion-open-summary-color)}details[open]>summary::after{transform:rotate(0)}[dir=rtl] details summary{text-align:right}[dir=rtl] details summary::after{float:left;background-position:left center}article{margin-bottom:var(--pico-block-spacing-vertical);padding:var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal);border-radius:var(--pico-border-radius);background:var(--pico-card-background-color);box-shadow:var(--pico-card-box-shadow)}article>footer,article>header{margin-right:calc(var(--pico-block-spacing-horizontal) * -1);margin-left:calc(var(--pico-block-spacing-horizontal) * -1);padding:calc(var(--pico-block-spacing-vertical) * .66) var(--pico-block-spacing-horizontal);background-color:var(--pico-card-sectioning-background-color)}article>header{margin-top:calc(var(--pico-block-spacing-vertical) * -1);margin-bottom:var(--pico-block-spacing-vertical);border-bottom:var(--pico-border-width) solid var(--pico-card-border-color);border-top-right-radius:var(--pico-border-radius);border-top-left-radius:var(--pico-border-radius)}article>footer{margin-top:var(--pico-block-spacing-vertical);margin-bottom:calc(var(--pico-block-spacing-vertical) * -1);border-top:var(--pico-border-width) solid var(--pico-card-border-color);border-bottom-right-radius:var(--pico-border-radius);border-bottom-left-radius:var(--pico-border-radius)}[role=group],[role=search]{display:inline-flex;position:relative;width:100%;margin-bottom:var(--pico-spacing);border-radius:var(--pico-border-radius);box-shadow:var(--pico-group-box-shadow,0 0 0 transparent);vertical-align:middle;transition:box-shadow var(--pico-transition)}[role=group] input:not([type=checkbox],[type=radio]),[role=group] select,[role=group]>*,[role=search] input:not([type=checkbox],[type=radio]),[role=search] select,[role=search]>*{position:relative;flex:1 1 auto;margin-bottom:0}[role=group] input:not([type=checkbox],[type=radio]):not(:first-child),[role=group] select:not(:first-child),[role=group]>:not(:first-child),[role=search] input:not([type=checkbox],[type=radio]):not(:first-child),[role=search] select:not(:first-child),[role=search]>:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}[role=group] input:not([type=checkbox],[type=radio]):not(:last-child),[role=group] select:not(:last-child),[role=group]>:not(:last-child),[role=search] input:not([type=checkbox],[type=radio]):not(:last-child),[role=search] select:not(:last-child),[role=search]>:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}[role=group] input:not([type=checkbox],[type=radio]):focus,[role=group] select:focus,[role=group]>:focus,[role=search] input:not([type=checkbox],[type=radio]):focus,[role=search] select:focus,[role=search]>:focus{z-index:2}[role=group] [role=button]:not(:first-child),[role=group] [type=button]:not(:first-child),[role=group] [type=reset]:not(:first-child),[role=group] [type=submit]:not(:first-child),[role=group] button:not(:first-child),[role=group] input:not([type=checkbox],[type=radio]):not(:first-child),[role=group] select:not(:first-child),[role=search] [role=button]:not(:first-child),[role=search] [type=button]:not(:first-child),[role=search] [type=reset]:not(:first-child),[role=search] [type=submit]:not(:first-child),[role=search] button:not(:first-child),[role=search] input:not([type=checkbox],[type=radio]):not(:first-child),[role=search] select:not(:first-child){margin-left:calc(var(--pico-border-width) * -1)}[role=group] [role=button],[role=group] [type=button],[role=group] [type=reset],[role=group] [type=submit],[role=group] button,[role=search] [role=button],[role=search] [type=button],[role=search] [type=reset],[role=search] [type=submit],[role=search] button{width:auto}@supports selector(:has(*)){[role=group]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus),[role=search]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus){--pico-group-box-shadow:var(--pico-group-box-shadow-focus-with-button)}[role=group]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus) input:not([type=checkbox],[type=radio]),[role=group]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus) select,[role=search]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus) input:not([type=checkbox],[type=radio]),[role=search]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus) select{border-color:transparent}[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus),[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus){--pico-group-box-shadow:var(--pico-group-box-shadow-focus-with-input)}[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus) [role=button],[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus) [type=button],[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus) [type=submit],[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus) button,[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus) [role=button],[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus) [type=button],[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus) [type=submit],[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus) button{--pico-button-box-shadow:0 0 0 var(--pico-border-width) var(--pico-primary-border);--pico-button-hover-box-shadow:0 0 0 var(--pico-border-width) var(--pico-primary-hover-border)}[role=group] [role=button]:focus,[role=group] [type=button]:focus,[role=group] [type=reset]:focus,[role=group] [type=submit]:focus,[role=group] button:focus,[role=search] [role=button]:focus,[role=search] [type=button]:focus,[role=search] [type=reset]:focus,[role=search] [type=submit]:focus,[role=search] button:focus{box-shadow:none}}[role=search]>:first-child{border-top-left-radius:5rem;border-bottom-left-radius:5rem}[role=search]>:last-child{border-top-right-radius:5rem;border-bottom-right-radius:5rem}[aria-busy=true]:not(input,select,textarea,html,form){white-space:nowrap}[aria-busy=true]:not(input,select,textarea,html,form)::before{display:inline-block;width:1em;height:1em;background-image:var(--pico-icon-loading);background-size:1em auto;background-repeat:no-repeat;content:"";vertical-align:-.125em}[aria-busy=true]:not(input,select,textarea,html,form):not(:empty)::before{margin-inline-end:calc(var(--pico-spacing) * .5)}[aria-busy=true]:not(input,select,textarea,html,form):empty{text-align:center}[role=button][aria-busy=true],[type=button][aria-busy=true],[type=reset][aria-busy=true],[type=submit][aria-busy=true],a[aria-busy=true],button[aria-busy=true]{pointer-events:none}:host,:root{--pico-scrollbar-width:0px}dialog{display:flex;z-index:999;position:fixed;top:0;right:0;bottom:0;left:0;align-items:center;justify-content:center;width:inherit;min-width:100%;height:inherit;min-height:100%;padding:0;border:0;-webkit-backdrop-filter:var(--pico-modal-overlay-backdrop-filter);backdrop-filter:var(--pico-modal-overlay-backdrop-filter);background-color:var(--pico-modal-overlay-background-color);color:var(--pico-color)}dialog>article{width:100%;max-height:calc(100vh - var(--pico-spacing) * 2);margin:var(--pico-spacing);overflow:auto}@media (min-width:576px){dialog>article{max-width:510px}}@media (min-width:768px){dialog>article{max-width:700px}}dialog>article>header>*{margin-bottom:0}dialog>article>header :is(a,button)[rel=prev]{margin:0;margin-left:var(--pico-spacing);padding:0;float:right}dialog>article>footer{text-align:right}dialog>article>footer [role=button],dialog>article>footer button{margin-bottom:0}dialog>article>footer [role=button]:not(:first-of-type),dialog>article>footer button:not(:first-of-type){margin-left:calc(var(--pico-spacing) * .5)}dialog>article :is(a,button)[rel=prev]{display:block;width:1rem;height:1rem;margin-top:calc(var(--pico-spacing) * -1);margin-bottom:var(--pico-spacing);margin-left:auto;border:none;background-image:var(--pico-icon-close);background-position:center;background-size:auto 1rem;background-repeat:no-repeat;background-color:transparent;opacity:.5;transition:opacity var(--pico-transition)}dialog>article :is(a,button)[rel=prev]:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){opacity:1}dialog:not([open]),dialog[open=false]{display:none}:where(nav li)::before{float:left;content:""}nav,nav ul{display:flex}nav{justify-content:space-between;overflow:visible}nav ol,nav ul{align-items:center;margin-bottom:0;padding:0;list-style:none}nav ol:first-of-type,nav ul:first-of-type{margin-left:calc(var(--pico-nav-element-spacing-horizontal) * -1)}nav ol:last-of-type,nav ul:last-of-type{margin-right:calc(var(--pico-nav-element-spacing-horizontal) * -1)}nav li{display:inline-block;margin:0;padding:var(--pico-nav-element-spacing-vertical) var(--pico-nav-element-spacing-horizontal)}nav li :where(a,[role=link]){display:inline-block;margin:calc(var(--pico-nav-link-spacing-vertical) * -1) calc(var(--pico-nav-link-spacing-horizontal) * -1);padding:var(--pico-nav-link-spacing-vertical) var(--pico-nav-link-spacing-horizontal);border-radius:var(--pico-border-radius)}nav li :where(a,[role=link]):not(:hover){text-decoration:none}nav li [role=button],nav li [type=button],nav li button,nav li input:not([type=checkbox],[type=radio],[type=range],[type=file]),nav li select{height:auto;margin-right:inherit;margin-bottom:0;margin-left:inherit;padding:calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal)}nav[aria-label=breadcrumb]{align-items:center;justify-content:start}nav[aria-label=breadcrumb] ul li:not(:first-child){margin-inline-start:var(--pico-nav-link-spacing-horizontal)}nav[aria-label=breadcrumb] ul li a{margin:calc(var(--pico-nav-link-spacing-vertical) * -1) 0;margin-inline-start:calc(var(--pico-nav-link-spacing-horizontal) * -1)}nav[aria-label=breadcrumb] ul li:not(:last-child)::after{display:inline-block;position:absolute;width:calc(var(--pico-nav-link-spacing-horizontal) * 4);margin:0 calc(var(--pico-nav-link-spacing-horizontal) * -1);content:var(--pico-nav-breadcrumb-divider);color:var(--pico-muted-color);text-align:center;text-decoration:none;white-space:nowrap}nav[aria-label=breadcrumb] a[aria-current]:not([aria-current=false]){background-color:transparent;color:inherit;text-decoration:none;pointer-events:none}aside li,aside nav,aside ol,aside ul{display:block}aside li{padding:calc(var(--pico-nav-element-spacing-vertical) * .5) var(--pico-nav-element-spacing-horizontal)}aside li a{display:block}aside li [role=button]{margin:inherit}[dir=rtl] nav[aria-label=breadcrumb] ul li:not(:last-child) ::after{content:"\\"}progress{display:inline-block;vertical-align:baseline}progress{-webkit-appearance:none;-moz-appearance:none;display:inline-block;appearance:none;width:100%;height:.5rem;margin-bottom:calc(var(--pico-spacing) * .5);overflow:hidden;border:0;border-radius:var(--pico-border-radius);background-color:var(--pico-progress-background-color);color:var(--pico-progress-color)}progress::-webkit-progress-bar{border-radius:var(--pico-border-radius);background:0 0}progress[value]::-webkit-progress-value{background-color:var(--pico-progress-color);-webkit-transition:inline-size var(--pico-transition);transition:inline-size var(--pico-transition)}progress::-moz-progress-bar{background-color:var(--pico-progress-color)}@media (prefers-reduced-motion:no-preference){progress:indeterminate{background:var(--pico-progress-background-color) linear-gradient(to right,var(--pico-progress-color) 30%,var(--pico-progress-background-color) 30%) top left/150% 150% no-repeat;animation:progress-indeterminate 1s linear infinite}progress:indeterminate[value]::-webkit-progress-value{background-color:transparent}progress:indeterminate::-moz-progress-bar{background-color:transparent}}@media (prefers-reduced-motion:no-preference){[dir=rtl] progress:indeterminate{animation-direction:reverse}}@keyframes progress-indeterminate{0%{background-position:200% 0}100%{background-position:-200% 0}}[data-tooltip]{position:relative}[data-tooltip]:not(a,button,input,[role=button]){border-bottom:1px dotted;text-decoration:none;cursor:help}[data-tooltip]::after,[data-tooltip]::before,[data-tooltip][data-placement=top]::after,[data-tooltip][data-placement=top]::before{display:block;z-index:99;position:absolute;bottom:100%;left:50%;padding:.25rem .5rem;overflow:hidden;transform:translate(-50%,-.25rem);border-radius:var(--pico-border-radius);background:var(--pico-tooltip-background-color);content:attr(data-tooltip);color:var(--pico-tooltip-color);font-style:normal;font-weight:var(--pico-font-weight);font-size:.875rem;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;opacity:0;pointer-events:none}[data-tooltip]::after,[data-tooltip][data-placement=top]::after{padding:0;transform:translate(-50%,0);border-top:.3rem solid;border-right:.3rem solid transparent;border-left:.3rem solid transparent;border-radius:0;background-color:transparent;content:"";color:var(--pico-tooltip-background-color)}[data-tooltip][data-placement=bottom]::after,[data-tooltip][data-placement=bottom]::before{top:100%;bottom:auto;transform:translate(-50%,.25rem)}[data-tooltip][data-placement=bottom]:after{transform:translate(-50%,-.3rem);border:.3rem solid transparent;border-bottom:.3rem solid}[data-tooltip][data-placement=left]::after,[data-tooltip][data-placement=left]::before{top:50%;right:100%;bottom:auto;left:auto;transform:translate(-.25rem,-50%)}[data-tooltip][data-placement=left]:after{transform:translate(.3rem,-50%);border:.3rem solid transparent;border-left:.3rem solid}[data-tooltip][data-placement=right]::after,[data-tooltip][data-placement=right]::before{top:50%;right:auto;bottom:auto;left:100%;transform:translate(.25rem,-50%)}[data-tooltip][data-placement=right]:after{transform:translate(-.3rem,-50%);border:.3rem solid transparent;border-right:.3rem solid}[data-tooltip]:focus::after,[data-tooltip]:focus::before,[data-tooltip]:hover::after,[data-tooltip]:hover::before{opacity:1}@media (hover:hover) and (pointer:fine){[data-tooltip]:focus::after,[data-tooltip]:focus::before,[data-tooltip]:hover::after,[data-tooltip]:hover::before{--pico-tooltip-slide-to:translate(-50%, -0.25rem);transform:translate(-50%,.75rem);animation-duration:.2s;animation-fill-mode:forwards;animation-name:tooltip-slide;opacity:0}[data-tooltip]:focus::after,[data-tooltip]:hover::after{--pico-tooltip-caret-slide-to:translate(-50%, 0rem);transform:translate(-50%,-.25rem);animation-name:tooltip-caret-slide}[data-tooltip][data-placement=bottom]:focus::after,[data-tooltip][data-placement=bottom]:focus::before,[data-tooltip][data-placement=bottom]:hover::after,[data-tooltip][data-placement=bottom]:hover::before{--pico-tooltip-slide-to:translate(-50%, 0.25rem);transform:translate(-50%,-.75rem);animation-name:tooltip-slide}[data-tooltip][data-placement=bottom]:focus::after,[data-tooltip][data-placement=bottom]:hover::after{--pico-tooltip-caret-slide-to:translate(-50%, -0.3rem);transform:translate(-50%,-.5rem);animation-name:tooltip-caret-slide}[data-tooltip][data-placement=left]:focus::after,[data-tooltip][data-placement=left]:focus::before,[data-tooltip][data-placement=left]:hover::after,[data-tooltip][data-placement=left]:hover::before{--pico-tooltip-slide-to:translate(-0.25rem, -50%);transform:translate(.75rem,-50%);animation-name:tooltip-slide}[data-tooltip][data-placement=left]:focus::after,[data-tooltip][data-placement=left]:hover::after{--pico-tooltip-caret-slide-to:translate(0.3rem, -50%);transform:translate(.05rem,-50%);animation-name:tooltip-caret-slide}[data-tooltip][data-placement=right]:focus::after,[data-tooltip][data-placement=right]:focus::before,[data-tooltip][data-placement=right]:hover::after,[data-tooltip][data-placement=right]:hover::before{--pico-tooltip-slide-to:translate(0.25rem, -50%);transform:translate(-.75rem,-50%);animation-name:tooltip-slide}[data-tooltip][data-placement=right]:focus::after,[data-tooltip][data-placement=right]:hover::after{--pico-tooltip-caret-slide-to:translate(-0.3rem, -50%);transform:translate(-.05rem,-50%);animation-name:tooltip-caret-slide}}@keyframes tooltip-slide{to{transform:var(--pico-tooltip-slide-to);opacity:1}}@keyframes tooltip-caret-slide{50%{opacity:0}to{transform:var(--pico-tooltip-caret-slide-to);opacity:1}}[aria-controls]{cursor:pointer}[aria-disabled=true],[disabled]{cursor:not-allowed}[aria-hidden=false][hidden]{display:initial}[aria-hidden=false][hidden]:not(:focus){clip:rect(0,0,0,0);position:absolute}[tabindex],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation}[dir=rtl]{direction:rtl}@media (prefers-reduced-motion:reduce){:not([aria-busy=true]),:not([aria-busy=true])::after,:not([aria-busy=true])::before{background-attachment:initial!important;animation-duration:1ms!important;animation-delay:-1ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-delay:0s!important;transition-duration:0s!important}}
\ No newline at end of file
diff --git a/scripts/dashboard/resources/shared-styles.css b/scripts/dashboard/resources/shared-styles.css
new file mode 100644
index 0000000..fce74f0
--- /dev/null
+++ b/scripts/dashboard/resources/shared-styles.css
@@ -0,0 +1,75 @@
+/*
+
+Shared Styles for various Pico-styled Yocto web properties within this repo:
+
+- Dashboard: https://dashboard.yoctoproject.org/
+- BugZilla Stats: https://dashboard.yoctoproject.org/bugzilla_stats.html
+- Bug Triage: https://dashboard.yoctoproject.org/bugtriage/
+- Autobuilder Issue Summary: https://valkyrie.yocto.io/pub/non-release/abint/
+ This lives in `/scripts/abint` and since it lives under a different URL, has its own copy of this file and related assets.
+
+The repo `yocto-metrics` also uses the same/similar styles for these pages:
+
+- Current CVE status for meta-openembedded: https://valkyrie.yocto.io/pub/non-release/patchmetrics-meta-oe/
+- Patchmetrics: https://valkyrie.yocto.io/pub/non-release/patchmetrics/
+
+*/
+
+html {
+ scroll-behavior: smooth;
+ scroll-padding-top: 1em;
+}
+
+main {
+ font-size: 0.9em;
+}
+
+section {
+ max-width: 55rem;
+ margin-inline: 3rem;
+}
+
+.indented {
+ margin-inline: 3rem;
+}
+
+h1.with-logo{
+ position: relative;
+ margin-inline-start: 3rem;
+}
+
+h1.with-logo::before {
+ content: "";
+ background: url(apple-touch-icon.png);
+ width: 1em;
+ height: 1em;
+ display: block;
+ background-size: contain;
+ position: absolute;
+ left: -1.5em;
+ top: 0.05em;
+ border-radius: 10%;
+}
+
+h2 {
+ padding-top: 1em;
+}
+
+.header {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: flex-start;
+ gap: 1em
+}
+
+.logo {
+ height: 2.6em;
+ border-radius: 10%;
+}
+
+.chart-container {
+ /* Apache eCharts like to have a container that already has a height */
+ height: 400px;
+ width: 100%;
+}
\ No newline at end of file
--
2.40.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [yocto-autobuilder-helper][PATCH 3/4] dashboard/bugtriage: update to unify styles with CVE/Patch Metrics pages
2026-01-28 14:02 [yocto-autobuilder-helper][PATCH 0/4] Update dashboard, Bugzilla stats, bug triage page and autobuilder issues page Alba Herrerias
2026-01-28 14:02 ` [yocto-autobuilder-helper][PATCH 1/4] dashboard: update to unify styles with CVE/Patch Metrics pages Alba Herrerias
@ 2026-01-28 14:02 ` Alba Herrerias
1 sibling, 0 replies; 3+ messages in thread
From: Alba Herrerias @ 2026-01-28 14:02 UTC (permalink / raw)
To: yocto-patches; +Cc: engineering, Alex Feyerke
From: Alex Feyerke <alex@neighbourhood.ie>
Replaced Google Material libraries with Pico.css, updated table sorting library.
Signed-off-by: Alex Feyerke <alex@neighbourhood.ie>
---
scripts/dashboard/bugtriage/index.html | 588 ++++++++++++------
scripts/dashboard/bugtriage/tablesort.min.js | 6 +
.../dashboard/bugtriage/tablesort.number.js | 26 +
3 files changed, 447 insertions(+), 173 deletions(-)
create mode 100644 scripts/dashboard/bugtriage/tablesort.min.js
create mode 100644 scripts/dashboard/bugtriage/tablesort.number.js
diff --git a/scripts/dashboard/bugtriage/index.html b/scripts/dashboard/bugtriage/index.html
index 10d998d..82ee3c3 100644
--- a/scripts/dashboard/bugtriage/index.html
+++ b/scripts/dashboard/bugtriage/index.html
@@ -5,181 +5,414 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bug Triage</title>
- <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
+ <link rel="stylesheet" href="../resources/pico.fluid.classless.min.css">
+ <link rel="stylesheet" href="../resources/shared-styles.css">
+ <link rel="apple-touch-icon" sizes="144x144" href="../resources/apple-touch-icon.png">
+ <link rel="icon" type="image/png" sizes="32x32" href="../resources/favicon-32x32.png">
+ <link rel="icon" type="image/png" sizes="16x16" href="../resources/favicon-16x16.png">
<style>
- .pin-top {
- position: relative;
+ body>main {
+ padding-block-start: 0;
}
- .pin-bottom {
- position: relative;
+ .spread {
+ display: flex;
+ justify-content: space-between;
}
- .pinned {
- position: fixed !important;
+ .content-with-sidebar {
+ display: flex;
+ flex-wrap: nowrap;
+ flex-direction: row-reverse;
}
- .table-of-contents a.active {
- border-left-color: #03a9f4;
+ .content {
+ padding-block-start: 1em;
}
- table.sortable th:not(.sorttable_sorted):not(.sorttable_sorted_reverse):not(.sorttable_nosort):after {
- content: " \25B4\25BE"
+ .sidebar {
+ border-left: 1px solid #ddd;
+ width: 20rem;
}
- </style>
-</head>
-<body>
- <nav>
- <div class="nav-wrapper light-blue" id="nav">
- <span class="brand-logo"> Yocto Project Bug Triage</span>
- <ul id="nav-mobile" class="right hide-on-med-and-down">
- <li><a href="https://bugzilla.yoctoproject.org/">Bugzilla</a></li>
- <li><a href="https://autobuilder.yoctoproject.org/">Autobuilder</a></li>
- </ul>
- </div>
- </nav>
-
- <div class="row">
- <div class="col s12 m9 l10">
- <p>
- The outcome of the bug triage meeting should be that all bugs have an
- owner, a target milestone, and a priority.
- </p>
- <p>
- The meeting is held every Thursday at 07:30 Pacific Time (typically
- 15:30 GMT or 16:30 CET, but be aware of daylight saving shifts). The
- meeting is held on <a href="https://zoom.us/">Zoom</a>, join with either the <a
- href="https://zoom.us/j/454367603?pwd=ZGxoa2ZXL3FkM3Y0bFd5aVpHVVZ6dz09">direct
- link</a> or use the Meeting ID <strong>454-367-603</strong> and password
- <strong>277925</strong>.
- </p>
- <p>
- The call facilitator is Stephen Jolley <<a
- href="mailto:sjolley.yp.pm@gmail.com">sjolley.yp.pm@gmail.com</a>>. The
- facilitator's job is to ensure the agenda is kept to, without ratholing
- on any particular bug, and keeping to the time slot.
- </p>
-
- <div class="section scrollspy" id="security-container">
- <h4>Security-related</h4>
- <p>
- <a href="https://bugzilla.yoctoproject.org/buglist.cgi?list_id=604307&resolution=---&query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ACCEPTED&bug_status=IN%20PROGRESS%20DESIGN&bug_status=IN%20PROGRESS%20DESIGN%20COMPLETE&bug_status=IN%20PROGRESS%20IMPLEMENTATION&bug_status=IN%20PROGRESS%20REVIEW&bug_status=REOPENED&bug_status=NEEDINFO&product=Security&product=Security%20-%20Recipe%20Upgrade" target="_blank">View security-related bugs in Bugzilla</a>.
- </p>
- <p>
- Security issues a need to be viewed directly in Bugzilla as they are
- only visible to users with sufficient permissions.
- </p>
- </div>
+ tr td:nth-child(2) {
+ word-break: break-word;
+ }
- <div class="section scrollspy" id="unprioritised-container">
- <h4>Unprioritised <a class="waves-effect btn-flat" onclick="reloadTable('#unprioritised');"><i class="material-icons">refresh</i></a></h4>
- <p>
- Bugs without a priority, that need a priority, target milestone, and owner assigned.
- </p>
- <div id="unprioritised"></div>
- </div>
+ #table-of-contents {
+ position: fixed;
+ margin: 0.5em 1em;
+ }
- <div class="section scrollspy" id="high-container">
- <h4>High <a class="waves-effect btn-flat" onclick="reloadTable('#high');"><i class="material-icons">refresh</i></a></h4>
- <p>
- All open high-priority bugs.
- </p>
- <div id="high"></div>
- </div>
+ #table-of-contents ul {
+ padding: 0;
+ margin: 0.5em;
+ }
- <div class="section scrollspy" id="reopened-container">
- <h4>Reopened <a class="waves-effect btn-flat" onclick="reloadTable('#reopened');"><i class="material-icons">refresh</i></a></h4>
- <p>
- Bugs that have been reopened. The owner should be reviewed and the bug
- moved to another state.
- </p>
- <div id="reopened"></div>
- </div>
+ #table-of-contents li {
+ list-style: none;
+ }
- <div class="section scrollspy" id="abint-container">
- <h4>Autobuilder Intermittent <a class="waves-effect btn-flat" onclick="reloadTable('#abint');"><i class="material-icons">refresh</i></a></h4>
- <p>
- Bugs which are tagged as tracking intermittent failures on the
- autobuilder. A <a
- href="https://valkyrie.yocto.io/pub/non-release/abint/" target="_blank">graphical
- view</a> is also available.
- </p>
- <div id="abint"></div>
- </div>
+ #table-of-contents a {
+ text-decoration: none;
+ padding-inline-start: 0.5em;
+ border-left: 5px solid transparent;
+ }
- <div class="section scrollspy" id="needinfo-container">
- <h4>Need Info <a class="waves-effect btn-flat" onclick="reloadTable('#needinfo');"><i class="material-icons">refresh</i></a></h4>
- <p>
- All bugs that are in the NEEDINFO state, and should be reviewed to
- identify if the information has been provided and the bug should be
- moved to another state.
- </p>
- <div id="needinfo"></div>
- </div>
+ #table-of-contents a.active {
+ font-weight: bold;
+ border-left-color: var(--pico-primary);
+ }
- <div class="section scrollspy" id="inactivebugs-container">
- <h4>Inactive Bugs <a class="waves-effect btn-flat" onclick="reloadTable('#inactivebugs');"><i class="material-icons">refresh</i></a></h4>
- <p>
- All open bugs that haven't been altered in two years.
- </p>
- <div id="inactivebugs"></div>
- </div>
+ .bug-count {
+ padding-inline: 0.25em;
+ }
- <div class="section scrollspy" id="inactivefeatures-container">
- <h4>Inactive Enhancements <a class="waves-effect btn-flat" onclick="reloadTable('#inactivefeatures');"><i class="material-icons">refresh</i></a></h4>
- <p>
- All open enhancements that haven't been altered in two years.
- </p>
- <div id="inactivefeatures"></div>
- </div>
+ .reload-button {
+ cursor: pointer;
+ text-decoration: none;
+ font-size: 0;
+ }
- <div class="section scrollspy" id="oldmilestone-container">
- <h4>Wrong Milestone <a class="waves-effect btn-flat" onclick="reloadTable('#oldmilestone');"><i class="material-icons">refresh</i></a></h4>
- <p>
- All open bugs that are targetted for a milestone in the past: they
- should be closed if fixed, or moved to a future milestone.
- </p>
- <div id="oldmilestone"></div>
- </div>
+ .reload-button::after {
+ content: "↻";
+ font-size: 1.25rem;
+ }
- <div class="section scrollspy" id="newcomer-container">
- <h4>Potential Newcomer <a class="waves-effect btn-flat" onclick="reloadTable('#newcomer');"><i class="material-icons">refresh</i></a></h4>
- <p>
- All open bugs which have been tagged as being potentially good for
- newcomers to the project who want to make their first contribution.
- </p>
- <div id="newcomer"></div>
- </div>
+ [href="#top"] {
+ cursor: pointer;
+ text-decoration: none;
+ font-size: 1em;
+ padding-inline-end: 1em;
+ }
+
+ .table-container {
+ overflow-x: auto;
+ margin-inline-end: 0;
+ max-width: calc(100vw - 20rem);
+ }
+
+ th {
+ cursor: pointer;
+ }
+
+ th span {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: center;
+ gap: 0.5em;
+ }
+
+ th span:after {
+ content: "⏶⏷";
+ color: #111;
+ opacity: 0.25;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ th span:after {
+ color: #EEE;
+ }
+ }
+
+ th[aria-sort="ascending"] span:after {
+ content: "⏶";
+ opacity: 1;
+ }
+
+ th[aria-sort="descending"] span:after {
+ content: "⏷";
+ opacity: 1;
+ }
+
+ #nav-drawer-open,
+ #nav-drawer-close {
+ display: none;
+ cursor: pointer;
+ font-size: 2.5rem;
+ line-height: 0.9em;
+ }
- <div class="section scrollspy" id="retest-container">
- <h4>Needs Testing <a class="waves-effect btn-flat" onclick="reloadTable('#retest');"><i class="material-icons">refresh</i></a></h4>
- <p>
- All open bugs which have been tagged as needing to be retested.
- </p>
- <div id="retest"></div>
+ #nav-drawer-open {
+ margin-inline-end: 0.75em;
+ }
+
+ #nav-drawer-close {
+ width: 100%;
+ text-align: right;
+ margin-top: 0.35em;
+ padding-inline-end: 0.4em;
+ }
+
+ @media (max-width: 1024px) {
+ body>main {
+ padding-right: 0;
+ }
+ #nav-drawer-open,
+ #nav-drawer-close {
+ display: block;
+ }
+ .spread {
+ display: flex;
+ justify-content: space-between;
+ position: sticky;
+ }
+ body.show-nav .sidebar{
+ transform: translateX(0em);
+ }
+ .sidebar {
+ display: block;
+ position: fixed;
+ background: white;
+ height: 100vh;
+ z-index: 1;
+ transform: translateX(22em);
+ width: auto;
+ transition: all 0.5s;
+ overflow-y: auto;
+ }
+ #table-of-contents {
+ position: relative;
+ margin-bottom: 2em;
+ }
+ section {
+ margin-inline: 0;
+ }
+ .table-container {
+ max-width: 95vw;
+ }
+ }
+ </style>
+</head>
+
+<body>
+ <main>
+ <div class="content-with-sidebar">
+ <div class="sidebar">
+ <div id="table-of-contents">
+ <div id="nav-drawer-close">×</div>
+ <ul>
+ <li>Navigation:</li>
+ <li><a href="/">Yocto Dashboard</a></li>
+ <li><a href="https://bugzilla.yoctoproject.org/">Bugzilla</a></li>
+ <li><a href="https://autobuilder.yoctoproject.org/">Autobuilder</a></li>
+ <li>Bug Categories:</li>
+ <li><a href="#security-container">Security<span class="bug-count"></span></a></li>
+ <li><a href="#unprioritised-container">Unprioritised<span class="bug-count"></span></a></li>
+ <li><a href="#high-container">High<span class="bug-count"></span></a></li>
+ <li><a href="#reopened-container">Reopened<span class="bug-count"></span></a></li>
+ <li><a href="#abint-container">AB-INT<span class="bug-count"></span></a></li>
+ <li><a href="#needinfo-container">Need Info<span class="bug-count"></span></a></li>
+ <li><a href="#inactivebugs-container">Old Bugs<span class="bug-count"></span></a></li>
+ <li><a href="#inactivefeatures-container">Old Features<span class="bug-count"></span></a></li>
+ <li><a href="#oldmilestone-container">Wrong Milestone<span class="bug-count"></span></a></li>
+ <li><a href="#newcomer-container">Newcomer<span class="bug-count"></span></a></li>
+ <li><a href="#retest-container">Retest<span class="bug-count"></span></a></li>
+ </ul>
+ </div>
+ </div>
+ <div class="content">
+ <div class="spread">
+ <h1 id="top" class="with-logo">Yocto Project Bug Triage</h1>
+ <div id="nav-drawer-open">≡</div>
+ </div>
+ <section>
+ <p>
+ The outcome of the bug triage meeting should be that all bugs have an
+ owner, a target milestone, and a priority.
+ </p>
+ <p>
+ The meeting is held every Thursday at 07:30 Pacific Time (typically
+ 15:30 GMT or 16:30 CET, but be aware of daylight saving shifts). The
+ meeting is held on <a href="https://zoom.us/">Zoom</a>, join with either the <a href="https://zoom.us/j/454367603?pwd=ZGxoa2ZXL3FkM3Y0bFd5aVpHVVZ6dz09">direct
+ link</a> or use the Meeting ID <strong>454-367-603</strong> and password
+ <strong>277925</strong>.
+ </p>
+ <p>
+ The call facilitator is Stephen Jolley <<a href="mailto:sjolley.yp.pm@gmail.com">sjolley.yp.pm@gmail.com</a>>. The
+ facilitator's job is to ensure the agenda is kept to, without ratholing
+ on any particular bug, and keeping to the time slot.
+ </p>
+ </section>
+ <section id="security-container" class="table-container">
+ <h4>Security-related</h4>
+ <p>
+ <a href="https://bugzilla.yoctoproject.org/buglist.cgi?list_id=604307&resolution=---&query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ACCEPTED&bug_status=IN%20PROGRESS%20DESIGN&bug_status=IN%20PROGRESS%20DESIGN%20COMPLETE&bug_status=IN%20PROGRESS%20IMPLEMENTATION&bug_status=IN%20PROGRESS%20REVIEW&bug_status=REOPENED&bug_status=NEEDINFO&product=Security&product=Security%20-%20Recipe%20Upgrade" target="_blank">View security-related bugs in Bugzilla</a>.
+ </p>
+ <p>
+ Security issues a need to be viewed directly in Bugzilla as they are
+ only visible to users with sufficient permissions.
+ </p>
+ </section>
+
+ <section id="unprioritised-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>Unprioritised<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#unprioritised');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ Bugs without a priority, that need a priority, target milestone, and owner assigned.
+ </p>
+ <div id="unprioritised"></div>
+ </section>
+
+ <section id="high-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>High<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#high');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ All open high-priority bugs.
+ </p>
+ <div id="high"></div>
+ </section>
+
+ <section id="reopened-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>Reopened<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#reopened');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ Bugs that have been reopened. The owner should be reviewed and the bug
+ moved to another state.
+ </p>
+ <div id="reopened"></div>
+ </section>
+
+ <section id="abint-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>Autobuilder Intermittent<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#abint');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ Bugs which are tagged as tracking intermittent failures on the
+ autobuilder. A <a href="https://valkyrie.yocto.io/pub/non-release/abint/" target="_blank">graphical
+ view</a> is also available.
+ </p>
+ <div id="abint"></div>
+ </section>
+
+ <section id="needinfo-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>Need Info<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#needinfo');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ All bugs that are in the NEEDINFO state, and should be reviewed to
+ identify if the information has been provided and the bug should be
+ moved to another state.
+ </p>
+ <div id="needinfo"></div>
+ </section>
+
+ <section id="inactivebugs-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>Inactive Bugs<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#inactivebugs');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ All open bugs that haven't been altered in two years.
+ </p>
+ <div id="inactivebugs"></div>
+ </section>
+
+ <section id="inactivefeatures-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>Inactive Enhancements<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#inactivefeatures');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ All open enhancements that haven't been altered in two years.
+ </p>
+ <div id="inactivefeatures"></div>
+ </section>
+
+ <section id="oldmilestone-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>Wrong Milestone<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#oldmilestone');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ All open bugs that are targetted for a milestone in the past: they
+ should be closed if fixed, or moved to a future milestone.
+ </p>
+ <div id="oldmilestone"></div>
+ </section>
+
+ <section id="newcomer-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>Potential Newcomer<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#newcomer');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ All open bugs which have been tagged as being potentially good for
+ newcomers to the project who want to make their first contribution.
+ </p>
+ <div id="newcomer"></div>
+ </section>
+
+ <section id="retest-container" class="table-container">
+ <span class="spread">
+ <span>
+ <h4>Needs Testing<span class="bug-count"></span><a class="reload-button" onclick="reloadTable('#retest');">Reload Bugs</a></h4>
+ </span>
+ <a href="#top">Back to top ⏶</a>
+ </span>
+ <p>
+ All open bugs which have been tagged as needing to be retested.
+ </p>
+ <div id="retest"></div>
+ </section>
</div>
</div>
- <div class="col hide-on-small-only m3 l2">
- <ul class="section table-of-contents pushpin">
- <li><a href="#security-container">Security</a></li>
- <li><a href="#unprioritised-container">Unprioritised</a></li>
- <li><a href="#high-container">High</a></li>
- <li><a href="#reopened-container">Reopened</a></li>
- <li><a href="#abint-container">AB-INT</a></li>
- <li><a href="#needinfo-container">Need Info</a></li>
- <li><a href="#inactivebugs-container">Old Bugs</a></li>
- <li><a href="#inactivefeatures-container">Old Features</a></li>
- <li><a href="#oldmilestone-container">Wrong Milestone</a></li>
- <li><a href="#newcomer-container">Newcomer</a></li>
- <li><a href="#retest-container">Retest</a></li>
- </ul>
- </div>
- </div>
- </div>
- <script src="sorttable.js"></script>
+ </main>
+ <script src="tablesort.min.js"></script>
+ <script src="tablesort.number.js"></script>
+ <script type="text/javascript">
+ // highlight nav items
+ navigation.addEventListener("navigate", (event) => {
+ // Unhighlight any highlighted link
+ document.querySelector('a.active')?.classList.remove("active");
+ // If we’ve navigated to an anchor, highlight the corresponding link(s)
+ const url = new URL(event.destination.url);
+ if (url.hash) {
+ document.querySelector(`[href="${url.hash}"]`)?.classList.add("active");
+ }
+ })
+ </script>
+ <script type="text/javascript">
+ // Handle toggle of nav drawer
+ document.querySelector('#nav-drawer-open').addEventListener('click', (event) => {
+ const body = document.querySelector('body')
+ body.classList.toggle('show-nav')
+ })
+
+ document.querySelector('#nav-drawer-close').addEventListener('click', (event) => {
+ const body = document.querySelector('body')
+ body.classList.toggle('show-nav')
+ })
+
+ </script>
<script>
const serverUrl = "https://bugzilla.yoctoproject.org";
@@ -200,21 +433,37 @@
["assigned_to", "Owner"],
]);
+ function appendBugCount(selector, bugCount) {
+ // Appends the bug count to both the section headline and
+ // the corresponding navigation item
+ const container = document.querySelector(selector).closest("section")
+ const headline = container.querySelector('.bug-count')
+ headline.innerText = `(${bugCount})`
+
+ const anchor = `#${container.getAttribute('id')}`
+ const navLink = document.querySelector(`[href="${anchor}"] .bug-count`)
+ navLink.innerText = `(${bugCount})`
+ }
+
function populateTable(selector, bugs) {
if (bugs.length === 0) {
const p = document.createElement("p");
p.innerHTML = "<em>No bugs found</em>.";
document.querySelector(selector).replaceChildren(p);
+ appendBugCount(selector, 0)
return;
}
const table = document.createElement("table");
- table.setAttribute("class", "highlight sortable")
const header = table.appendChild(document.createElement("thead"));
const tr = header.appendChild(document.createElement("tr"));
- for (const value of fields.values()) {
- tr.appendChild(document.createElement("th")).append(value);
+ for (const [key, value] of fields.entries()) {
+ const th = document.createElement("th")
+ tr.appendChild(th).appendChild(document.createElement("span")).append(value);
+ if (key === 'id') {
+ th.setAttribute('data-sort-method', 'number')
+ }
}
const body = table.appendChild(document.createElement("tbody"));
@@ -230,18 +479,21 @@
}
const footer = table.appendChild(document.createElement("tfoot"));
- footer.innerHTML = `<tr><td colspan="${fields.size}">${bugs.length} bugs found.</td></tr>`;
+ footer.innerHTML = `<tr><td colspan="${fields.size}">${bugs.length} bug${bugs.length > 1 ? 's' : ''} found</td></tr>`;
- sorttable.makeSortable(table);
+ appendBugCount(selector, bugs.length)
+
+ new Tablesort(table);
document.querySelector(selector).replaceChildren(table);
}
async function searchBugs(selector, params) {
- const spinner = document.createElement("div");
- spinner.setAttribute("class", "progress")
- spinner.innerHTML = `<div class="indeterminate"></div>`;
- document.querySelector(selector).replaceChildren(spinner);
+ // Refresh a section
+ const table = document.querySelector(selector)
+ table.setAttribute('aria-busy', true)
+ const container = document.querySelector(selector).closest("section")
+ const reloadButton = container.querySelector('.reload-button')
try {
params.append("include_fields", Array.from(fields.keys()).join());
@@ -260,6 +512,7 @@
console.error(`Failed to fetch bugs for ${selector}: ${error}`);
alert("Error fetching bugs. Check the console for details.");
}
+ table.setAttribute('aria-busy', false)
}
async function bugsByWhiteboard(table, keyword) {
@@ -373,12 +626,10 @@
// The next major release (eg 6.0) is active
parts = release.series_version.split(".");
- next = `${parseInt(parts[0])+1}.0`
+ next = `${parseInt(parts[0]) + 1}.0`
active.push(next);
// And all of the next releases milestones
active.push(...createMilestones(next));
-
- console.log(active);
}
}
return active;
@@ -441,16 +692,7 @@
reloadTable("#inactivefeatures");
reloadTable("#oldmilestone");
reloadTable("#retest");
-
- document.addEventListener('DOMContentLoaded', function () {
- var elems = document.querySelectorAll('.scrollspy');
- M.ScrollSpy.init(elems, { scrollOffset: 100 });
-
- elems = document.querySelectorAll('.pushpin');
- M.Pushpin.init(elems, { offset: document.querySelector("#nav").offsetHeight });
- });
</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</body>
-</html>
+</html>
\ No newline at end of file
diff --git a/scripts/dashboard/bugtriage/tablesort.min.js b/scripts/dashboard/bugtriage/tablesort.min.js
new file mode 100644
index 0000000..e745bef
--- /dev/null
+++ b/scripts/dashboard/bugtriage/tablesort.min.js
@@ -0,0 +1,6 @@
+/*!
+ * tablesort v5.7.0 (2025-12-26)
+ * http://tristen.ca/tablesort/demo/
+ * Copyright (c) 2025 ; Licensed MIT
+*/
+(()=>{function r(t,e){if(!(this instanceof r))return new r(t,e);if(!t||"TABLE"!==t.tagName)throw new Error("Element must be a table");this.init(t,e||{})}function v(t){var e;return window.CustomEvent&&"function"==typeof window.CustomEvent?e=new CustomEvent(t):(e=document.createEvent("CustomEvent")).initCustomEvent(t,!1,!1,void 0),e}function p(t,e){return e=e.sortAttribute||"data-sort",t.hasAttribute(e)?t.getAttribute(e):t.textContent||t.innerText||""}function A(t,e){return(t=t.trim().toLowerCase())===(e=e.trim().toLowerCase())?0:t<e?1:-1}function E(t,e){return[].slice.call(t).find(function(t){return t.getAttribute("data-sort-column-key")===e})}function x(n,o){return function(t,e){var r=n(t.td,e.td);return 0===r?o?e.index-t.index:t.index-e.index:r}}var y=[];r.extend=function(t,e,r){if("function"!=typeof e||"function"!=typeof r)throw new Error("Pattern and sort must be a function");y.push({name:t,pattern:e,sort:r})},r.prototype={init:function(t,e){var r,n,o,i=this;if(i.table=t,i.thead=!1,i.options=e,t.rows&&0<t.rows.length)if(t.tHead&&0<t.tHead.rows.length){for(a=0;a<t.tHead.rows.length;a++)if("thead"===t.tHead.rows[a].getAttribute("data-sort-method")){r=t.tHead.rows[a];break}r=r||t.tHead.rows[t.tHead.rows.length-1],i.thead=!0}else r=t.rows[0];if(r){for(var s=function(){i.current&&i.current!==this&&i.current.removeAttribute("aria-sort"),i.current=this,i.sortTable(this)},a=0;a<r.cells.length;a++)(o=r.cells[a]).setAttribute("role","columnheader"),"none"!==o.getAttribute("data-sort-method")&&(o.tabIndex=0,o.addEventListener("click",s,!1),o.addEventListener("keydown",function(t){"Enter"===t.key&&(t.preventDefault(),s.call(this))}),null!==o.getAttribute("data-sort-default"))&&(n=o);n&&(i.current=n,i.sortTable(n))}},sortTable:function(t,e){var r=this,n=t.getAttribute("data-sort-column-key"),o=t.cellIndex,i=A,s="",a=[],d=r.thead?0:1,u=t.getAttribute("data-sort-method"),l=t.hasAttribute("data-sort-reverse"),c=t.getAttribute("aria-sort");if(r.table.dispatchEvent(v("beforeSort")),e||(c="ascending"===c||"descending"!==c&&!!r.options.descending!=l?"descending":"ascending",t.setAttribute("aria-sort",c)),!(r.table.rows.length<2)){if(!u){for(;a.length<3&&d<r.table.tBodies[0].rows.length;)0<(s=(s=(h=n?E(r.table.tBodies[0].rows[d].cells,n):r.table.tBodies[0].rows[d].cells[o])?p(h,r.options):"").trim()).length&&a.push(s),d++;if(!a)return}for(d=0;d<y.length;d++)if(s=y[d],u){if(s.name===u){i=s.sort;break}}else if(a.every(s.pattern)){i=s.sort;break}for(r.col=o,d=0;d<r.table.tBodies.length;d++){var f,h,b=[],w={},g=0,m=0;if(!(r.table.tBodies[d].rows.length<2)){for(f=0;f<r.table.tBodies[d].rows.length;f++)"none"===(s=r.table.tBodies[d].rows[f]).getAttribute("data-sort-method")?w[g]=s:(h=n?E(s.cells,n):s.cells[r.col],b.push({tr:s,td:h?p(h,r.options):"",index:g})),g++;for("descending"===c?b.sort(x(i,!0)):(b.sort(x(i,!1)),b.reverse()),f=0;f<g;f++)w[f]?(s=w[f],m++):s=b[f-m].tr,r.table.tBodies[d].appendChild(s)}}r.table.dispatchEvent(v("afterSort"))}},refresh:function(){void 0!==this.current&&this.sortTable(this.current,!0)}},"undefined"!=typeof module&&module.exports?module.exports=r:window.Tablesort=r})();
\ No newline at end of file
diff --git a/scripts/dashboard/bugtriage/tablesort.number.js b/scripts/dashboard/bugtriage/tablesort.number.js
new file mode 100644
index 0000000..55ece40
--- /dev/null
+++ b/scripts/dashboard/bugtriage/tablesort.number.js
@@ -0,0 +1,26 @@
+(function(){
+ var cleanNumber = function(i) {
+ return i.replace(/[^\-?0-9.]/g, '');
+ },
+
+ compareNumber = function(a, b) {
+ a = parseFloat(a);
+ b = parseFloat(b);
+
+ a = isNaN(a) ? 0 : a;
+ b = isNaN(b) ? 0 : b;
+
+ return a - b;
+ };
+
+ Tablesort.extend('number', function(item) {
+ return item.match(/^[-+]?[£\x24Û¢´€]?\d+\s*([,\.]\d{0,2})/) || // Prefixed currency
+ item.match(/^[-+]?\d+\s*([,\.]\d{0,2})?[£\x24Û¢´€]/) || // Suffixed currency
+ item.match(/^[-+]?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/); // Number
+ }, function(a, b) {
+ a = cleanNumber(a);
+ b = cleanNumber(b);
+
+ return compareNumber(b, a);
+ });
+}());
--
2.40.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-01-28 14:03 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-28 14:02 [yocto-autobuilder-helper][PATCH 0/4] Update dashboard, Bugzilla stats, bug triage page and autobuilder issues page Alba Herrerias
2026-01-28 14:02 ` [yocto-autobuilder-helper][PATCH 1/4] dashboard: update to unify styles with CVE/Patch Metrics pages Alba Herrerias
2026-01-28 14:02 ` [yocto-autobuilder-helper][PATCH 3/4] dashboard/bugtriage: " Alba Herrerias
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.