From 820d2184472a0080aaba37c2eb9fa0de3b4fc532 Mon Sep 17 00:00:00 2001 From: Kieran Klukas <92754843+kcoderhtml@users.noreply.github.com> Date: Sat, 14 Sep 2024 11:22:35 -0400 Subject: [PATCH] feat: add config options and load items from hc api --- config.default.yml | 6 ++ config/config.go | 8 ++ go.mod | 5 +- go.sum | 2 + main.go | 4 +- models/products.go | 1 + routes/shop.go | 16 ++-- services/services.go | 4 + services/shop.go | 90 +++++++++++++++++++++++ static/assets/css/app.dist.v0.1.6.css | 2 +- static/assets/css/app.dist.v0.1.6.css.br | Bin 4659 -> 4679 bytes views/shop.tpl.html | 60 ++++++++++++--- 12 files changed, 175 insertions(+), 23 deletions(-) create mode 100644 services/shop.go diff --git a/config.default.yml b/config.default.yml index b97c4d8c..c59caecd 100644 --- a/config.default.yml +++ b/config.default.yml @@ -106,3 +106,9 @@ mail: username: password: tls: + +shop: + enabled: true + airtable_api_key: + airtable_base_id: + airtable_product_table_name: diff --git a/config/config.go b/config/config.go index f8a10ee1..5f041702 100644 --- a/config/config.go +++ b/config/config.go @@ -189,6 +189,13 @@ type SMTPMailConfig struct { SkipVerify bool `env:"WAKAPI_MAIL_SMTP_SKIP_VERIFY"` } +type shopConfig struct { + Enabled bool `yaml:"enabled" default:"false" env:"WAKAPI_SHOP_ENABLED"` + AirtableApiKey string `env:"WAKAPI_SHOP_AIRTABLE_API_KEY"` + AirtableBaseId string `env:"WAKAPI_SHOP_AIRTABLE_BASE_ID"` + AirtableProductTableName string `env:"WAKAPI_SHOP_AIRTABLE_PRODUCT_TABLE_NAME"` +} + type Config struct { Env string `default:"dev" env:"ENVIRONMENT"` Version string `yaml:"-"` @@ -203,6 +210,7 @@ type Config struct { Subscriptions subscriptionsConfig Sentry sentryConfig Mail mailConfig + Shop shopConfig } func (c *Config) CreateCookie(name, value string) *http.Cookie { diff --git a/go.mod b/go.mod index 3af09249..2046a30b 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,10 @@ require ( gorm.io/gorm v1.25.11 ) -require github.com/cespare/xxhash/v2 v2.3.0 // indirect +require ( + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/fabioberger/airtable-go v3.1.0+incompatible // indirect +) require ( filippo.io/edwards25519 v1.1.0 // indirect diff --git a/go.sum b/go.sum index 43189623..32c25a33 100644 --- a/go.sum +++ b/go.sum @@ -60,6 +60,8 @@ github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 h1:hH4PQfOndHDlpz github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= github.com/emersion/go-smtp v0.21.3 h1:7uVwagE8iPYE48WhNsng3RRpCUpFvNl39JGNSIyGVMY= github.com/emersion/go-smtp v0.21.3/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= +github.com/fabioberger/airtable-go v3.1.0+incompatible h1:n5dw+HWBc+hytrVL75xe94EGt7FtNFGDII1tNoWTCAE= +github.com/fabioberger/airtable-go v3.1.0+incompatible/go.mod h1:EoKuSh7EefzhMCyVr6iXPlgFzDgHyZCZ3E5Sg8Cy9GM= github.com/getsentry/sentry-go v0.28.1 h1:zzaSm/vHmGllRM6Tpx1492r0YDzauArdBfkJRtY6P5k= github.com/getsentry/sentry-go v0.28.1/go.mod h1:1fQZ+7l7eeJ3wYi82q5Hg8GqAPgefRq+FP/QhafYVgg= github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= diff --git a/main.go b/main.go index 297f70fa..e251666e 100644 --- a/main.go +++ b/main.go @@ -87,6 +87,7 @@ var ( diagnosticsService services.IDiagnosticsService housekeepingService services.IHousekeepingService miscService services.IMiscService + shopService services.IShopService ) // TODO: Refactor entire project to be structured after business domains @@ -188,6 +189,7 @@ func main() { diagnosticsService = services.NewDiagnosticsService(diagnosticsRepository) housekeepingService = services.NewHousekeepingService(userService, heartbeatService, summaryService) miscService = services.NewMiscService(userService, heartbeatService, summaryService, keyValueService, mailService) + shopService = services.NewShopService() if config.App.LeaderboardEnabled { leaderboardService = services.NewLeaderboardService(leaderboardRepository, summaryService, userService) @@ -233,7 +235,7 @@ func main() { settingsHandler := routes.NewSettingsHandler(userService, heartbeatService, summaryService, aliasService, aggregationService, languageMappingService, projectLabelService, keyValueService, mailService) subscriptionHandler := routes.NewSubscriptionHandler(userService, mailService, keyValueService) projectsHandler := routes.NewProjectsHandler(userService, heartbeatService) - shopHandler := routes.NewShopHandler(userService) + shopHandler := routes.NewShopHandler(userService, shopService) homeHandler := routes.NewHomeHandler(userService, keyValueService) loginHandler := routes.NewLoginHandler(userService, mailService, keyValueService) imprintHandler := routes.NewImprintHandler(keyValueService) diff --git a/models/products.go b/models/products.go index 1510968a..61d9ab0b 100644 --- a/models/products.go +++ b/models/products.go @@ -7,6 +7,7 @@ type Product struct { ID uint `json:"id" gorm:"primary_key"` Name string `json:"name"` Price int `json:"price"` + Stock int `json:"stock"` Description string `json:"description"` Image string `json:"image"` } diff --git a/routes/shop.go b/routes/shop.go index 7a6815e3..bf76e670 100644 --- a/routes/shop.go +++ b/routes/shop.go @@ -6,7 +6,6 @@ import ( "github.com/go-chi/chi/v5" conf "github.com/kcoderhtml/hackatime/config" "github.com/kcoderhtml/hackatime/middlewares" - "github.com/kcoderhtml/hackatime/models" "github.com/kcoderhtml/hackatime/models/view" routeutils "github.com/kcoderhtml/hackatime/routes/utils" "github.com/kcoderhtml/hackatime/services" @@ -16,12 +15,14 @@ import ( type ShopHandler struct { config *conf.Config userService services.IUserService + shopService services.IShopService } -func NewShopHandler(userService services.IUserService) *ShopHandler { +func NewShopHandler(userService services.IUserService, shopService services.IShopService) *ShopHandler { return &ShopHandler{ config: conf.Get(), userService: userService, + shopService: shopService, } } @@ -54,13 +55,10 @@ func (h *ShopHandler) buildViewModel(r *http.Request, w http.ResponseWriter) *vi return h.buildViewModel(r, w).WithError("unauthorized") } - products := []*models.Product{ - { - Name: "Sticker Pile", - Price: 1, - Description: "We'll send you 3 random stickers! (Available anywhere!)", - Image: "https://cloud-c1gqq7ttf-hack-club-bot.vercel.app/0sticker_pile_2.png", - }, + products, err := h.shopService.GetProducts() + if err != nil { + conf.Log().Request(r).Error("failed to get products", "error", err.Error()) + return h.buildViewModel(r, w).WithError("failed to get products") } pageParams := utils.ParsePageParamsWithDefault(r, 1, 24) diff --git a/services/services.go b/services/services.go index 557969fd..7a70693e 100644 --- a/services/services.go +++ b/services/services.go @@ -152,3 +152,7 @@ type IUserService interface { FlushCache() FlushUserCache(string) } + +type IShopService interface { + GetProducts() ([]*models.Product, error) +} diff --git a/services/shop.go b/services/shop.go new file mode 100644 index 00000000..14e7473d --- /dev/null +++ b/services/shop.go @@ -0,0 +1,90 @@ +package services + +import ( + "encoding/json" + "fmt" + "net/http" + "sort" + "time" + + "github.com/kcoderhtml/hackatime/config" + "github.com/kcoderhtml/hackatime/models" + "github.com/patrickmn/go-cache" +) + +type ShopService struct { + config *config.Config + cache *cache.Cache +} + +func NewShopService() *ShopService { + return &ShopService{ + config: config.Get(), + cache: cache.New(6*time.Hour, 6*time.Hour), + } +} + +type HackClubProduct struct { + Name string `json:"name"` + SmallName string `json:"smallName"` + Description string `json:"description"` + Hours int `json:"hours"` + ImageURL string `json:"imageURL"` + Stock *int `json:"stock"` // Change to pointer to allow null +} + +func (srv *ShopService) GetProducts() ([]*models.Product, error) { + // Check if products are in cache + if cachedProducts, found := srv.cache.Get("products"); found { + return cachedProducts.([]*models.Product), nil + } + + // Fetch products from Hack Club API + resp, err := http.Get("https://hackclub.com/api/arcade/shop/") + if err != nil { + return nil, fmt.Errorf("error fetching products: %v", err) + } + defer resp.Body.Close() + + var hackClubProducts []HackClubProduct + if err := json.NewDecoder(resp.Body).Decode(&hackClubProducts); err != nil { + return nil, fmt.Errorf("error decoding products: %v", err) + } + + formattedProducts := []*models.Product{} + + for i, product := range hackClubProducts { + description := product.Description + if description == "" { + description = product.SmallName + } + + stock := -1 + if product.Stock != nil { + stock = *product.Stock + } + + formattedProducts = append(formattedProducts, &models.Product{ + ID: uint(i + 1), // Use index + 1 as ID + Name: product.Name, + Description: description, + Price: product.Hours, + Stock: stock, + Image: product.ImageURL, + }) + } + + // Sort products by price + sort.Slice(formattedProducts, func(i, j int) bool { + return formattedProducts[i].Price < formattedProducts[j].Price + }) + + // Cache the sorted formatted products + srv.cache.Set("products", formattedProducts, cache.DefaultExpiration) + + return formattedProducts, nil +} + +func (srv *ShopService) ClearProductsCache() { + srv.cache.Delete("products") +} diff --git a/static/assets/css/app.dist.v0.1.6.css b/static/assets/css/app.dist.v0.1.6.css index 987e0700..307ce9e7 100644 --- a/static/assets/css/app.dist.v0.1.6.css +++ b/static/assets/css/app.dist.v0.1.6.css @@ -1 +1 @@ -/*! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.absolute{position:absolute}.relative{position:relative}.right-0{right:0}.top-0{top:0}.top-1{top:.25rem}.z-10{z-index:10}.col-span-2{grid-column:span 2/span 2}.row-span-2{grid-row:span 2/span 2}.float-right{float:right}.m-0{margin:0}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-4{margin-top:1rem;margin-bottom:1rem}.-mb-1{margin-bottom:-.25rem}.-ml-1{margin-left:-.25rem}.-mt-4{margin-top:-1rem}.mb-1{margin-bottom:.25rem}.mb-10{margin-bottom:2.5rem}.mb-14{margin-bottom:3.5rem}.mb-16{margin-bottom:4rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.ml-px{margin-left:1px}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mr-8{margin-right:2rem}.mr-px{margin-right:1px}.mt-1{margin-top:.25rem}.mt-10{margin-top:2.5rem}.mt-12{margin-top:3rem}.mt-16{margin-top:4rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.inline-grid{display:inline-grid}.hidden{display:none}.h-4{height:1rem}.h-48{height:12rem}.h-full{height:100%}.h-min{height:-moz-min-content;height:min-content}.min-h-screen{min-height:100vh}.\!w-auto{width:auto!important}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-12{width:3rem}.w-16{width:4rem}.w-2\/3{width:66.666667%}.w-4{width:1rem}.w-40{width:10rem}.w-full{width:100%}.max-w-4xl{max-width:56rem}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-screen-lg{max-width:1024px}.max-w-screen-sm{max-width:640px}.max-w-screen-xl{max-width:1280px}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink{flex-shrink:1}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.flex-grow,.grow{flex-grow:1}.-translate-x-3{--tw-translate-x:-0.75rem}.-translate-x-3,.-translate-y-0\.5{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-0\.5{--tw-translate-y:-0.125rem}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.flex-nowrap{flex-wrap:nowrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-6{gap:1.5rem}.gap-x-1{-moz-column-gap:.25rem;column-gap:.25rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-x-8{-moz-column-gap:2rem;column-gap:2rem}.gap-y-1{row-gap:.25rem}.gap-y-6{row-gap:1.5rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.25rem*var(--tw-space-x-reverse));margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.self-center{align-self:center}.overflow-hidden,.truncate{overflow:hidden}.truncate{white-space:nowrap}.text-ellipsis,.truncate{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.border-2{border-width:2px}.border-4{border-width:4px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}.border-gray-800{--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity))}.border-green-700{--tw-border-opacity:1;border-color:rgb(21 128 61/var(--tw-border-opacity))}.border-orange-500{--tw-border-opacity:1;border-color:rgb(249 115 22/var(--tw-border-opacity))}.border-primary{border-color:oklch(73.01% .146 74.32)}.border-secondary-secondary{border-color:oklch(66.14% .04 200.43)}.bg-accent-primary{background-color:oklch(67.61% .114 293.1)}.bg-background{background-color:oklch(87.84% .001 197.14)}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}.bg-primary{background-color:oklch(73.01% .146 74.32)}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}.bg-secondary-primary{background-color:oklch(75.31% .04 200.43)}.bg-secondary-secondary{background-color:oklch(66.14% .04 200.43)}.bg-secondary-tertiary{background-color:oklch(57.44% .04 200.43)}.bg-transparent{background-color:transparent}.object-cover{-o-object-fit:cover;object-fit:cover}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-4{padding:1rem}.p-px{padding:1px}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-10{padding-bottom:2.5rem}.pb-4{padding-bottom:1rem}.pt-10{padding-top:2.5rem}.pt-8{padding-top:2rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.777rem}.text-3xl{font-size:2.369rem}.text-4xl{font-size:3.158rem}.text-8xl{font-size:6rem;line-height:1}.text-base{font-size:1rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.75rem}.text-xl{font-size:1.333rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.capitalize{text-transform:capitalize}.leading-6{line-height:1.5rem}.leading-none{line-height:1}.leading-snug{line-height:1.375}.text-accent-secondary{color:oklch(63.15% .114 293.1)}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}.text-green-700{--tw-text-opacity:1;color:rgb(21 128 61/var(--tw-text-opacity))}.text-primary{color:oklch(73.01% .146 74.32)}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.text-text-dark-primary{color:oklch(94% .033 91.67)}.text-text-dark-tertiary{color:oklch(62.3% .015 93.07)}.text-text-primary{color:oklch(26.33% .04 91.04)}.text-text-secondary{color:oklch(43.57% .028 90.91)}.text-text-tertiary{color:oklch(52.82% .022 90.66)}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.placeholder-current::-moz-placeholder{color:currentColor}.placeholder-current::placeholder{color:currentColor}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}h1,h2,h3,h4,h5,h6{font-family:Superclarendon,Bookman Old Style,URW Bookman,URW Bookman L,Georgia Pro,Georgia,serif}body{font-family:ui-rounded,Hiragino Maru Gothic ProN,Quicksand,Comfortaa,Manjari,Arial Rounded MT,Arial Rounded MT Bold,Calibri,source-sans-pro,sans-serif}[v-cloak]{display:none}.bg-gray-850{background-color:#242b3a}.hover\:bg-gray-850:hover{--bg-opacity:1;background-color:#242b3a}.text-xsi{font-size:.75rem!important;line-height:1rem!important}.text-xxs{font-size:.65rem!important}.mt-14{margin-top:3.5rem}.text-7xl{font-size:4.5rem;line-height:1.1}.text-8xl{font-size:5rem;line-height:1.1}.imp\:cursor-not-allowed{cursor:not-allowed!important}.h1{margin:0;font-size:2.369rem;font-weight:600;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.h1-subcaption{font-size:.75rem;--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.btn-default{border-radius:.25rem;background-color:oklch(67.61% .114 293.1);padding:.5rem 1rem;font-size:.75rem;font-weight:600}.btn-default:hover{--bg-opacity:1;background-color:#242b3a;background-color:oklch(63.15% .114 293.1)}@media (prefers-color-scheme:dark){.btn-default{background-color:oklch(46.02% .127 287.87)}.btn-default:hover{background-color:oklch(43.57% .127 287.87)}}.btn-disabled{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.btn-disabled,.btn-primary{border-radius:.25rem;padding:.5rem 1rem;font-size:.75rem;font-weight:600}.btn-primary{background-color:oklch(73.01% .146 74.32)}.btn-primary:hover{background-color:oklch(65.87% .146 74.32)}.btn-danger{border-radius:.25rem;--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity));padding:.5rem 1rem;font-size:.75rem;font-weight:600}.btn-danger:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity))}.btn-small{padding:.25rem .5rem}.input-default{width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;background-color:oklch(75.31% .04 200.43);padding:.5rem 1rem;color:oklch(26.33% .04 91.04)}.input-default::-moz-placeholder{color:currentColor}.input-default::placeholder{color:currentColor}.input-default{outline:2px solid transparent;outline-offset:2px}.input-default:focus{background-color:oklch(66.14% .04 200.43)}@media (prefers-color-scheme:dark){.input-default{background-color:oklch(50.08% .042 200.2);color:oklch(94% .033 91.67)}.input-default:focus{background-color:oklch(44.12% .042 200.2)}}.select-default{cursor:pointer;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;background-color:oklch(75.31% .04 200.43);padding:.5rem 1rem;color:oklch(26.33% .04 91.04)}.select-default::-moz-placeholder{color:currentColor}.select-default::placeholder{color:currentColor}.select-default{outline:2px solid transparent;outline-offset:2px}.select-default:focus{background-color:oklch(66.14% .04 200.43)}@media (prefers-color-scheme:dark){.select-default{background-color:oklch(50.08% .042 200.2);color:oklch(94% .033 91.67)}.select-default:focus{background-color:oklch(44.12% .042 200.2)}}.menu-item{display:flex;cursor:pointer;align-items:center}.menu-item>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}.menu-item{border-radius:.25rem;padding:.5rem 1rem;font-size:.75rem;font-weight:600}.menu-item:hover{background-color:oklch(67.61% .114 293.1)}@media (prefers-color-scheme:dark){.menu-item:hover{background-color:oklch(46.02% .127 287.87)}}.submenu-item{border-radius:.25rem;padding:.25rem;text-align:right}.submenu-item:hover{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.chip{margin-bottom:.25rem;display:inline-block;border-radius:9999px;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;background-color:#242b3a}.chip,.link{font-weight:600}.link{color:oklch(43.57% .028 90.91)}.link:hover{color:oklch(67.61% .114 293.1)}@media (prefers-color-scheme:dark){.link{color:oklch(79.23% .024 90.79)}}.newsbox{border-radius:.375rem;border-width:2px;--tw-border-opacity:1;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));background-color:#242b3a}.newsbox,.newsbox-default{border-color:rgb(21 128 61/var(--tw-border-opacity))}.newsbox-default,.newsbox-warning{--tw-border-opacity:1}.newsbox-warning{border-color:rgb(202 138 4/var(--tw-border-opacity))}.newsbox-danger{--tw-border-opacity:1;border-color:rgb(185 28 28/var(--tw-border-opacity))}.leaderboard-default{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}.leaderboard-self{margin-left:-10px;margin-right:-10px;padding-left:calc(1rem + 10px);padding-right:calc(1rem + 10px);--tw-border-opacity:1;border-color:rgb(21 128 61/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.text-gold{color:#daa520}.leaderboard-gold{border-color:#daa520}.leaderboard-silver{border-color:silver}.leaderboard-bronze{border-color:#cd7f32}::-webkit-calendar-picker-indicator{filter:invert(1);cursor:pointer}.max-available{max-width:-moz-available;max-width:-webkit-fill-available;max-width:fill-available}.projects-item a{display:flex;flex-direction:column;border-radius:.375rem;background-color:oklch(66.14% .04 200.43);padding:.5rem 1rem;vertical-align:middle;--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.projects-item a,.projects-item a:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.projects-item a:hover{background-color:oklch(75.31% .04 200.43);--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}@media (prefers-color-scheme:dark){.projects-item a{background-color:oklch(44.12% .042 200.2)}.projects-item a:hover{background-color:oklch(50.08% .042 200.2)}}.projects-item .color-fading{position:absolute;height:100%;width:100%;border-radius:.375rem;pointer-events:none}.disabled{pointer-events:none;cursor:default;opacity:75%}.entity-filter-control{width:180px;font-size:.75rem;color:oklch(43.57% .028 90.91)}@media (prefers-color-scheme:dark){.entity-filter-control{color:oklch(79.23% .024 90.79)}}.entity-filter-control label{vertical-align:text-bottom;font-weight:600;text-transform:capitalize}.entity-filter-control select{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.375rem .625rem}.wi-min{width:-moz-min-content!important;width:min-content!important}.checked\:text-green-500:checked{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}.hover\:bg-accent-secondary:hover{background-color:oklch(63.15% .114 293.1)}.hover\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.hover\:bg-gray-800:hover{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.hover\:bg-primary-dark:hover{background-color:oklch(65.87% .146 74.32)}.hover\:bg-secondary-secondary:hover{background-color:oklch(66.14% .04 200.43)}.hover\:bg-secondary-tertiary:hover{background-color:oklch(57.44% .04 200.43)}.hover\:text-accent-secondary:hover{color:oklch(63.15% .114 293.1)}.hover\:text-gray-500:hover{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.hover\:text-text-primary:hover{color:oklch(26.33% .04 91.04)}.hover\:text-text-secondary:hover{color:oklch(43.57% .028 90.91)}.focus\:bg-secondary-secondary:focus{background-color:oklch(66.14% .04 200.43)}@media (min-width:640px){.sm\:inline-block{display:inline-block}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-nowrap{flex-wrap:nowrap}}@media (min-width:768px){.md\:mb-0{margin-bottom:0}.md\:flex{display:flex}.md\:w-1\/2{width:50%}.md\:w-1\/3{width:33.333333%}.md\:w-2\/3{width:66.666667%}.md\:w-3\/4{width:75%}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-nowrap{flex-wrap:nowrap}.md\:space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(2rem*var(--tw-space-x-reverse));margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)))}.md\:px-10{padding-left:2.5rem;padding-right:2.5rem}}@media (min-width:1024px){.lg\:inline-block{display:inline-block}.lg\:w-1\/2{width:50%}.lg\:w-3\/4{width:75%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-24{padding-left:6rem;padding-right:6rem}}@media (prefers-color-scheme:dark){.dark\:border-secondary-dark-secondary{border-color:oklch(44.12% .042 200.2)}.dark\:bg-accent-dark-primary{background-color:oklch(46.02% .127 287.87)}.dark\:bg-background-dark{background-color:oklch(31% .007 229.04)}.dark\:bg-secondary-dark-primary{background-color:oklch(50.08% .042 200.2)}.dark\:bg-secondary-dark-secondary{background-color:oklch(44.12% .042 200.2)}.dark\:bg-secondary-dark-tertiary{background-color:oklch(37.59% .042 200.2)}.dark\:text-accent-primary{color:oklch(67.61% .114 293.1)}.dark\:text-primary-dark{color:oklch(65.87% .146 74.32)}.dark\:text-text-dark-primary{color:oklch(94% .033 91.67)}.dark\:text-text-dark-secondary{color:oklch(79.23% .024 90.79)}.dark\:text-text-dark-tertiary{color:oklch(62.3% .015 93.07)}.dark\:hover\:bg-accent-dark-secondary:hover,.hover\:dark\:bg-accent-dark-secondary:hover{background-color:oklch(43.57% .127 287.87)}.hover\:dark\:bg-secondary-dark-secondary:hover{background-color:oklch(44.12% .042 200.2)}.hover\:dark\:bg-secondary-dark-tertiary:hover{background-color:oklch(37.59% .042 200.2)}.dark\:hover\:text-text-dark-secondary:hover{color:oklch(79.23% .024 90.79)}.hover\:dark\:hover\:text-accent-primary:hover:hover{color:oklch(67.61% .114 293.1)}.hover\:dark\:text-text-dark-primary:hover{color:oklch(94% .033 91.67)}.focus\:dark\:bg-secondary-dark-secondary:focus{background-color:oklch(44.12% .042 200.2)}} \ No newline at end of file +/*! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.absolute{position:absolute}.relative{position:relative}.right-0{right:0}.top-0{top:0}.top-1{top:.25rem}.z-10{z-index:10}.col-span-2{grid-column:span 2/span 2}.row-span-2{grid-row:span 2/span 2}.float-right{float:right}.m-0{margin:0}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-4{margin-top:1rem;margin-bottom:1rem}.-mb-1{margin-bottom:-.25rem}.-ml-1{margin-left:-.25rem}.-mt-4{margin-top:-1rem}.mb-1{margin-bottom:.25rem}.mb-10{margin-bottom:2.5rem}.mb-14{margin-bottom:3.5rem}.mb-16{margin-bottom:4rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.ml-px{margin-left:1px}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mr-8{margin-right:2rem}.mr-px{margin-right:1px}.mt-1{margin-top:.25rem}.mt-10{margin-top:2.5rem}.mt-12{margin-top:3rem}.mt-16{margin-top:4rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-auto{margin-top:auto}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.inline-grid{display:inline-grid}.hidden{display:none}.h-4{height:1rem}.h-48{height:12rem}.h-full{height:100%}.h-min{height:-moz-min-content;height:min-content}.min-h-screen{min-height:100vh}.\!w-auto{width:auto!important}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-12{width:3rem}.w-16{width:4rem}.w-2\/3{width:66.666667%}.w-4{width:1rem}.w-40{width:10rem}.w-full{width:100%}.max-w-4xl{max-width:56rem}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-screen-lg{max-width:1024px}.max-w-screen-sm{max-width:640px}.max-w-screen-xl{max-width:1280px}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink{flex-shrink:1}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.flex-grow,.grow{flex-grow:1}.-translate-x-3{--tw-translate-x:-0.75rem}.-translate-x-3,.-translate-y-0\.5{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-0\.5{--tw-translate-y:-0.125rem}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.flex-nowrap{flex-wrap:nowrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-6{gap:1.5rem}.gap-x-1{-moz-column-gap:.25rem;column-gap:.25rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-x-8{-moz-column-gap:2rem;column-gap:2rem}.gap-y-1{row-gap:.25rem}.gap-y-6{row-gap:1.5rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.25rem*var(--tw-space-x-reverse));margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.self-center{align-self:center}.overflow-hidden,.truncate{overflow:hidden}.truncate{white-space:nowrap}.text-ellipsis,.truncate{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.border-2{border-width:2px}.border-4{border-width:4px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}.border-gray-800{--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity))}.border-green-700{--tw-border-opacity:1;border-color:rgb(21 128 61/var(--tw-border-opacity))}.border-orange-500{--tw-border-opacity:1;border-color:rgb(249 115 22/var(--tw-border-opacity))}.border-primary{border-color:oklch(73.01% .146 74.32)}.border-secondary-secondary{border-color:oklch(66.14% .04 200.43)}.bg-accent-primary{background-color:oklch(67.61% .114 293.1)}.bg-background{background-color:oklch(87.84% .001 197.14)}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}.bg-primary{background-color:oklch(73.01% .146 74.32)}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}.bg-secondary-primary{background-color:oklch(75.31% .04 200.43)}.bg-secondary-secondary{background-color:oklch(66.14% .04 200.43)}.bg-secondary-tertiary{background-color:oklch(57.44% .04 200.43)}.bg-transparent{background-color:transparent}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-4{padding:1rem}.p-px{padding:1px}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-10{padding-bottom:2.5rem}.pb-4{padding-bottom:1rem}.pt-10{padding-top:2.5rem}.pt-8{padding-top:2rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.777rem}.text-3xl{font-size:2.369rem}.text-4xl{font-size:3.158rem}.text-8xl{font-size:6rem;line-height:1}.text-base{font-size:1rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.75rem}.text-xl{font-size:1.333rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.capitalize{text-transform:capitalize}.leading-6{line-height:1.5rem}.leading-none{line-height:1}.leading-snug{line-height:1.375}.text-accent-secondary{color:oklch(63.15% .114 293.1)}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}.text-green-700{--tw-text-opacity:1;color:rgb(21 128 61/var(--tw-text-opacity))}.text-primary{color:oklch(73.01% .146 74.32)}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.text-text-dark-primary{color:oklch(94% .033 91.67)}.text-text-dark-tertiary{color:oklch(62.3% .015 93.07)}.text-text-primary{color:oklch(26.33% .04 91.04)}.text-text-secondary{color:oklch(43.57% .028 90.91)}.text-text-tertiary{color:oklch(52.82% .022 90.66)}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.placeholder-current::-moz-placeholder{color:currentColor}.placeholder-current::placeholder{color:currentColor}.opacity-50{opacity:.5}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}h1,h2,h3,h4,h5,h6{font-family:Superclarendon,Bookman Old Style,URW Bookman,URW Bookman L,Georgia Pro,Georgia,serif}body{font-family:ui-rounded,Hiragino Maru Gothic ProN,Quicksand,Comfortaa,Manjari,Arial Rounded MT,Arial Rounded MT Bold,Calibri,source-sans-pro,sans-serif}[v-cloak]{display:none}.bg-gray-850{background-color:#242b3a}.hover\:bg-gray-850:hover{--bg-opacity:1;background-color:#242b3a}.text-xsi{font-size:.75rem!important;line-height:1rem!important}.text-xxs{font-size:.65rem!important}.mt-14{margin-top:3.5rem}.text-7xl{font-size:4.5rem;line-height:1.1}.text-8xl{font-size:5rem;line-height:1.1}.imp\:cursor-not-allowed{cursor:not-allowed!important}.h1{margin:0;font-size:2.369rem;font-weight:600;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.h1-subcaption{font-size:.75rem;--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.btn-default{border-radius:.25rem;background-color:oklch(67.61% .114 293.1);padding:.5rem 1rem;font-size:.75rem;font-weight:600}.btn-default:hover{--bg-opacity:1;background-color:#242b3a;background-color:oklch(63.15% .114 293.1)}@media (prefers-color-scheme:dark){.btn-default{background-color:oklch(46.02% .127 287.87)}.btn-default:hover{background-color:oklch(43.57% .127 287.87)}}.btn-disabled{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.btn-disabled,.btn-primary{border-radius:.25rem;padding:.5rem 1rem;font-size:.75rem;font-weight:600}.btn-primary{background-color:oklch(73.01% .146 74.32)}.btn-primary:hover{background-color:oklch(65.87% .146 74.32)}.btn-danger{border-radius:.25rem;--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity));padding:.5rem 1rem;font-size:.75rem;font-weight:600}.btn-danger:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity))}.btn-small{padding:.25rem .5rem}.input-default{width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;background-color:oklch(75.31% .04 200.43);padding:.5rem 1rem;color:oklch(26.33% .04 91.04)}.input-default::-moz-placeholder{color:currentColor}.input-default::placeholder{color:currentColor}.input-default{outline:2px solid transparent;outline-offset:2px}.input-default:focus{background-color:oklch(66.14% .04 200.43)}@media (prefers-color-scheme:dark){.input-default{background-color:oklch(50.08% .042 200.2);color:oklch(94% .033 91.67)}.input-default:focus{background-color:oklch(44.12% .042 200.2)}}.select-default{cursor:pointer;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;background-color:oklch(75.31% .04 200.43);padding:.5rem 1rem;color:oklch(26.33% .04 91.04)}.select-default::-moz-placeholder{color:currentColor}.select-default::placeholder{color:currentColor}.select-default{outline:2px solid transparent;outline-offset:2px}.select-default:focus{background-color:oklch(66.14% .04 200.43)}@media (prefers-color-scheme:dark){.select-default{background-color:oklch(50.08% .042 200.2);color:oklch(94% .033 91.67)}.select-default:focus{background-color:oklch(44.12% .042 200.2)}}.menu-item{display:flex;cursor:pointer;align-items:center}.menu-item>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}.menu-item{border-radius:.25rem;padding:.5rem 1rem;font-size:.75rem;font-weight:600}.menu-item:hover{background-color:oklch(67.61% .114 293.1)}@media (prefers-color-scheme:dark){.menu-item:hover{background-color:oklch(46.02% .127 287.87)}}.submenu-item{border-radius:.25rem;padding:.25rem;text-align:right}.submenu-item:hover{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.chip{margin-bottom:.25rem;display:inline-block;border-radius:9999px;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;background-color:#242b3a}.chip,.link{font-weight:600}.link{color:oklch(43.57% .028 90.91)}.link:hover{color:oklch(67.61% .114 293.1)}@media (prefers-color-scheme:dark){.link{color:oklch(79.23% .024 90.79)}}.newsbox{border-radius:.375rem;border-width:2px;--tw-border-opacity:1;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));background-color:#242b3a}.newsbox,.newsbox-default{border-color:rgb(21 128 61/var(--tw-border-opacity))}.newsbox-default,.newsbox-warning{--tw-border-opacity:1}.newsbox-warning{border-color:rgb(202 138 4/var(--tw-border-opacity))}.newsbox-danger{--tw-border-opacity:1;border-color:rgb(185 28 28/var(--tw-border-opacity))}.leaderboard-default{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}.leaderboard-self{margin-left:-10px;margin-right:-10px;padding-left:calc(1rem + 10px);padding-right:calc(1rem + 10px);--tw-border-opacity:1;border-color:rgb(21 128 61/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.text-gold{color:#daa520}.leaderboard-gold{border-color:#daa520}.leaderboard-silver{border-color:silver}.leaderboard-bronze{border-color:#cd7f32}::-webkit-calendar-picker-indicator{filter:invert(1);cursor:pointer}.max-available{max-width:-moz-available;max-width:-webkit-fill-available;max-width:fill-available}.projects-item a{display:flex;flex-direction:column;border-radius:.375rem;background-color:oklch(66.14% .04 200.43);padding:.5rem 1rem;vertical-align:middle;--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.projects-item a,.projects-item a:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.projects-item a:hover{background-color:oklch(75.31% .04 200.43);--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}@media (prefers-color-scheme:dark){.projects-item a{background-color:oklch(44.12% .042 200.2)}.projects-item a:hover{background-color:oklch(50.08% .042 200.2)}}.projects-item .color-fading{position:absolute;height:100%;width:100%;border-radius:.375rem;pointer-events:none}.disabled{pointer-events:none;cursor:default;opacity:75%}.entity-filter-control{width:180px;font-size:.75rem;color:oklch(43.57% .028 90.91)}@media (prefers-color-scheme:dark){.entity-filter-control{color:oklch(79.23% .024 90.79)}}.entity-filter-control label{vertical-align:text-bottom;font-weight:600;text-transform:capitalize}.entity-filter-control select{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.375rem .625rem}.wi-min{width:-moz-min-content!important;width:min-content!important}.checked\:text-green-500:checked{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}.hover\:bg-accent-secondary:hover{background-color:oklch(63.15% .114 293.1)}.hover\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.hover\:bg-gray-800:hover{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.hover\:bg-primary-dark:hover{background-color:oklch(65.87% .146 74.32)}.hover\:bg-secondary-secondary:hover{background-color:oklch(66.14% .04 200.43)}.hover\:bg-secondary-tertiary:hover{background-color:oklch(57.44% .04 200.43)}.hover\:text-accent-secondary:hover{color:oklch(63.15% .114 293.1)}.hover\:text-gray-500:hover{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.hover\:text-text-primary:hover{color:oklch(26.33% .04 91.04)}.hover\:text-text-secondary:hover{color:oklch(43.57% .028 90.91)}.focus\:bg-secondary-secondary:focus{background-color:oklch(66.14% .04 200.43)}@media (min-width:640px){.sm\:inline-block{display:inline-block}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-nowrap{flex-wrap:nowrap}}@media (min-width:768px){.md\:mb-0{margin-bottom:0}.md\:flex{display:flex}.md\:w-1\/2{width:50%}.md\:w-1\/3{width:33.333333%}.md\:w-2\/3{width:66.666667%}.md\:w-3\/4{width:75%}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-nowrap{flex-wrap:nowrap}.md\:space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(2rem*var(--tw-space-x-reverse));margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)))}.md\:px-10{padding-left:2.5rem;padding-right:2.5rem}}@media (min-width:1024px){.lg\:inline-block{display:inline-block}.lg\:w-1\/2{width:50%}.lg\:w-3\/4{width:75%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-24{padding-left:6rem;padding-right:6rem}}@media (prefers-color-scheme:dark){.dark\:border-secondary-dark-secondary{border-color:oklch(44.12% .042 200.2)}.dark\:bg-accent-dark-primary{background-color:oklch(46.02% .127 287.87)}.dark\:bg-background-dark{background-color:oklch(31% .007 229.04)}.dark\:bg-secondary-dark-primary{background-color:oklch(50.08% .042 200.2)}.dark\:bg-secondary-dark-secondary{background-color:oklch(44.12% .042 200.2)}.dark\:bg-secondary-dark-tertiary{background-color:oklch(37.59% .042 200.2)}.dark\:text-accent-primary{color:oklch(67.61% .114 293.1)}.dark\:text-primary-dark{color:oklch(65.87% .146 74.32)}.dark\:text-text-dark-primary{color:oklch(94% .033 91.67)}.dark\:text-text-dark-secondary{color:oklch(79.23% .024 90.79)}.dark\:text-text-dark-tertiary{color:oklch(62.3% .015 93.07)}.dark\:hover\:bg-accent-dark-secondary:hover,.hover\:dark\:bg-accent-dark-secondary:hover{background-color:oklch(43.57% .127 287.87)}.hover\:dark\:bg-secondary-dark-secondary:hover{background-color:oklch(44.12% .042 200.2)}.hover\:dark\:bg-secondary-dark-tertiary:hover{background-color:oklch(37.59% .042 200.2)}.dark\:hover\:text-text-dark-secondary:hover{color:oklch(79.23% .024 90.79)}.hover\:dark\:hover\:text-accent-primary:hover:hover{color:oklch(67.61% .114 293.1)}.hover\:dark\:text-text-dark-primary:hover{color:oklch(94% .033 91.67)}.focus\:dark\:bg-secondary-dark-secondary:focus{background-color:oklch(44.12% .042 200.2)}} \ No newline at end of file diff --git a/static/assets/css/app.dist.v0.1.6.css.br b/static/assets/css/app.dist.v0.1.6.css.br index 52ef0f5fb52cb3e03a8c4ab1e395d8dfc006b0bf..ba52c49a7784bba476c90a67512ec5458a3ca208 100644 GIT binary patch literal 4679 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 J-8v=rS^?$!9y|a5 literal 4659 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

@@ -37,23 +49,40 @@ > {{ range .Products }}
- {{ .Name }} -
+ {{ if gt .Stock 0 }} +
+ In Stock: {{ .Stock }} +
+ {{ else if eq .Stock 0 }} +
Out of Stock
+ {{ else }} +
+ Unlimited +
+ {{ end }} +
+ {{ .Name }} +
+

{{ .Name }}

{{ .Description }}

-