templates for self-hosting game jams (or any other kind of jam tbh)

Compare changes

Choose any two refs to compare.

Changed files
+1664 -1261
_raw-assets
astro
src
components
layouts
hugo
archetypes
assets
exampleSite
images
layouts
scss
static
jekyll
plain-html
plain-php
wordpress
resources
zola
+12 -2
README.md
···
there is also a folder called "colorthemes" that has, well, a bunch of color themes to replace the site variables with if you want something different and don't feel inspired.
+
if you are a developer, ./assets.sh will build/copy the scss and the images to all the projects from the `_raw-assets` folder. if you're not a developer you can safely ignore all that
+
some notes for each version follow below; please make sure and read the section for whichever framework you're working with!
## plain html
···
## jekyll
-
watch this space
+
watch this space.
## astro
please note that there's a bun.lock file because i use [bun](https://bun.sh) but you do not have to. you can use npm/pnpm/yarn/deno etc it's daijoubu
+
uses astro collections, so data files go in src/data/games
+
## hugo
watch this space
···
## wordpress
-
watch this space
+
WIP
+
+
run `bun i` and then `bun vite build` to compile assets (or run w/ npm/pnpm/yarn/deno if you prefer; if you don't know what any of these are you are most likely to have npm)
+
+
should not need any additional plugins to run. please understand this involved me ascending to another astral plane because trying to do this in a way that's nice and friendly without Advanced Custom Fields is bananas.
+
+
wordpress uses its own database for all of this, so you don't have to deal with any markdown or json files; just look to the left sidebar in the admin panel and you'll see a section for "games." you can also optionally use wordpress to manage your signups, but you don't have to and can still collect that data from google forms or airtable or a custom data feed yourself and pipe it in.
## additional notes
+11
_raw-assets/scss/_partials/_global.scss
···
display: inline-block;
vertical-align: middle;
margin-right: 5px;
+
background-color: var(--foreground);
&.web {
mask: url(../images/web.svg);
···
&.sort-desc {
mask: url(../images/sort-desc.svg);
+
}
+
+
.active & {
+
background-color: var(--accent);
}
}
···
main {
padding: 20px;
text-align: center;
+
+
.submissions & {
+
display: grid;
+
grid-template-areas: "filters list";
+
grid-template-columns: 250px 1fr;
+
}
}
footer {
+1 -1
_raw-assets/scss/_partials/_submissions.scss
···
display: grid;
grid-area: list;
grid-template-columns: repeat(4, 1fr);
-
grid-template-rows: auto;
+
grid-template-rows: fit-content(300px);
gap: 10px;
}
+2 -2
assets.sh
···
# copy sass for zola, jekyll, hugo, wordpress
cp -r _raw-assets/scss/* zola/sass/
cp -r _raw-assets/scss/* jekyll/_sass/
-
cp -r _raw-assets/scss/* hugo/scss/
+
cp -r _raw-assets/scss/* hugo/assets/scss/
cat _raw-assets/scss/style.scss >> wordpress/resources/css/app.scss
echo "" >> wordpress/resources/css/app.scss
echo "@source \"../views/\";" > wordpress/resources/css/app.scss
···
cp -r _raw-assets/images/* plain-html/images/
cp -r _raw-assets/images/* plain-php/images/
cp -r _raw-assets/images/* zola/static/images/
-
cp -r _raw-assets/images/* hugo/images/
+
cp -r _raw-assets/images/* hugo/static/images/
cp -r _raw-assets/images/* wordpress/resources/images/
cp -r _raw-assets/images/* astro/src/assets/images/
+1 -1
astro/src/components/Submissions.astro
···
display: grid;
grid-area: list;
grid-template-columns: repeat(4, 1fr);
-
grid-template-rows: auto;
+
grid-template-rows: fit-content(300px);
gap: 10px;
}
</style>
+11
astro/src/layouts/Layout.astro
···
display: inline-block;
vertical-align: middle;
margin-right: 5px;
+
background-color: var(--foreground);
&.web {
mask: url(../images/web.svg);
···
&.sort-desc {
mask: url(../images/sort-desc.svg);
+
}
+
+
.active & {
+
background-color: var(--accent);
}
}
···
main {
padding: 20px;
text-align: center;
+
+
.submissions & {
+
display: grid;
+
grid-template-areas: "filters list";
+
grid-template-columns: 250px 1fr;
+
}
}
footer {
-56
hugo/CONTRIBUTING.md
···
-
# Contributing to Hugo ส•โ€ขแดฅโ€ขส” Bear Blog
-
-
Thank you for your interest in contributing to Hugo ส•โ€ขแดฅโ€ขส” Bear Blog! This Hugo theme aims to maintain the simplicity and elegance of the original [ส•โ€ขแดฅโ€ขส” Bear Blog Platform](https://bearblog.dev/) while enabling you to host your site completely independently. Before contributing, please take a moment to review these guidelines.
-
-
## ๐Ÿค” Have a Question?
-
-
If you have questions about using the theme or implementing specific features:
-
-
1. Check our [existing GitHub issues](https://github.com/janraasch/hugo-bearblog/issues) - your question might already be answered
-
2. Consider posting on the [Hugo Discourse](https://discourse.gohugo.io/) - there's a larger community there that might help, and your question could benefit others
-
-
## ๐Ÿ› Found a Bug?
-
-
If you've discovered a bug:
-
-
1. First, search our [existing issues](https://github.com/janraasch/hugo-bearblog/issues) to see if it's already reported
-
2. If not, create a new issue with:
-
- A clear description of the problem
-
- Steps to reproduce the issue
-
- Expected vs actual behavior
-
- Your Hugo version and configuration
-
- Any relevant error messages or screenshots
-
-
## โœจ Feature Requests
-
-
While we appreciate feature suggestions, please note that Hugo ส•โ€ขแดฅโ€ขส” Bear Blog intentionally maintains a minimal feature set, staying true to the original [ส•โ€ขแดฅโ€ขส” Bear Blog Platform's](https://bearblog.dev/) philosophy.
-
-
Before submitting a feature request:
-
-
1. Review existing issues and discussions - your idea might have been discussed before
-
2. Consider if the feature could be implemented using Hugo's built-in capabilities
-
-
If you decide to submit a feature request, please:
-
- Clearly describe the feature and its use case
-
- Consider providing examples of similar implementations
-
-
## ๐Ÿš€ Pull Requests
-
-
Pull requests are welcome! Please:
-
-
1. Create an issue first to discuss *significant* changes
-
2. Fork the repository and create a new branch for your feature
-
3. Follow the existing code style
-
4. Include appropriate documentation updates
-
5. Test your changes thoroughly
-
-
## ๐Ÿ’ Share Your Experience
-
We love hearing how people are using Hugo ส•โ€ขแดฅโ€ขส” Bear Blog! If you're using the theme for your website, have made interesting customizations, or just want to share your appreciation:
-
-
1. Visit our [issues](https://github.com/janraasch/hugo-bearblog/issues) page
-
2. Select "Share Your Story" template
-
3. Tell us about your experience, share screenshots, or show off your customizations
-
-
Your stories help build our community and might inspire others in their journey!
-
-
Thank you for helping make Hugo ส•โ€ขแดฅโ€ขส” Bear Blog better! ๐ŸŽ‰
+9
hugo/archetypes/game.md
···
+
+++
+
title = "{{ replace .Name "-" " " | title }}"
+
date = "{{ .Date }}"
+
description = "Optional blurb goes here"
+
+
tags = [{{ range $plural, $terms := .Site.Taxonomies }}{{ range $term, $val := $terms }}"{{ printf "%s" $term }}",{{ end }}{{ end }}]
+
+++
+
+
This is the game ยป{{ replace .Name "-" " " | title }}ยซ.
+2
hugo/assets/js/afs.modern.js
···
+
class t{constructor(t=!1,i="info"){this.enabled=t,this.level=i,this.levels={error:0,warn:1,info:2,debug:3}}t(t,...i){if(("error"===t||this.enabled)&&this.levels[t]<=this.levels[this.level]){const e=(new Date).toLocaleTimeString(),s=`[AFS ${t.toUpperCase()}]`;(console[t]||console.log).call(console,s,e,...i)}}error(...t){this.t("error",...t)}warn(...t){this.t("warn",...t)}info(...t){this.t("info",...t)}debug(...t){this.t("debug",...t)}setDebugMode(t,i="info"){const e=this.enabled;this.enabled=!!t,this.levels.hasOwnProperty(i)&&(this.level=i),(this.enabled||e)&&this.t("info",`Debug mode ${this.enabled?"enabled":"disabled"} with level: ${this.level}`)}getState(){return{enabled:this.enabled,level:this.level}}}class i{static defaults={containerSelector:".afs-filter-container",itemSelector:".afs-filter-item",filterButtonSelector:".afs-btn-filter",filterDropdownSelector:".afs-filter-dropdown",searchInputSelector:".afs-filter-search",counterSelector:".afs-filter-counter",sortButtonSelector:".afs-btn-sort",activeClass:"active",hiddenClass:"hidden",activeSortClass:"sort-active",transitionClass:"afs-transition",filterMode:"OR",groupMode:"AND",searchKeys:["title"],debounceTime:300,debug:!1,logLevel:"info",responsive:!0,preserveState:!1,stateExpiry:864e5,observeDOM:!1,dateFormat:"YYYY-MM-DD",counter:{template:"Showing {visible} of {total}",showFiltered:!0,filteredTemplate:"({filtered} filtered)",noResultsTemplate:"No items found",formatter(t){return t.toLocaleString()}},styles:{slider:{ui:{showHistogram:!1,bins:10,track:{radius:"0",background:"#e5e7eb"},selected:{background:"#000"},thumb:{radius:"50%",size:"16px",background:"#000"},histogram:{background:"#e5e7eb",bar:{background:"#000"}}}},pagination:{ui:{button:{background:"transparent",border:"1px solid #000",borderRadius:"4px",padding:"8px 12px",color:"#000",active:{background:"#000",color:"#fff"},hover:{background:"#000",color:"#fff"}}}},colors:{primary:"#000",background:"#e5e7eb",text:"#000",textHover:"#fff"}},slider:{containerClass:"afs-range-slider",trackClass:"afs-range-track",thumbClass:"afs-range-thumb",valueClass:"afs-range-value",selectedClass:"afs-range-selected"},pagination:{enabled:!1,itemsPerPage:10,container:".afs-pagination-container",pageButtonClass:"afs-page-button",activePageClass:"afs-page-active",containerClass:"afs-pagination",scrollToTop:!1,scrollOffset:50,scrollBehavior:"smooth"},animation:{type:"fade",duration:300,easing:"ease-out",inClass:"afs-animation-enter",outClass:"afs-animation-leave"}};constructor(t={}){this.options=this.mergeOptions(i.defaults,t),this.initializeStyles(),this.validate()}initializeStyles(){const t=i.defaults.styles,e=this.options.styles||{};this.options.styles=this.mergeOptions(t,e),this.options.styles.colors={...t.colors,...e.colors||{}}}mergeOptions(t,i){const e={...t};for(const s in i)null===i[s]||"object"!=typeof i[s]||Array.isArray(i[s])?void 0!==i[s]&&(e[s]=i[s]):(t[s]&&"object"==typeof t[s]||(e[s]={}),e[s]=this.mergeOptions(e[s],i[s]));return e}validate(){const t=["containerSelector","itemSelector"];for(const i of t)if("string"!=typeof this.options[i])throw Error(i+" must be a string");if("number"!=typeof this.options.animation?.duration||this.options.animation?.duration<0)throw Error("animation.duration must be a positive number");if(!["OR","AND"].includes(this.options.filterMode.toUpperCase()))throw Error('filterMode must be either "OR" or "AND"');if(!["OR","AND"].includes(this.options.groupMode.toUpperCase()))throw Error('groupMode must be either "OR" or "AND"');if(!Array.isArray(this.options.searchKeys)||0===this.options.searchKeys.length)throw Error("searchKeys must be a non-empty array");if(this.options.counter){if("string"!=typeof this.options.counter.template)throw Error("counter.template must be a string");"boolean"!=typeof this.options.counter.showFiltered&&(this.options.counter.showFiltered=!0),"function"!=typeof this.options.counter.formatter&&(this.options.counter.formatter=t=>t.toLocaleString())}else this.options.counter={...i.defaults.counter}}get(t){return t.split(".").reduce(((t,i)=>t?.[i]),this.options)}set(t,i){const e=t.split("."),s=e.pop();e.reduce(((t,i)=>(i in t||(t[i]={}),t[i])),this.options)[s]=i,this.validate()}update(t){this.options=this.mergeOptions(this.options,t),this.validate()}reset(){this.options={...i.defaults}}export(){return{...this.options}}}class e{constructor(){this.state={filters:{current:new Set(["*"]),groups:new Map,ranges:new Map,dateRanges:new Map,mode:"OR",groupMode:"OR"},search:{query:"",keys:["title"]},sort:{orders:{},current:null},items:{visible:new Set,total:0},pagination:{currentPage:1,itemsPerPage:10,totalPages:0}}}getState(){return this.state}setState(t,i){const e=t.split(".");let s=this.state;for(let t=0;t<e.length-1;t++)e[t]in s||(s[e[t]]={}),s=s[e[t]];s[e[e.length-1]]=i}export(){return{filters:{current:Array.from(this.state.filters.current),groups:Array.from(this.state.filters.groups.entries()),ranges:Array.from(this.state.filters.ranges.entries()),dateRanges:Array.from(this.state.filters.dateRanges.entries()),mode:this.state.filters.mode,groupMode:this.state.filters.groupMode},search:{...this.state.search},sort:{...this.state.sort},pagination:{...this.state.pagination}}}import(t){t.filters&&(this.state.filters.current=new Set(t.filters.current),this.state.filters.groups=new Map(t.filters.groups),this.state.filters.ranges=new Map(t.filters.ranges),this.state.filters.dateRanges=new Map(t.filters.dateRanges),this.state.filters.mode=t.filters.mode,this.state.filters.groupMode=t.filters.groupMode),t.search&&(this.state.search={...t.search}),t.sort&&(this.state.sort={...t.sort}),t.pagination&&(this.state.pagination={...t.pagination})}reset(){this.state={filters:{current:new Set(["*"]),groups:new Map,ranges:new Map,dateRanges:new Map,mode:"OR",groupMode:"OR"},search:{query:"",keys:["title"]},sort:{orders:{},current:null},items:{visible:new Set,total:0},pagination:{currentPage:1,itemsPerPage:10,totalPages:0}}}}class s{constructor(t){this.options=t,this.styleElement=null}createBaseStyles(){const t=this.options.get("hiddenClass")||"hidden",i=this.options.get("itemSelector")||".afs-filter-item",e=this.options.get("filterButtonSelector")||".afs-btn-filter",s=this.options.get("activeClass")||"active",n=this.options.get("animation.duration")||"300ms",r=this.options.get("animation.easing")||"ease-out",a=this.options.get("filterDropdownSelector")||".afs-filter-dropdown",o=this.options.get("styles.colors.primary")||"#000",h=this.options.get("styles.colors.background")||"#e5e7eb",c=this.options.get("styles.colors.text")||"#000",l=this.options.get("styles.colors.textHover")||"#fff",u=this.options.get("styles.button")||{},d=this.options.get("styles.dropdown")||{},p=this.options.get("styles.checkbox")||{},m=this.options.get("styles.radio")||{},f=u.padding||"4px 8px",g=d.padding||"4px 32px 4px 8px",b=u.border||"1px solid "+h,y=d.border||"1px solid "+h,w=u.borderRadius||"4px",$=d.borderRadius||"4px",v=u.fontSize||"14px",S=d.fontSize||"14px",x=u.fontFamily||"inherit",M=d.fontFamily||"inherit",F=u.fontWeight||"normal",C=d.fontWeight||"normal",R=u.lineHeight||"1.5",k=d.lineHeight||"1.5",A=u.letterSpacing||"normal",D=d.letterSpacing||"normal",P=u.textTransform||"none",T=d.textTransform||"none",I=u.boxShadow||"none",E=d.boxShadow||"none",N=u.background||"transparent",O=d.background||"transparent",L=u.color||c,z=d.color||c,U=p.border||"1px solid "+h,q=p.borderRadius||"4px",B=p.background||"transparent",H=p.color||c,Y=p.padding||"8px",_=p.height||"20px",V=p.width||"20px",j=p.activeBorder||"none",X=m.border||"1px solid "+h,G=m.borderRadius||"50%",K=m.background||"transparent",J=m.color||c,W=m.padding||"8px",Q=m.height||"20px",Z=m.width||"20px",tt=m.activeBorder||"none",it=o.match(/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i),et=it?`rgba(${parseInt(it[1],16)}, ${parseInt(it[2],16)}, ${parseInt(it[3],16)}, 0.2)`:"rgba(0, 0, 0, 0.2)",st=`data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='${encodeURIComponent(c)}' d='M6 8L1 3h10z'/%3E%3C/svg%3E`;return`\n /* Hidden state */\n .${t} {\n display: none !important;\n }\n\n /* Filterable items */\n ${i} {\n opacity: 1;\n transform: scale(1);\n filter: blur(0);\n transition: opacity ${n} ${r},\n transform ${n} ${r},\n filter ${n} ${r};\n }\n\n ${i}.${t} {\n opacity: 0;\n transform: scale(0.95);\n filter: blur(5px);\n }\n\n /* Common styles for both buttons and dropdowns */\n ${e} {\n appearance: none;\n -webkit-appearance: none;\n padding: ${f};\n border: ${b};\n border-radius: ${w};\n font-size: ${v};\n font-family: ${x};\n font-weight: ${F};\n letter-spacing: ${A};\n text-transform: ${P};\n background-color: ${N};\n color: ${L};\n cursor: pointer;\n transition: all ${n} ${r};\n line-height: ${R};\n display: inline-flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n margin: 0;\n box-shadow: ${I};\n }\n\n ${a} {\n appearance: none;\n -webkit-appearance: none;\n padding: ${g};\n border: ${y};\n border-radius: ${$};\n font-size: ${S};\n font-family: ${M};\n font-weight: ${C};\n letter-spacing: ${D};\n text-transform: ${T};\n background-color: ${O};\n color: ${z};\n cursor: pointer;\n transition: all ${n} ${r};\n line-height: ${k};\n display: inline-flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n margin: 0;\n box-shadow: ${E};\n }\n\n /* Checkbox styles */\n ${e}[type="checkbox"] {\n position: relative;\n appearance: none;\n -webkit-appearance: none;\n padding: ${Y};\n background-color: ${B};\n color: ${H};\n border: ${U};\n border-radius: ${q};\n height: ${_};\n width: ${V};\n cursor: pointer;\n transition: all ${n} ${r};\n }\n\n ${e}[type="checkbox"]:hover:before {\n position: absolute;\n top: 0;\n left: 0;\n content: "";\n display: block;\n width: 100%;\n height: 100%;\n border-radius: ${q};\n border: ${j};\n }\n \n ${e}.${s}[type="checkbox"]:before {\n position: absolute;\n top: 0;\n left: 0;\n content: "";\n display: block;\n width: 100%;\n height: 100%;\n border-radius: ${q};\n border: ${j};\n }\n\n /* Radio button styles */\n ${e}[type="radio"] {\n position: relative;\n appearance: none;\n -webkit-appearance: none;\n padding: ${W};\n background-color: ${K};\n color: ${J};\n border: ${X};\n border-radius: ${G};\n height: ${Q};\n width: ${Z};\n cursor: pointer;\n transition: all ${n} ${r};\n }\n\n ${e}[type="radio"]:hover:before {\n position: absolute;\n top: 0;\n left: 0;\n content: "";\n display: block;\n width: 100%;\n height: 100%;\n border-radius: ${G};\n border: ${tt};\n }\n \n ${e}.${s}[type="radio"]:before {\n position: absolute;\n top: 0;\n left: 0;\n content: "";\n display: block;\n width: 100%;\n height: 100%;\n border-radius: ${G};\n border: ${tt};\n }\n\n /* Hover state */\n ${e}:hover,{\n border-color: ${o};\n background-color: ${o};\n color: ${l};\n box-shadow: ${u.hover?.boxShadow||d.hover?.boxShadow||"none"};\n }\n\n /* Focus state */\n ${e}:focus,\n ${a}:focus {\n outline: none;\n border-color: ${o};\n box-shadow: 0 0 0 2px ${et};\n }\n\n /* Active state */\n ${e}.${s} {\n background-color: ${o};\n border-color: ${o};\n color: ${l};\n box-shadow: ${u.active?.boxShadow||"none"};\n }\n\n /* Disabled state */\n ${e}:disabled,\n ${a}:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: ${h};\n }\n\n /* Dropdown specific styles */\n ${a} {\n padding: ${g};\n position: relative;\n background-image: url("${st}");\n background-repeat: no-repeat;\n background-position: right 12px center;\n text-align: left;\n }\n\n /* Mobile optimization */\n @media (max-width: 768px) {\n ${e},\n ${a} {\n width: 100%;\n justify-content: flex-start;\n }\n }\n `}addTransitionStyles(){const t=document.createElement("style");t.textContent="\n .afs-transition {\n transition: opacity 300ms ease-in-out,\n transform 300ms ease-in-out,\n filter 300ms ease-in-out !important;\n }\n .afs-hidden {\n opacity: 0;\n pointer-events: none;\n }\n ",document.head.appendChild(t)}createRangeStyles(){const t=this.options.get("styles"),i=this.options.get("slider")||{},e=t.slider,s=t.colors;return`\n /* Range Slider Styles */\n .${i.containerClass||"afs-range-slider"} {\n position: relative;\n width: auto;\n height: 40px;\n margin: 10px 0;\n padding: 0 8px;\n }\n\n .${i.trackClass||"afs-range-track"} {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 100%;\n height: 4px;\n background: ${e.ui.track.background||s.background};\n border-radius: ${e.ui.track.radius||"0"};\n }\n\n .${i.thumbClass||"afs-range-thumb"} {\n position: absolute;\n top: 50%;\n width: ${e.ui.thumb.size||"16px"};\n height: ${e.ui.thumb.size||"16px"};\n background: ${e.ui.thumb.background||s.primary};\n border-radius: ${e.ui.thumb.radius||"50%"};\n transform: translate(-50%, -50%);\n cursor: pointer;\n z-index: 2;\n }\n\n .${i.valueClass||"afs-range-value"} {\n position: absolute;\n top: -20px;\n transform: translateX(-50%);\n font-size: 10px;\n color: ${s.text};\n }\n\n .${i.selectedClass||"afs-range-selected"} {\n position: absolute;\n height: 4px;\n background: ${e.ui.selected.background||s.primary};\n top: 50%;\n transform: translateY(-50%);\n }\n\n /* Histogram Styles */\n .afs-histogram {\n position: absolute;\n bottom: 22px;\n left: 8px;\n right: 8px;\n height: 20px;\n display: flex;\n align-items: flex-end;\n gap: 1px;\n opacity: 0.5;\n }\n\n .afs-histogram-bar {\n flex: 1;\n background-color: ${e.ui.histogram.background||s.background};\n min-height: 4px;\n transition: background-color 0.2s ease;\n }\n\n .afs-histogram-bar.active {\n background-color: ${e.ui.histogram.bar.background||s.primary};\n }\n `}createDateStyles(){const t=this.options.get("styles").colors;return`\n .afs-date-range-container {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n margin: 10px 0;\n }\n\n .afs-date-input-wrapper {\n flex: 1;\n }\n\n .afs-date-input-wrapper label {\n display: block;\n font-size: 0.875rem;\n color: ${t.text};\n margin-bottom: 0.5rem;\n }\n\n .afs-date-input {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid ${t.background};\n border-radius: 0.25rem;\n font-size: 0.875rem;\n color: ${t.text};\n transition: border-color 0.2s ease;\n }\n\n .afs-date-input:focus {\n outline: none;\n border-color: ${t.primary};\n }\n `}createInputRangeStyles(){const t=this.options.get("styles").colors;return`\n .afs-input-range-container {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n margin: 10px 0;\n }\n\n .afs-input-wrapper {\n flex: 1;\n }\n\n .afs-input-label {\n display: block;\n font-size: 0.875rem;\n color: ${t.text};\n margin-bottom: 0.5rem;\n }\n\n .afs-input {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid ${t.background};\n border-radius: 0.25rem;\n font-size: 0.875rem;\n color: ${t.text};\n transition: border-color 0.2s ease;\n }\n\n .afs-input:focus {\n outline: none;\n border-color: ${t.primary};\n }\n `}applyStyles(){try{const t=`\n \n /* Global transition styles */\n ${this.addTransitionStyles()}\n\n /* Base styles */\n ${this.createBaseStyles()}\n\n /* Range slider styles */\n ${this.createRangeStyles()}\n\n /* Date filter styles */\n ${this.createDateStyles()}\n\n /* Pagination styles */\n ${this.createPaginationStyles()}\n\n /* Search styles */\n ${this.createSearchStyles()}\n\n /* Input range styles */\n ${this.createInputRangeStyles()}\n `;this.styleElement?this.styleElement.textContent=t:(this.styleElement=document.createElement("style"),this.styleElement.textContent=t,document.head.appendChild(this.styleElement))}catch(t){const i=this.createBaseStyles();this.styleElement?this.styleElement.textContent=i:(this.styleElement=document.createElement("style"),this.styleElement.textContent=i,document.head.appendChild(this.styleElement))}}createPaginationStyles(){const t=this.options.get("styles"),i=this.options.get("pagination")||{},e=this.options.get("styles").colors,s=i.pageButtonClass||"afs-page-button",n=t.pagination;return`\n .${i.containerClass||"afs-pagination"} {\n display: flex;\n justify-content: center;\n gap: 8px;\n margin-top: 20px;\n }\n\n .${s} {\n padding: ${n.ui.button.padding||"8px 12px"};\n border: ${n.ui.button.border||"1px solid "+e.primary};\n border-radius: ${n.ui.button.borderRadius||"4px"};\n cursor: pointer;\n transition: all 200ms ease-out;\n background: ${n.ui.button.background||"transparent"};\n color: ${n.ui.button.color||e.primary};\n }\n\n .${s}:hover {\n background: ${n.ui.button.hover.background||e.primary};\n color: ${n.ui.button.hover.color||"white"};\n }\n\n .${s}.${i.activePageClass||"afs-page-active"} {\n background: ${n.ui.button.active.background||e.primary};\n color: ${n.ui.button.active.color||"white"};\n }\n\n .${s}:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `}createSearchStyles(){const t=this.options.get("searchInputClass")||"afs-search",i=this.options.get("styles").colors;return`\n .${t} {\n padding: 8px;\n border: 1px solid ${i.background};\n border-radius: 4px;\n width: 100%;\n max-width: 300px;\n transition: border-color 200ms ease-out;\n }\n\n .${t}:focus {\n outline: none;\n border-color: ${i.primary};\n }\n `}updateStyles(t){this.options=t,this.applyStyles()}removeStyles(){this.styleElement&&(this.styleElement.remove(),this.styleElement=null)}}class n{constructor(){this.events=new Map,this.onceEvents=new Map}on(t,i){return this.events.has(t)||this.events.set(t,new Set),this.events.get(t).add(i),()=>this.off(t,i)}once(t,i){const e=(...s)=>{this.off(t,e),i.apply(this,s)};return this.onceEvents.has(t)||this.onceEvents.set(t,new Map),this.onceEvents.get(t).set(i,e),this.on(t,e)}off(t,i){if(this.events.has(t)&&(this.events.get(t).delete(i),0===this.events.get(t).size&&this.events.delete(t)),this.onceEvents.has(t)){const e=this.onceEvents.get(t).get(i);e&&(this.events.get(t)?.delete(e),this.onceEvents.get(t).delete(i)),0===this.onceEvents.get(t).size&&this.onceEvents.delete(t)}}emit(t,...i){this.events.has(t)&&this.events.get(t).forEach((t=>{try{t.apply(this,i)}catch(t){}}))}removeAllListeners(t){t?(this.events.delete(t),this.onceEvents.delete(t)):(this.events.clear(),this.onceEvents.clear())}listenerCount(t){return(this.events.get(t)?.size||0)+(this.onceEvents.get(t)?.size||0)}}class r{constructor(t){this.afs=t,this.options=this.afs.options,this.animations={fade:{in:{opacity:1,transform:"scale(1)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"scale(0.95)",transitionTimingFunction:"ease-out"}},slide:{in:{opacity:1,transform:"translateY(0)",transitionTimingFunction:"ease-in-out"},out:{opacity:0,transform:"translateY(20px)",transitionTimingFunction:"ease-in-out"}},scale:{in:{opacity:1,transform:"scale(1)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"scale(0.8)",transitionTimingFunction:"ease-out"}},rotate:{in:{opacity:1,transform:"rotate(0deg) scale(1)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"rotate(90deg) scale(0.9)",transitionTimingFunction:"ease-out"}},flip:{in:{opacity:1,transform:"rotateY(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"rotateY(180deg)",transitionTimingFunction:"ease-out"}},zoom:{in:{opacity:1,transform:"scale(1.2)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"scale(0.8)",transitionTimingFunction:"ease-out"}},bounce:{in:{opacity:1,transform:"translateY(0)",animation:"bounce 1s cubic-bezier(0.68, -0.55, 0.27, 1.55)"},out:{opacity:0,transform:"translateY(-20px)",animation:"bounceOut 1s ease-out"}},blur:{in:{opacity:1,filter:"blur(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,filter:"blur(5px)",transitionTimingFunction:"ease-out"}},skew:{in:{opacity:1,transform:"skew(0deg)",transitionTimingFunction:"ease-in-out"},out:{opacity:0,transform:"skew(10deg)",transitionTimingFunction:"ease-in-out"}},slideInLeft:{in:{opacity:1,transform:"translateX(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"translateX(-100%)",transitionTimingFunction:"ease-out"}},slideInRight:{in:{opacity:1,transform:"translateX(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"translateX(100%)",transitionTimingFunction:"ease-out"}},fadeInUp:{in:{opacity:1,transform:"translateY(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"translateY(10px)",transitionTimingFunction:"ease-out"}},fadeInDown:{in:{opacity:1,transform:"translateY(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"translateY(-10px)",transitionTimingFunction:"ease-out"}},bounceIn:{in:{opacity:1,transform:"scale(1.05)",transitionTimingFunction:"cubic-bezier(0.68, -0.55, 0.27, 1.55)"},out:{opacity:0,transform:"scale(0.9)",transitionTimingFunction:"ease-out"}}}}applyShowAnimation(t,i="fade"){const e=this.animations[i]?.in||this.animations.fade.in;t.classList.add("afs-transition"),t.style.display=this.afs.filter.getItemDisplayType(t),t.style.visibility="visible",window.innerWidth<=768&&(t.style.filter="none"),requestAnimationFrame((()=>{Object.assign(t.style,{opacity:"0",transform:"scale(0.95)",display:this.afs.filter.getItemDisplayType(t)}),requestAnimationFrame((()=>{Object.assign(t.style,e)}))}));const s=this.afs.options.get("animation.duration")||300;setTimeout((()=>{window.innerWidth<=768?(t.style.transform="",t.style.opacity="1",t.style.filter="none",t.style.transition=""):this.afs.state.getState().items.visible.has(t)&&Object.assign(t.style,{transform:"",opacity:"1",filter:"none",display:this.afs.filter.getItemDisplayType(t)})}),s+50)}applyHideAnimation(t,i="fade"){const e=this.animations[i]?.out||this.animations.fade.out;t.classList.add("afs-transition"),t.style.display=this.afs.filter.getItemDisplayType(t),t.style.visibility="visible",requestAnimationFrame((()=>{Object.assign(t.style,e)}));const s=this.afs.options.get("animation.duration")||300;setTimeout((()=>{this.afs.state.getState().items.visible.has(t)||(t.style.display="none",t.style.visibility="hidden",t.style.opacity="0",t.style.transform="",t.style.filter="none",t.style.transition="")}),s+50)}updateOptions(t){const i=t.duration||300,e=t.timing||"ease-in-out",s=document.querySelector(".afs-transition");s&&(s.textContent=`\n .afs-transition {\n transition: opacity ${i}ms ${e},\n transform ${i}ms ${e},\n filter ${i}ms ${e} !important;\n }\n `)}setAnimation(t){this.animations[t]&&this.afs.options.set("animation.type",t)}}class a{constructor(t){this.afs=t,this.animation=new r(t),this.filterButtons=new Map,this.activeFilters=new Set(["*"]),this.currentFilters=new Set(["*"]),this.filterGroups=new Map,this.sortOrders=new Map,this.itemDisplayTypes=new Map,this.isScrolling=!1,this.scrollTimeout=null,this.setupFilters()}setupFilters(){this.afs.logger.debug("Setting up filters");const t=this.afs.options.get("filterButtonSelector");if(!t)return;document.querySelectorAll(t).forEach((t=>{const i=t.dataset.filter;i?(this.filterButtons.set(t,i),this.bindFilterEvent(t)):this.afs.logger.warn("Filter button missing data-filter attribute:",t)}));const i=this.afs.options.get("filterDropdownSelector");i&&document.querySelectorAll(i).forEach((t=>{this.bindDropdownEvent(t)})),this.afs.items.forEach((t=>{const i=window.getComputedStyle(t);this.itemDisplayTypes.set(t,"none"===i.display?"block":i.display)})),this.afs.logger.debug("Filters initialized")}setLogic(t){if("boolean"==typeof t)this.afs.options.set("filterMode",t?"AND":"OR");else{const i=t.toUpperCase();if(!["OR","AND"].includes(i))return void this.afs.logger.warn("Invalid filter mode: "+t);this.afs.options.set("filterMode",i)}this.afs.logger.debug("Filter logic set to: "+this.afs.options.get("filterMode")),this.applyFilters()}clearAllFilters(){this.afs.logger.debug("Clearing all filters and resetting selects"),this.activeFilters.clear(),this.activeFilters.add("*"),this.filterButtons.forEach(((t,i)=>{i.classList.remove(this.afs.options.get("activeClass"))})),this.filterGroups.clear();const t=this.findAllButton();t&&t.classList.add(this.afs.options.get("activeClass"));const i=this.afs.options.get("filterDropdownSelector")||".afs-filter-dropdown";document.querySelectorAll(i).forEach((t=>{const i=t.getAttribute("data-filter-type")||t.id.replace("Filter","").toLowerCase(),e=Array.from(t.options).find((t=>{const e=t.value;return"*"===e||e===i+":all"||e.endsWith(":all")}));if(e){t.value=e.value;const i=new Event("change",{bubbles:!0,cancelable:!0});t.dispatchEvent(i)}else{t.selectedIndex=0;const i=new Event("change",{bubbles:!0,cancelable:!0});t.dispatchEvent(i)}})),this.sortOrders.clear(),this.applyFilters(),this.afs.urlManager.updateURL(),this.afs.emit("filtersCleared"),this.afs.logger.debug("All filters cleared and selects reset")}bindDropdownEvent(t){this.afs.logger.debug("Binding filter event to dropdown:",t),t.addEventListener("change",(()=>{const i=t.value,[e]=i.split(":");"*"===i||i.endsWith(":all")||this.activeFilters.delete("*"),this.activeFilters.forEach((t=>{t.startsWith(e+":")&&this.activeFilters.delete(t)})),"*"===i||i.endsWith(":all")?0===this.activeFilters.size&&this.activeFilters.add("*"):this.activeFilters.add(i),!i&&t.options.length>0&&(t.selectedIndex=0,this.activeFilters.add(t.options[0].value)),this.applyFilters(),this.afs.urlManager.updateURL(),this.afs.emit("filterChanged",{type:e,value:i||t.options[0]?.value,activeFilters:Array.from(this.activeFilters)})}))}bindFilterEvent(t){this.afs.logger.debug("Binding filter event to button:",t),t.addEventListener("click",(()=>{const i=this.filterButtons.get(t);i&&("*"===i?this.resetFilters():this.toggleFilter(i,t),this.afs.urlManager.updateURL())}))}resetFilters(){this.afs.logger.debug("Resetting filters"),this.activeFilters.clear(),this.filterButtons.forEach(((t,i)=>{i.classList.remove(this.afs.options.get("activeClass"))})),this.activeFilters.add("*");const t=this.findAllButton();t&&t.classList.add(this.afs.options.get("activeClass")),this.filterGroups.clear();const i=[];this.afs.items.forEach((t=>{const e=new Promise((i=>{t.classList.remove(this.afs.options.get("hiddenClass")),requestAnimationFrame((()=>{this.animation.applyShowAnimation(t,this.afs.options.get("animation.type")),setTimeout(i,this.afs.options.get("animation.duration")||300)}))}));i.push(e)}));const e=new Set(this.afs.items);this.afs.state.setState("items.visible",e),Promise.all(i).then((()=>{this.afs.updateCounter(),this.afs.urlManager.updateURL(),this.afs.emit("filtersReset")}))}findAllButton(){for(const[t,i]of this.filterButtons.entries())if("*"===i)return t;return null}handleFilterClick(t){const i=t.dataset.filter;this.afs.logger.debug("Filter clicked:",i),"*"===i?this.resetFilters():this.toggleFilter(i,t),this.filter(),this.updateURL()}toggleFilter(t,i){this.activeFilters.delete("*");const e=this.findAllButton();if(e&&e.classList.remove(this.afs.options.get("activeClass")),"radio"===i.type||"radio"===i.getAttribute("type")){const e=i.name||i.getAttribute("name");e&&document.querySelectorAll(`input[name="${e}"]`).forEach((t=>{t.classList.remove(this.afs.options.get("activeClass"));const i=this.filterButtons.get(t);i&&this.activeFilters.delete(i)})),i.classList.add(this.afs.options.get("activeClass")),this.activeFilters.add(t)}else if(i.classList.contains(this.afs.options.get("activeClass"))){if(i.classList.remove(this.afs.options.get("activeClass")),this.activeFilters.delete(t),0===this.activeFilters.size)return void this.resetFilters()}else i.classList.add(this.afs.options.get("activeClass")),this.activeFilters.add(t);this.applyFilters(),this.afs.emit("filterToggled",{filter:t,activeFilters:Array.from(this.activeFilters)}),this.afs.logger.debug("Filter toggled:",t)}applyFilters(){const t=Array.from(this.activeFilters);this.afs.logger.debug("Active filters:",t);const i=new Set(this.afs.state.getState().items.visible),e=new Set;this.afs.items.forEach((t=>{(this.activeFilters.has("*")||this.itemMatchesFilters(t))&&e.add(t)})),this.afs.state.setState("items.visible",e),this.activeFilters.has("*");const s=[];this.afs.items.forEach((t=>{const i=new Promise((i=>{e.has(t)?(t.classList.remove(this.afs.options.get("hiddenClass")),t.style.display=this.getItemDisplayType(t),requestAnimationFrame((()=>{this.animation.applyShowAnimation(t,this.afs.options.get("animation.type")),setTimeout(i,parseFloat(this.afs.options.get("animation.duration"))||300)}))):(t.classList.add(this.afs.options.get("hiddenClass")),t.style.display="none",requestAnimationFrame((()=>{this.animation.applyHideAnimation(t,this.afs.options.get("animation.type")),setTimeout(i,parseFloat(this.afs.options.get("animation.duration"))||300)})))}));s.push(i)})),Promise.all(s).then((()=>{this.afs.items.forEach((t=>{e.has(t)?(this.showItem(t),t.style.display=this.getItemDisplayType(t),t.style.opacity="1"):(t.style.display="none",t.classList.add(this.afs.options.get("hiddenClass")))})),this.afs.updateCounter(),this.afs.urlManager.updateURL(),this.afs.emit("filtersApplied",{activeFilters:t,visibleItems:e.size})})),this.emitFilterEvents(i,e)}itemMatchesFilters(t){if(this.activeFilters.has("*"))return!0;const i=new Set(t.dataset.categories?.split(" ")||[]);return"AND"===(this.afs.options.get("filterMode")||"OR")?this.itemMatchesAllFilters(i):this.itemMatchesAnyFilter(i)}itemMatchesAnyFilter(t){return Array.from(this.activeFilters).some((i=>"*"===i||t.has(i)))}itemMatchesAllFilters(t){return Array.from(this.activeFilters).every((i=>"*"===i||t.has(i)))}itemMatchesFilterGroups(t){const i=Array.from(this.filterGroups.values()).map((i=>0===i.filters.size||("OR"===i.operator?Array.from(i.filters).some((i=>t.has(i))):Array.from(i.filters).every((i=>t.has(i))))));return"OR"===this.afs.options.get("groupMode")?i.some((t=>t)):i.every((t=>t))}emitFilterEvents(t,i){const e=new Set([...i].filter((i=>!t.has(i)))),s=new Set([...t].filter((t=>!i.has(t))));this.afs.emit("filter",{activeFilters:Array.from(this.activeFilters),visibleItems:i.size,added:e.size,removed:s.size}),e.size>0&&this.afs.emit("itemsShown",{items:e}),s.size>0&&this.afs.emit("itemsHidden",{items:s})}addFilterGroup(t,i,e="OR"){if(this.afs.logger.debug("Adding filter group: "+t),!Array.isArray(i))return void this.afs.logger.error("Filters must be an array");const s=e.toUpperCase();["AND","OR"].includes(s)||(this.afs.logger.warn(`Invalid operator: ${e}, defaulting to OR`),e="OR"),this.filterGroups.set(t,{filters:new Set(i),operator:s}),this.applyFilters()}removeFilterGroup(t){this.filterGroups.delete(t)&&(this.afs.logger.debug("Removed filter group: "+t),0===this.filterGroups.size?this.resetFilters():this.applyFilters())}setGroupMode(t){const i=t.toUpperCase();["AND","OR"].includes(i)?(this.afs.options.set("groupMode",i),this.afs.logger.debug("Set group mode to: "+i),this.applyFilters()):this.afs.logger.warn("Invalid group mode: "+t)}addFilter(t){if(this.afs.logger.debug("Adding filter: "+t),"*"===t)return void this.resetFilters();const[i]=t.split(":");this.activeFilters.forEach((t=>{t.startsWith(i+":")&&this.activeFilters.delete(t)})),this.activeFilters.delete("*"),this.activeFilters.add(t),this.filterButtons.forEach(((i,e)=>{i===t?e.classList.add(this.afs.options.get("activeClass")):"*"===i&&e.classList.remove(this.afs.options.get("activeClass"))})),this.applyFilters()}removeFilter(t){this.afs.logger.debug("Removing filter: "+t),this.activeFilters.delete(t),this.filterButtons.forEach(((i,e)=>{i===t&&e.classList.remove(this.afs.options.get("activeClass"))})),0===this.activeFilters.size?this.resetFilters():this.applyFilters()}setFilterMode(t){this.afs.logger.debug("Setting filter mode to: "+t);const i=t.toUpperCase();["AND","OR"].includes(i)?(this.afs.options.set("filterMode",i),this.afs.logger.debug("Set filter mode to: "+i),this.applyFilters()):this.afs.logger.warn("Invalid filter mode: "+t)}getActiveFilters(){return new Set(this.activeFilters)}getFilterGroups(){return new Map(this.filterGroups)}addFilterButton(t,i){i?(this.filterButtons.set(t,i),this.bindFilterEvent(t),this.afs.logger.debug("Added filter button for: "+i)):this.afs.logger.warn("Filter value required for new filter button")}sortWithOrder(t){this.afs.logger.debug("Sorting by "+t);try{const i=Array.from(this.afs.items),e="asc"===(this.sortOrders.get(t)||"asc")?"desc":"asc";this.sortOrders.set(t,e);const s=this.determineSortType(i[0],t);return i.sort(((i,n)=>{const r=this.getSortValue(i,t,s),a=this.getSortValue(n,t,s);return this.compareValues(r,a,e)})),this.reorderItems(i),this.afs.emit("sort",{key:t,order:e}),this.afs.logger.info(`Sorted items by ${t} in ${e} order`),e}catch(t){return this.afs.logger.error("Sort error:",t),null}}shuffle(){this.afs.logger.debug("Shuffling items");try{const t=Array.from(this.afs.items);for(let i=t.length-1;i>0;i--){const e=Math.floor(Math.random()*(i+1));[t[i],t[e]]=[t[e],t[i]]}this.reorderItems(t),this.sortOrders.clear(),this.afs.emit("shuffled",{itemCount:t.length}),this.afs.logger.debug("Items shuffled successfully")}catch(t){this.afs.logger.error("Shuffle error:",t)}}determineSortType(t,i){this.afs.logger.debug("Determining sort type for "+i);const e=t.dataset[i];return e?isNaN(e)?/^\d{4}-\d{2}-\d{2}/.test(e)?"date":"string":"number":"string"}getSortValue(t,i,e){const s=t.dataset[i];switch(e){case"number":return parseFloat(s)||0;case"date":return new Date(s).getTime()||0;default:return(s||"").toLowerCase()}}compareValues(t,i,e){if(null==t)return"asc"===e?1:-1;if(null==i)return"asc"===e?-1:1;const s=t<i?-1:t>i?1:0;return"asc"===e?s:-s}reorderItems(t){const i=document.createDocumentFragment();t.forEach((t=>i.appendChild(t))),this.afs.container.appendChild(i)}getCurrentSortOrder(t){return this.sortOrders.get(t)||"asc"}clearSortOrders(){this.afs.logger.debug("Clearing all sort orders"),this.sortOrders.clear(),this.afs.emit("sortCleared")}clearAllFilters(){this.afs.logger.debug("Clearing all filters and search"),this.activeFilters.clear(),this.activeFilters.add("*"),this.filterButtons.forEach(((t,i)=>{i.classList.remove(this.afs.options.get("activeClass"))}));const t=this.findAllButton();t&&t.classList.add(this.afs.options.get("activeClass")),document.querySelectorAll(this.afs.options.get("filterButtonSelector")+'[type="checkbox"]').forEach((t=>{t.classList.contains(this.afs.options.get("activeClass"))&&(t.checked=!1,t.classList.remove(this.afs.options.get("activeClass")))})),this.afs.search&&this.afs.search.setValue(""),this.filterGroups.clear(),this.sortOrders.clear(),this.applyFilters(),this.afs.urlManager&&this.afs.urlManager.updateURL(),this.afs.emit("filtersCleared"),this.afs.logger.info("All filters cleared")}refresh(){this.afs.logger.debug("Refreshing view"),this.applyFilters(),this.afs.updateCounter()}removeFilterButton(t){this.filterButtons.delete(t),t.removeEventListener("click",this.handleFilterClick)}destroy(){this.filterButtons.forEach(((t,i)=>{this.removeFilterButton(i)})),this.filterButtons.clear(),this.activeFilters.clear(),this.filterGroups.clear(),this.afs.logger.debug("Filter functionality destroyed")}getItemDisplayType(t){return this.itemDisplayTypes.get(t)||"block"}showItem(t){t.classList.remove(this.afs.options.get("hiddenClass"));const i=this.getItemDisplayType(t);"none"===t.style.display&&(t.style.display=i&&"none"!==i?i:""),t.style.opacity="1",t.style.visibility="visible",t.style.filter="none",t.style.transform=""}}const o=(t,i,e=!1)=>{let s;return function(...n){const r=this,a=e&&!s;clearTimeout(s),s=setTimeout((()=>{s=null,e||t.apply(r,n)}),i),a&&t.apply(r,n)}};class h{constructor(t){this.afs=t,this.activeRanges=new Map}addInputRange({key:t,container:i,min:e,max:s,step:n=1,label:r=""}){if(this.afs.logger.debug("Adding input range for "+t),!i)return void this.afs.logger.error("Container element required for input range");const a=this.calculateMinMax(t);e=e??a.min,s=s??a.max;const o=this.createInputElements(r),h=this.initializeState(e,s,n);this.appendElements(i,o),this.setupEventHandlers(o,h,t),this.activeRanges.set(t,{state:h,elements:o}),this.updateInputUI(t),this.afs.logger.info("Input range added for "+t)}calculateMinMax(t){try{const i=Array.from(this.afs.items).map((i=>{if(!i||!i.dataset||!i.dataset[t])return null;const e=parseFloat(i.dataset[t]);return isNaN(e)?null:e})).filter((t=>null!==t));return 0===i.length?{min:0,max:100}:{min:Math.min(...i),max:Math.max(...i)}}catch(t){return this.afs.logger.error("Error calculating range:",t),{min:0,max:100}}}createInputElements(t){const i=document.createElement("div");if(i.className="afs-input-range-container",t){const e=document.createElement("div");e.className="afs-input-range-label",e.textContent=t,i.appendChild(e)}const e=document.createElement("div");e.className="afs-input-wrapper";const s=document.createElement("label");s.textContent="Min",s.className="afs-input-label";const n=document.createElement("input");n.type="number",n.className="afs-input min",e.appendChild(s),e.appendChild(n);const r=document.createElement("div");r.className="afs-input-wrapper";const a=document.createElement("label");a.textContent="Max",a.className="afs-input-label";const o=document.createElement("input");return o.type="number",o.className="afs-input max",r.appendChild(a),r.appendChild(o),i.appendChild(e),i.appendChild(r),{container:i,minInput:n,maxInput:o}}initializeState(t,i,e){return{min:t,max:i,step:e,currentMin:t,currentMax:i}}appendElements(t,i){t.appendChild(i.container)}setupEventHandlers(t,i,e){const{minInput:s,maxInput:n}=t,r=o((()=>{const t=parseFloat(s.value),r=parseFloat(n.value);isNaN(t)||isNaN(r)||(i.currentMin=Math.max(i.min,Math.min(r,t)),i.currentMax=Math.min(i.max,Math.max(t,r)),this.updateInputUI(e),this.applyFilter(e))}),300);s.addEventListener("input",r),n.addEventListener("input",r)}updateInputUI(t){try{const{state:i,elements:e}=this.activeRanges.get(t),{minInput:s,maxInput:n}=e;s.min=i.min,s.max=i.max,s.step=i.step,n.min=i.min,n.max=i.max,n.step=i.step,s.value=i.currentMin,n.value=i.currentMax}catch(t){this.afs.logger.error("Error updating input UI:",t)}}applyFilter(t){this.afs.logger.info("Applying input filter for "+t);const{state:i}=this.activeRanges.get(t);this.afs.items.forEach((e=>{try{if(!e||!e.dataset||!e.dataset[t])return void this.afs.hideItem(e);const s=parseFloat(e.dataset[t]);if(isNaN(s))return void this.afs.hideItem(e);s>=i.currentMin&&s<=i.currentMax?this.afs.showItem(e):this.afs.hideItem(e)}catch(t){this.afs.logger.error("Error filtering item:",t),this.afs.hideItem(e)}})),this.afs.updateCounter(),this.afs.urlManager.updateURL(),this.afs.emit("inputRangeFilter",{key:t,min:i.currentMin,max:i.currentMax})}getRange(t){const i=this.activeRanges.get(t);return i?{min:i.state.currentMin,max:i.state.currentMax}:null}setRange(t,i,e){const s=this.activeRanges.get(t);s&&(s.state.currentMin=i,s.state.currentMax=e,this.updateInputUI(t),this.applyFilter(t))}removeInputRange(t){const i=this.activeRanges.get(t);i&&(i.elements.container.remove(),this.activeRanges.delete(t),this.afs.logger.info("Input range removed for "+t))}}class c{constructor(t){this.afs=t,this.searchInput=null,this.searchKeys=["title"],this.minSearchLength=2,this.highlightClass="afs-highlight",this.setupSearch()}setupSearch(){const t=this.afs.options.get("searchInputSelector");t&&(this.searchInput=document.querySelector(t),this.searchInput?(this.searchKeys=this.afs.options.get("searchKeys")||this.searchKeys,this.minSearchLength=this.afs.options.get("minSearchLength")||this.minSearchLength,this.bindSearchEvents(),this.afs.logger.debug("Search functionality initialized")):this.afs.logger.warn("Search input not found: "+t))}bindSearchEvents(){if(!this.searchInput)return;const t=o((t=>{this.search(t.target.value)}),this.afs.options.get("debounceTime")||300);this.searchInput.addEventListener("input",t),this.searchInput.addEventListener("search",(t=>{t.target.value||this.clearSearch()})),this.searchInput.addEventListener("keypress",(t=>{"Enter"===t.key&&(t.preventDefault(),this.search(t.target.value))}))}search(t){this.afs.logger.debug("Performing search:",t);const i=this.normalizeQuery(t);this.afs.state.setState("search.query",i);let e=0;if(i)if(i.length<this.minSearchLength)this.afs.logger.debug("Search query too short");else try{const t=this.createSearchRegex(i),s=[];this.afs.items.forEach((i=>{const n=this.getItemSearchText(i),r=t.test(n),a=new Promise((s=>{r?(this.afs.showItem(i),this.highlightMatches(i,t),e++):(this.afs.hideItem(i),this.removeHighlights(i)),setTimeout(s,this.afs.options.get("animation.duration")||300)}));s.push(a)})),Promise.all(s).then((()=>{this.afs.items.forEach((t=>{this.afs.state.getState().items.visible.has(t)?(t.style.display="",t.style.opacity="1"):t.style.display="none"})),this.afs.urlManager.updateURL(),this.afs.emit("search",{query:i,matches:e,total:this.afs.items.length}),this.afs.updateCounter(),this.afs.logger.info(`Search complete. Found ${e} matches`)}))}catch(t){this.afs.logger.error("Search error:",t)}else this.clearSearch()}normalizeQuery(t){return t.toLowerCase().trim().replace(/\s+/g," ")}createSearchRegex(t){const i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").split(" ").filter(Boolean).map((t=>`(?=.*${t})`)).join("");return RegExp(i,"i")}getItemSearchText(t){return this.searchKeys.map((i=>t.dataset[i]||"")).join(" ").toLowerCase()}highlightMatches(t,i){this.afs.options.get("highlightMatches")&&this.searchKeys.forEach((i=>{const e=t.querySelector(`[data-search-key="${i}"]`);if(!e)return;const s=e.textContent,n=this.afs.state.getState().search.query.split(" ");let r=s;n.forEach((t=>{if(!t)return;const i=RegExp(`(${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")})`,"gi");r=r.replace(i,`<span class="${this.highlightClass}">$1</span>`)})),e.innerHTML=r}))}removeHighlights(t){this.afs.options.get("highlightMatches")&&this.searchKeys.forEach((i=>{const e=t.querySelector(`[data-search-key="${i}"]`);e&&e.querySelectorAll("."+this.highlightClass).forEach((t=>{t.replaceWith(t.textContent)}))}))}clearSearch(){this.afs.logger.debug("Clearing search"),this.searchInput&&(this.searchInput.value=""),this.afs.state.setState("search.query","");const t=[];this.afs.items.forEach((i=>{const e=new Promise((t=>{this.afs.showItem(i),this.removeHighlights(i),setTimeout(t,this.afs.options.get("animation.duration")||300)}));t.push(e)})),Promise.all(t).then((()=>{this.afs.items.forEach((t=>{t.style.display="",t.style.opacity="1"})),this.afs.urlManager.updateURL(),this.afs.emit("searchCleared"),this.afs.updateCounter()}))}setValue(t){this.searchInput&&(this.searchInput.value=t),this.search(t)}getValue(){return this.afs.state.getState().search.query}updateConfig({searchKeys:t,minSearchLength:i,highlightClass:e,debounceTime:s}={}){t&&(this.searchKeys=t),i&&(this.minSearchLength=i),e&&(this.highlightClass=e),s&&this.bindSearchEvents()}destroy(){this.searchInput&&(this.searchInput.removeEventListener("input",this.debouncedSearch),this.searchInput.removeEventListener("search",this.handleClear),this.searchInput.removeEventListener("keypress",this.handleEnter)),this.clearSearch()}}class l{constructor(t){this.afs=t,this.sortButtons=new Map,this.setupSort()}setupSort(){const t=this.afs.options.get("sortButtonSelector");if(!t)return;const i=document.querySelectorAll(t);0!==i.length?(i.forEach((t=>{const i=t.dataset.sortKey;i?(this.sortButtons.set(t,{key:i,direction:t.dataset.sortDirection||"asc"}),this.bindSortEvent(t)):this.afs.logger.warn("Sort button missing data-sort-key attribute:",t)})),this.afs.logger.debug("Sort functionality initialized")):this.afs.logger.warn("No sort buttons found with selector:",t)}bindSortEvent(t){this.afs.logger.debug("Binding sort event to button:",t),t.addEventListener("click",(()=>{const i=this.sortButtons.get(t);i&&(i.direction="asc"===i.direction?"desc":"asc",this.sortButtons.set(t,i),this.updateSortButtonState(t,i),this.sort(i.key,i.direction))}))}updateSortButtonState(t,i){this.sortButtons.forEach(((t,i)=>{i.classList.remove(this.afs.options.get("activeSortClass"))})),t.classList.add(this.afs.options.get("activeSortClass"));const e=t.querySelector(".sort-direction");e&&(e.textContent="asc"===i.direction?"โ†‘":"โ†“")}sort(t,i="asc"){this.afs.logger.debug(`Sorting by ${t} in ${i} order`);try{if(!t)throw Error("Sort key is required");["asc","desc"].includes(i.toLowerCase())||(this.afs.logger.warn(`Invalid sort direction: ${i}, defaulting to "asc"`),i="asc"),this.afs.state.setState("sort.current",{key:t,direction:i});const e=Array.from(this.afs.items);if(0===e.length)return this.afs.logger.info("No items to sort"),!0;const s=this.determineSortType(e[0],t);return this.afs.logger.debug(`Determined sort type for key "${t}": ${s}`),e.sort(((e,n)=>{try{const r=this.getSortValue(e,t,s),a=this.getSortValue(n,t,s);return this.compareValues(r,a,i)}catch(t){return this.afs.logger.error("Error during sort comparison:",t),0}})),this.reorderItems(e),this.afs.urlManager.updateURL(),this.afs.emit("sort",{key:t,direction:i,sortType:s,itemCount:e.length}),this.afs.logger.info(`Sorted ${e.length} items by ${t} ${i} (${s})`),!0}catch(t){return this.afs.logger.error("Sort error:",t),!1}}determineSortType(t,i){if(!t)return this.afs.logger.warn("Cannot determine sort type: No items available for key "+i),"string";if(!t.dataset||!(i in t.dataset))return this.afs.logger.warn("Item missing dataset key: "+i,t),"string";const e=t.dataset[i];return null==e||""===e?"string":!isNaN(parseFloat(e))&&isFinite(e)?"number":/^\d{4}-\d{2}-\d{2}/.test(e)?isNaN(new Date(e).getTime())?"string":"date":"string"}getSortValue(t,i,e){if(!t)return this.afs.logger.warn("Undefined item in getSortValue"),null;if(!t.dataset||!{}.hasOwnProperty.call(t.dataset,i))return this.afs.logger.warn(`Missing data attribute: ${i} on item`,t),"number"===e||"date"===e?0:"";const s=t.dataset[i];if(null==s||""===s)return"number"===e||"date"===e?0:"";switch(e){case"number":const t=parseFloat(s);return isNaN(t)?0:t;case"date":const i=new Date(s).getTime();return isNaN(i)?0:i;default:return(s+"").toLowerCase()}}compareValues(t,i,e){const s="asc"===e?1:-1;return t===i?0:null==t?1:null==i?-1:t>i?s:-s}reorderItems(t){const i=this.afs.options.get("containerSelector"),e=document.querySelector(i);if(!e)return void this.afs.logger.error("Container not found:",i);let s=!1;for(let i=0;i<t.length-1;i++)if(!(t[i].compareDocumentPosition(t[i+1])&Node.DOCUMENT_POSITION_FOLLOWING)){s=!0;break}if(!s)return void this.afs.logger.debug("Items already in correct order, skipping DOM operations");const n=document.createDocumentFragment();t.forEach((t=>n.appendChild(t))),e.appendChild(n),this.afs.logger.debug(`Reordered ${t.length} items`)}sortMultiple(t){this.afs.logger.debug("Sorting by multiple criteria:",t);try{if(!Array.isArray(t)||0===t.length)throw Error("Sort criteria must be a non-empty array");t.forEach(((t,i)=>{if(!t.key)throw Error(`Sort criterion at index ${i} missing key property`);t.direction&&!["asc","desc"].includes(t.direction.toLowerCase())&&(this.afs.logger.warn(`Invalid sort direction in criterion ${i}: ${t.direction}, defaulting to "asc"`),t.direction="asc")}));const i=Array.from(this.afs.items);if(0===i.length)return this.afs.logger.info("No items to sort"),!0;const e={};return t.forEach((t=>{e[t.key]||(e[t.key]=this.determineSortType(i[0],t.key))})),i.sort(((i,s)=>{for(const{key:n,direction:r="asc"}of t)try{const t=e[n]||"string",a=this.getSortValue(i,n,t),o=this.getSortValue(s,n,t),h=this.compareValues(a,o,r);if(0!==h)return h}catch(t){this.afs.logger.error(`Error comparing values for key ${n}:`,t)}return 0})),this.reorderItems(i),t.length>0&&this.afs.state.setState("sort.current",t[0]),this.afs.urlManager.updateURL(),this.afs.emit("multiSort",{criteria:t,itemCount:i.length,sortTypes:e}),this.afs.logger.info(`Multi-sorted ${i.length} items with ${t.length} criteria`),!0}catch(t){return this.afs.logger.error("Multiple sort error:",t),!1}}sortWithComparator(t,i){this.afs.logger.debug(`Sorting by ${t} with custom comparator`);try{if(!t)throw Error("Sort key is required");if("function"!=typeof i)throw Error("Comparator must be a function");const e=Array.from(this.afs.items);return 0===e.length?(this.afs.logger.info("No items to sort"),!0):(e.sort(((e,s)=>{try{return e.dataset&&s.dataset&&t in e.dataset&&t in s.dataset?i(e.dataset[t],s.dataset[t]):(this.afs.logger.warn(`Missing data attribute ${t} in one or both items being compared`),0)}catch(t){return this.afs.logger.error("Error in custom comparator:",t),0}})),this.reorderItems(e),this.afs.emit("customSort",{key:t,comparatorName:i.name||"anonymous",itemCount:e.length}),this.afs.logger.info(`Custom sorted ${e.length} items by ${t}`),!0)}catch(t){return this.afs.logger.error("Custom sort error:",t),!1}}shuffle(){this.afs.logger.debug("Shuffling items");try{const t=Array.from(this.afs.items);if(0===t.length)return this.afs.logger.info("No items to shuffle"),!0;if(1===t.length)return this.afs.logger.info("Only one item to shuffle, no change needed"),!0;this.afs.logger.debug(`Shuffling ${t.length} items`);for(let i=t.length-1;i>0;i--){const e=Math.floor(Math.random()*(i+1));[t[i],t[e]]=[t[e],t[i]]}return this.reorderItems(t),this.afs.state.setState("sort.current",null),this.sortButtons.forEach(((t,i)=>{i.classList.remove(this.afs.options.get("activeSortClass"));const e=i.querySelector(".sort-direction");e&&(e.textContent="")})),this.afs.urlManager.updateURL(),this.afs.emit("shuffle",{itemCount:t.length}),this.afs.logger.info(`Shuffled ${t.length} items`),!0}catch(t){return this.afs.logger.error("Shuffle error:",t),!1}}reset(){this.afs.logger.debug("Resetting sort");try{this.afs.state.setState("sort.current",null),this.sortButtons.forEach(((t,i)=>{i.classList.remove(this.afs.options.get("activeSortClass"));const e=i.querySelector(".sort-direction");e&&(e.textContent="")}));let t=0;return this.sortButtons.forEach(((i,e)=>{i.direction="asc",this.sortButtons.set(e,i),t++})),this.afs.urlManager.updateURL(),this.afs.emit("sortReset",{buttonCount:t}),this.afs.logger.info(`Sort reset: ${t} sort buttons reset to default state`),!0}catch(t){return this.afs.logger.error("Sort reset error:",t),!1}}getCurrentSort(){return this.afs.state.getState().sort.current}addSortButton(t,i,e="asc"){i?(this.sortButtons.set(t,{key:i,direction:e}),this.bindSortEvent(t),this.afs.logger.debug("Added sort button for "+i)):this.afs.logger.warn("Sort key required for new sort button")}removeSortButton(t){this.sortButtons.has(t)&&(t.removeEventListener("click",this.bindSortEvent),this.sortButtons.delete(t),this.afs.logger.debug("Removed sort button"))}destroy(){this.sortButtons.forEach(((t,i)=>{this.removeSortButton(i)})),this.sortButtons.clear(),this.afs.logger.debug("Sort functionality destroyed")}}class u{constructor(t){this.afs=t,this.container=null,this.animation=new r(t),this.options=this.afs.options.get("pagination"),this.setupPagination()}setupPagination(){if(this.afs.logger.debug("Setting up pagination"),!this.afs.options.get("pagination.enabled"))return void this.afs.state.setState("pagination",{currentPage:1,itemsPerPage:this.options.itemsPerPage||10,totalPages:1});this.container=document.createElement("div"),this.container.className=this.options.containerClass;const t=document.querySelector(this.afs.options.get("pagination.container"));t?(t.appendChild(this.container),this.afs.state.setState("pagination",{currentPage:1,itemsPerPage:this.options.itemsPerPage,totalPages:0}),this.bindEvents(),this.update(),this.afs.logger.debug("Pagination initialized")):this.afs.logger.error("Items container not found.")}bindEvents(){this.afs.options.get("pagination.enabled")&&this.container&&(this.afs.on("filter",(()=>this.update())),this.afs.on("search",(()=>this.update())),this.afs.on("sort",(()=>this.update())),this.container.addEventListener("click",(t=>{const i=t.target.closest("button");if(!i)return;const e=i.dataset.page;e&&this.goToPage(parseInt(e,10))})))}update(){if(!this.afs.options.get("pagination.enabled"))return void this.showAllItems();const t=Array.from(this.afs.state.getState().items.visible),i=this.afs.state.getState().pagination.itemsPerPage,e=Math.max(1,Math.ceil(t.length/i)),s=this.afs.state.getState().pagination;let n=s.currentPage;n>e&&(n=e),this.afs.state.setState("pagination",{...s,currentPage:n,totalPages:e}),this.updateVisibility(t),this.container&&this.renderPagination(),this.afs.urlManager.updateURL(),this.afs.emit("pagination",{currentPage:n,totalPages:e,itemsPerPage:i,visibleItems:t.length})}updateVisibility(t){if(!this.afs.options.get("pagination.enabled"))return void this.showAllItems();const{currentPage:i,itemsPerPage:e}=this.afs.state.getState().pagination,s=(i-1)*e,n=s+e;this.afs.items.forEach((t=>{t.style.display="none",t.classList.add(this.afs.options.get("hiddenClass"))}));const r=t.slice(s,n);0===r.length&&t.length>0?this.goToPage(1):requestAnimationFrame((()=>{r.forEach((t=>{t.style.display="",t.classList.remove(this.afs.options.get("hiddenClass")),requestAnimationFrame((()=>{this.animation.applyShowAnimation(t,this.options.animationType||"fade")}))}))}))}renderPagination(){if(!this.container||!this.afs.options.get("pagination.enabled"))return;const{currentPage:t,totalPages:i}=this.afs.state.getState().pagination;if(this.container.innerHTML="",i<=1)return void(this.container.style.display="none");this.container.style.display="flex";const e=this.createPaginationControls(t,i);this.container.appendChild(e)}createPaginationControls(t,i){const e=document.createDocumentFragment();if(this.options.showPrevNext){const i=this.createPageButton("โ€น",t-1,{disabled:1===t,class:"afs-pagination-prev"});e.appendChild(i)}e.appendChild(this.createPageButton("1",1,{active:1===t}));const s=this.calculatePageRange(t,i);s.start>2&&e.appendChild(this.createEllipsis());for(let n=s.start;n<=s.end;n++)1!==n&&n!==i&&e.appendChild(this.createPageButton(""+n,n,{active:t===n}));if(s.end<i-1&&e.appendChild(this.createEllipsis()),i>1&&e.appendChild(this.createPageButton(""+i,i,{active:t===i})),this.options.showPrevNext){const s=this.createPageButton("โ€บ",t+1,{disabled:t===i,class:"afs-pagination-next"});e.appendChild(s)}return e}createPageButton(t,i,{active:e=!1,disabled:s=!1,class:n=""}={}){const r=document.createElement("button");return r.textContent=t,r.dataset.page=i,r.classList.add(this.options.pageButtonClass||"afs-page-button"),n&&r.classList.add(n),e&&r.classList.add(this.options.activePageClass||"afs-page-active"),s&&(r.disabled=!0),r}createEllipsis(){const t=document.createElement("span");return t.textContent="...",t.classList.add("afs-pagination-ellipsis"),t}calculatePageRange(t,i){const e=this.options.maxButtons||7;let s=Math.max(2,t-Math.floor((e-3)/2)),n=Math.min(i-1,s+e-3);return n-s<e-3&&(s=Math.max(2,n-(e-3))),{start:s,end:n}}goToPage(t){const i=this.afs.state.getState().pagination,e=Math.max(1,Math.min(t,i.totalPages));e!==i.currentPage&&(this.afs.state.setState("pagination.currentPage",e),this.update(),this.options.scrollToTop&&window.innerWidth>768&&setTimeout((()=>this.scrollToTop()),100),this.afs.emit("pageChanged",{previousPage:i.currentPage,currentPage:e,totalPages:i.totalPages}))}scrollToTop(){const t=document.querySelector(this.afs.options.get("pagination.container"));t?window.scrollTo({top:t.offsetTop-this.options.scrollOffset,behavior:"smooth"}):this.afs.logger.warn("Scroll container not found.")}setPaginationMode(t){this.afs.logger.debug("Setting pagination mode to: "+t),this.afs.options.set("pagination.enabled",t),t?this.setupPagination():(this.container.remove(),this.showAllItems()),this.afs.emit("paginationModeChanged",{enabled:t})}showAllItems(){try{const t=Array.from(this.afs.state.getState().items.visible),i=window.innerWidth<=768;requestAnimationFrame((()=>{t.forEach((t=>{t.style.display="",t.classList.remove(this.afs.options.get("hiddenClass")),i?(t.style.opacity="1",t.style.transform="",t.style.filter="none"):requestAnimationFrame((()=>{this.animation.applyShowAnimation(t,this.options?.animationType||"fade")}))})),i&&setTimeout((()=>{t.forEach((t=>{t.style.opacity="1",t.style.transform="",t.style.filter="none"}))}),50)}))}catch(t){this.afs.logger.error("Error in showAllItems:",t),this.afs.items.forEach((t=>{this.afs.state.getState().items.visible.has(t)&&(t.style.display="",t.classList.remove(this.afs.options.get("hiddenClass")),t.style.opacity="1",t.style.filter="none")}))}}}class d{constructor(t){this.afs=t,this.defaultParams=new URLSearchParams,this.setupPopStateHandler()}initialize(){this.loadFromURL()}setupPopStateHandler(){window.addEventListener("popstate",(()=>{this.loadFromURL()}))}updateURL(){this.afs.logger.debug("Updating URL state");const t=new URLSearchParams,i=this.afs.state.getState(),e=this.afs.filter.getActiveFilters();i.filters.current=e,this.addFiltersToURL(t,i),this.addRangesToURL(t,i),this.addSearchToURL(t,i),this.addSortToURL(t,i),this.addPaginationToURL(t,i),this.pushState(t)}addFiltersToURL(t,i){const e=i.filters;if(0===e.current.size||1===e.current.size&&e.current.has("*"))return;const s={};for(const t of e.current)if("*"!==t){const[i,e]=t.split(":");s[i]||(s[i]=new Set),s[i].add(e)}Object.entries(s).forEach((([i,e])=>{t.set(i,Array.from(e).join(","))})),"OR"!==e.mode&&t.set("filterMode",e.mode.toLowerCase()),e.groups.size>0&&"OR"!==e.groupMode&&t.set("groupMode",e.groupMode.toLowerCase()),e.groups.forEach(((i,e)=>{t.set("group_"+e,Array.from(i.filters).join(",")),"OR"!==i.operator&&t.set("groupOp_"+e,i.operator.toLowerCase())}))}addRangesToURL(t,i){i.filters.ranges.forEach(((i,e)=>{const{currentMin:s,currentMax:n}=i;s===i.min&&n===i.max||t.set("range_"+e,`${s},${n}`)})),i.filters.dateRanges.forEach(((i,e)=>{const{start:s,end:n}=i;t.set("dateRange_"+e,`${s.toISOString()},${n.toISOString()}`)}))}addSearchToURL(t,i){i.search.query&&t.set("search",i.search.query)}addSortToURL(t,i){if(i.sort.current){const{key:e,direction:s}=i.sort.current;t.set("sort",`${e},${s}`)}}addPaginationToURL(t,i){const{currentPage:e,itemsPerPage:s}=i.pagination;this.afs.options.get("pagination.enabled")&&(e>1&&t.set("page",""+e),s!==this.afs.options.get("pagination.itemsPerPage")&&t.set("perPage",""+s))}pushState(t){const i=""+t,e=`${window.location.pathname}${i?"?"+i:""}`;e!==window.location.href&&(window.history.pushState({},"",e),this.afs.logger.debug("URL updated:",e))}loadFromURL(){this.afs.logger.debug("Loading state from URL");const t=new URLSearchParams(window.location.search);try{this.afs.filter&&this.afs.filter.clearAllFilters();const i=t.get("filterMode");i&&this.afs.filter&&this.afs.filter.setFilterMode(i.toUpperCase());const e=Array.from(t.entries()).filter((([t])=>this.isRegularFilter(t)));e.length>0&&this.afs.filter&&(this.afs.filter.activeFilters.clear(),e.forEach((([t,i])=>{i&&i.split(",").forEach((i=>{this.afs.filter.addFilter(`${t}:${i}`)}))}))),this.afs.filter&&this.afs.filter.applyFilters(),this.processSearchFromURL(t),this.processSortFromURL(t),this.processPaginationFromURL(t),this.afs.emit("urlStateLoaded",{params:Object.fromEntries(t)}),this.afs.logger.info("State loaded from URL")}catch(t){this.afs.logger.error("Error loading state from URL:",t),this.afs.filter&&this.afs.filter.clearAllFilters()}}processFiltersFromURL(t){const i=this.afs.state.getState();let e=!1;const s=t.get("filterMode");s&&(i.filters.mode=s.toUpperCase());const n=t.get("groupMode");n&&(i.filters.groupMode=n.toUpperCase());for(const[s,n]of t.entries())this.isRegularFilter(s)&&n.split(",").filter(Boolean).forEach((t=>{e=!0,i.filters.current.add(`${s}:${t}`)}));for(const[e,s]of t.entries())if(e.startsWith("group_")){const n=e.replace("group_",""),r=t.get("groupOp_"+n)?.toUpperCase()||"OR";i.filters.groups.set(n,{filters:new Set(s.split(",")),operator:r})}e||0!==i.filters.groups.size||i.filters.current.add("*")}processRangesFromURL(t){const i=this.afs.state.getState();for(const[e,s]of t.entries())if(e.startsWith("range_")){const t=e.replace("range_",""),[n,r]=s.split(",").map(Number);i.filters.ranges.set(t,{currentMin:n,currentMax:r})}for(const[e,s]of t.entries())if(e.startsWith("dateRange_")){const t=e.replace("dateRange_",""),[n,r]=s.split(",").map((t=>new Date(t)));i.filters.dateRanges.set(t,{start:n,end:r})}}processSearchFromURL(t){const i=t.get("search")||"";this.afs.state.setState("search.query",i),this.afs.options.get("searchInput")&&(this.afs.options.get("searchInput").value=i)}processSortFromURL(t){const i=t.get("sort");if(i){const[t,e]=i.split(",");this.afs.state.setState("sort.current",{key:t,direction:e})}}processPaginationFromURL(t){const i=parseInt(t.get("page"))||1,e=parseInt(t.get("perPage"))||this.afs.options.get("pagination.itemsPerPage");this.afs.state.setState("pagination",{currentPage:i,itemsPerPage:e})}isRegularFilter(t){return!(["search","sort","page","perPage","filterMode","groupMode"].includes(t)||t.startsWith("group_")||t.startsWith("groupOp_")||t.startsWith("range_")||t.startsWith("dateRange_"))}clearURL(){window.history.pushState({},"",window.location.pathname),this.afs.state.reset(),this.afs.filter&&this.afs.filter.clearAllFilters()}getURLParams(){return new URLSearchParams(window.location.search)}hasParams(){return window.location.search.length>1}getParam(t){return new URLSearchParams(window.location.search).get(t)}}class p{constructor(t){this.afs=t,this.activeRanges=new Map,this.options=this.afs.options.get("slider"),this.afs.styleManager||(this.afs.styleManager=new s(this.afs.options)),this.afs.styleManager.applyStyles()}addRangeSlider({key:t,type:i,container:e,min:s,max:n,step:r=1,ui:a}){if(this.afs.logger.debug("Adding range slider for "+t),!e)return void this.afs.logger.error("Container element required for range slider");const o=this.calculateMinMax(t,i);s=s??o.min,n=n??o.max;const h={...this.afs.options.get("styles.slider.ui")||{showHistogram:!1,bins:10},...a},c=h.showHistogram?this.calculateHistogramData(t,h.bins):{counts:[],binEdges:[],max:0},l=this.createSliderElements(c,h),u=this.initializeState(s,n,r,i);u.ui=h,h.showHistogram&&(u.histogram=c),this.appendElements(e,l),this.setupEventHandlers(l,u,t),this.activeRanges.set(t,{state:u,elements:l}),this.updateSliderUI(t),h.showHistogram&&this.setupHistogramHighlight(l,u,c.binEdges),this.afs.logger.info("Range slider added for "+t)}calculateMinMax(t,i){const e=Array.from(this.afs.items).map((e=>{const s=e.dataset[t];return"date"===i?new Date(s).getTime():parseFloat(s)})).filter((t=>!isNaN(t)));return{min:Math.min(...e),max:Math.max(...e)}}createSliderElements(t,i){const e=(this.afs.options.get("styles")||this.afs.styleManager.defaultStyles).colors||this.afs.styleManager.defaultStyles.colors,s=this.afs.options.get("slider")||{},n=document.createElement("div");n.className="afs-range-container";const r=document.createElement("div");r.className=s.containerClass;const a=document.createElement("div");if(a.className=s.trackClass,i?.showHistogram&&t?.counts?.length>0){const i=this.createHistogramBars(t,e);r.appendChild(i)}const o=document.createElement("div");o.className=s.selectedClass;const h=document.createElement("div");h.className=s.thumbClass;const c=document.createElement("div");c.className=s.thumbClass;const l=document.createElement("div");l.className=s.valueClass;const u=document.createElement("div");return u.className=s.valueClass,r.appendChild(a),r.appendChild(o),r.appendChild(h),r.appendChild(c),r.appendChild(l),r.appendChild(u),n.appendChild(r),{container:n,slider:r,track:a,selectedRange:o,minThumb:h,maxThumb:c,minValue:l,maxValue:u}}createHistogram(t,i){const e=document.createElement("div");return e.className="afs-histogram",t.forEach(((t,s)=>{const n=document.createElement("div");n.className="afs-histogram-bar",n.style.height=t+"%",n.style.backgroundColor=i.histogram,e.appendChild(n)})),e}calculateHistogramData(t,i=10){try{const e=Array.from(this.afs.items).map((i=>parseFloat(i.dataset[t]))).filter((t=>!isNaN(t)));if(0===e.length)return{counts:[],binEdges:[],max:0};const s=Math.min(...e),n=Math.max(...e),r=(n-s)/i,a=Array(i).fill(0),o=Array(i+1);for(let t=0;t<=i;t++)o[t]=s+t*r;e.forEach((t=>{t!==n?a[Math.floor((t-s)/r)]++:a[a.length-1]++}));const h=Math.max(...a);return{counts:a.map((t=>Math.max(20,Math.round(t/h*100)))),binEdges:o,max:h,min:s,max:n}}catch(t){return this.afs.logger.error("Error calculating histogram:",t),{counts:[],binEdges:[],max:0}}}setupHistogramHighlight(t,i,e){const s=t.slider.querySelectorAll(".afs-histogram-bar"),n=()=>{const t=i.currentMin,n=i.currentMax;s.forEach(((i,s)=>{e[s]>=t&&e[s+1]<=n?i.classList.add("active"):i.classList.remove("active")}))};this.afs.on("rangeFilter",(()=>n())),n()}createHistogramBars(t,i){const{counts:e}=t,s=document.createElement("div");return s.className="afs-histogram",e.forEach((t=>{const i=document.createElement("div");i.className="afs-histogram-bar",i.style.height=t+"%",s.appendChild(i)})),s}initializeState(t,i,e,s){return{min:t,max:i,currentMin:t,currentMax:i,step:e,type:s,isDragging:!1}}appendElements(t,i){const{slider:e,track:s,selectedRange:n,minThumb:r,maxThumb:a,minValue:o,maxValue:h}=i;e.appendChild(s),e.appendChild(n),e.appendChild(r),e.appendChild(a),e.appendChild(o),e.appendChild(h),t.appendChild(e)}setupEventHandlers(t,i,e){const{minThumb:s,maxThumb:n}=t,r=s=>n=>{n.preventDefault(),i.isDragging=!0;const r=n=>{const r=(a=n).touches?a.touches[0]:a;var a;this.createMoveHandler(t,i,e,s)(r)},a=()=>{i.isDragging=!1,window.removeEventListener("mousemove",r),window.removeEventListener("mouseup",a),window.removeEventListener("touchmove",r),window.removeEventListener("touchend",a),window.removeEventListener("touchcancel",a),this.applyFilter(e)};window.addEventListener("mousemove",r),window.addEventListener("mouseup",a),window.addEventListener("touchmove",r,{passive:!1}),window.addEventListener("touchend",a),window.addEventListener("touchcancel",a)};s.addEventListener("mousedown",r(!0)),s.addEventListener("touchstart",r(!0),{passive:!1}),n.addEventListener("mousedown",r(!1)),n.addEventListener("touchstart",r(!1),{passive:!1})}updateSliderUI(t){const{state:i,elements:e}=this.activeRanges.get(t),{minThumb:s,maxThumb:n,selectedRange:r,minValue:a,maxValue:o}=e,h=i.max-i.min,c=(i.currentMax-i.min)/h*100,l=Math.max(0,Math.min((i.currentMin-i.min)/h*100,100)),u=Math.max(0,Math.min(c,100));s.style.left=l+"%",n.style.left=u+"%",r.style.left=l+"%",r.style.width=u-l+"%";const d="date"===i.type?t=>new Date(t).toLocaleDateString():t=>t.toFixed(2);a.textContent=d(i.currentMin),o.textContent=d(i.currentMax),a.style.left=l+"%",o.style.left=u+"%",a.style.transform=l<5?"translateX(0)":l>95?"translateX(-100%)":"translateX(-50%)",o.style.transform=u<5?"translateX(0)":u>95?"translateX(-100%)":"translateX(-50%)"}createMoveHandler(t,i,e,s){this.afs.logger.debug("Creating move handler for "+e);const{track:n}=t;return o((t=>{const r=t.touches?t.touches[0].clientX:t.clientX,a=n.getBoundingClientRect(),o=a.width,h=.05*o,c=Math.round((i.min+(i.max-i.min)*Math.min(Math.max(0,(r-a.left-h)/(o-2*h)),1))/i.step)*i.step;s?i.currentMin=Math.min(c,i.currentMax):i.currentMax=Math.max(c,i.currentMin),this.updateSliderUI(e)}),16)}applyFilter(t){this.afs.logger.debug("Applying range filter for "+t);const{state:i}=this.activeRanges.get(t);this.afs.items.forEach((e=>{const s="date"===i.type?new Date(e.dataset[t]).getTime():parseFloat(e.dataset[t]);s>=i.currentMin&&s<=i.currentMax?this.afs.showItem(e):this.afs.hideItem(e)})),this.afs.updateCounter(),this.afs.urlManager.updateURL(),this.afs.emit("rangeFilter",{key:t,min:i.currentMin,max:i.currentMax})}getRangeValues(t){const i=this.activeRanges.get(t);return i?{min:i.state.currentMin,max:i.state.currentMax,type:i.state.type}:null}setRangeValues(t,i,e){const s=this.activeRanges.get(t);s&&(s.state.currentMin=i,s.state.currentMax=e,this.updateSliderUI(t),this.applyFilter(t))}removeRangeSlider(t){const i=this.activeRanges.get(t);i&&(i.elements.slider.remove(),this.activeRanges.delete(t),this.afs.logger.info("Range slider removed for "+t))}}class m{constructor(t){this.afs=t,this.activeDateRanges=new Map,this.defaultFormat=this.afs.options.get("dateFormat")||"YYYY-MM-DD"}addDateRange({key:t,container:i,minDate:e,maxDate:s,format:n=this.defaultFormat}){if(this.afs.logger.debug("Adding date range for "+t),!i)return void this.afs.logger.error("Container element required for date range");const r=this.calculateMinMaxDates(t);e=e??r.min,s=s??r.max;const a=this.createDateElements(),o=this.initializeState(e,s,n);this.appendElements(i,a),this.setupEventHandlers(a,o,t),this.activeDateRanges.set(t,{state:o,elements:a}),this.updateDateUI(t),this.afs.logger.info("Date range added for "+t)}calculateMinMaxDates(t){try{const i=Array.from(this.afs.items).map((i=>{if(!i||!i.dataset||!i.dataset[t])return null;const e=new Date(i.dataset[t]);return isNaN(e.getTime())?null:e})).filter((t=>null!==t));if(0===i.length){const t=new Date;return{min:new Date(t.getFullYear(),0,1),max:new Date(t.getFullYear(),11,31)}}return{min:new Date(Math.min(...i)),max:new Date(Math.max(...i))}}catch(t){this.afs.logger.error("Error calculating date range:",t);const i=new Date;return{min:new Date(i.getFullYear(),0,1),max:new Date(i.getFullYear(),11,31)}}}createDateElements(){this.afs.logger.debug("Creating date picker elements");const t=document.createElement("div");t.className="afs-date-range-container";const i=document.createElement("div");i.className="afs-date-input-wrapper";const e=document.createElement("label");e.textContent="Start Date";const s=document.createElement("input");s.type="date",s.className="afs-date-input start-date";const n=document.createElement("div");n.className="afs-date-input-wrapper";const r=document.createElement("label");r.textContent="End Date";const a=document.createElement("input");return a.type="date",a.className="afs-date-input end-date",i.appendChild(e),i.appendChild(s),n.appendChild(r),n.appendChild(a),t.appendChild(i),t.appendChild(n),{container:t,startInput:s,endInput:a}}initializeState(t,i,e){return{minDate:t,maxDate:i,currentStartDate:t,currentEndDate:i,format:e}}appendElements(t,i){t.appendChild(i.container)}setupEventHandlers(t,i,e){this.afs.logger.debug("Setting up event handlers for date range "+e);const{startInput:s,endInput:n}=t,r=o((()=>{const t=new Date(s.value),r=new Date(n.value);isNaN(t.getTime())||isNaN(r.getTime())||(i.currentStartDate=t,i.currentEndDate=r,this.applyDateFilter(e))}),300);s.addEventListener("change",r),n.addEventListener("change",r)}updateDateUI(t){try{const{state:i,elements:e}=this.activeDateRanges.get(t),{startInput:s,endInput:n}=e,r=t=>{try{const i=new Date(t);if(isNaN(i.getTime()))throw Error("Invalid date");return i.toISOString().split("T")[0]}catch(t){return this.afs.logger.error("Error formatting date:",t),""}};s.min=r(i.minDate),s.max=r(i.maxDate),n.min=r(i.minDate),n.max=r(i.maxDate),s.value=r(i.currentStartDate),n.value=r(i.currentEndDate)}catch(t){this.afs.logger.error("Error updating date UI:",t)}}applyDateFilter(t){this.afs.logger.info("Applying date filter for "+t);const{state:i}=this.activeDateRanges.get(t);this.afs.items.forEach((e=>{try{if(!e||!e.dataset||!e.dataset[t])return void this.afs.hideItem(e);const s=new Date(e.dataset[t]);if(isNaN(s.getTime()))return void this.afs.hideItem(e);const n=new Date(i.currentStartDate);n.setHours(0,0,0,0);const r=new Date(i.currentEndDate);r.setHours(23,59,59,999);const a=new Date(s);a.setHours(0,0,0,0),a>=n&&a<=r?this.afs.showItem(e):this.afs.hideItem(e)}catch(t){this.afs.logger.error("Error filtering item by date:",t),this.afs.hideItem(e)}})),this.afs.updateCounter(),this.afs.urlManager.updateURL(),this.afs.emit("dateFilter",{key:t,startDate:i.currentStartDate,endDate:i.currentEndDate})}getDateRange(t){const i=this.activeDateRanges.get(t);return i?{startDate:i.state.currentStartDate,endDate:i.state.currentEndDate}:null}setDateRange(t,i,e){const s=this.activeDateRanges.get(t);s&&(s.state.currentStartDate=i,s.state.currentEndDate=e,this.updateDateUI(t),this.applyDateFilter(t))}removeDateRange(t){const i=this.activeDateRanges.get(t);i&&(i.elements.container.remove(),this.activeDateRanges.delete(t),this.afs.logger.info("Date range removed for "+t))}}const f="1.3.11";class g extends n{constructor(t={}){super(),this.initializeCore(t)}initializeCore(n){try{this.options=new i(n);const r=this.options.get("debug"),a=this.options.get("logLevel");this.logger=new t(r,a),this.logger.debug("Logger initialized with debug:",r,"level:",a),this.state=new e,this.styleManager=new s(this.options),this.initializeDOM(),this.initializeFeatures(),this.setupLifecycle()}catch(t){throw t}}initializeDOM(){if(this.logger.debug("Initializing DOM elements"),this.container=document.querySelector(this.options.get("containerSelector")),!this.container)throw Error("Container not found: "+this.options.get("containerSelector"));this.items=this.container.querySelectorAll(this.options.get("itemSelector")),0===this.items.length&&this.logger.warn("No items found in container"),this.state.setState("items.total",this.items.length),this.state.setState("items.visible",new Set(this.items))}initializeFeatures(){this.logger.debug("Initializing features"),this.filter=new a(this),this.search=new c(this),this.sort=new l(this),this.rangeFilter=new p(this),this.urlManager=new d(this),this.dateFilter=new m(this),this.pagination=new u(this),this.inputRangeFilter=new h(this),this.styleManager.applyStyles(),this.urlManager.initialize()}setupLifecycle(){this.options.get("responsive")&&window.addEventListener("resize",this.handleResize.bind(this)),this.options.get("preserveState")&&document.addEventListener("visibilitychange",this.handleVisibilityChange.bind(this)),this.options.get("observeDOM")&&this.setupMutationObserver(),this.emit("initialized",{itemCount:this.items.length,options:this.options.export()})}showItem(t){const i=this.state.getState().items.visible;i.add(t),this.state.setState("items.visible",i),t.classList.remove(this.options.get("hiddenClass")),t.style.opacity="0",t.style.transform="scale(0.95)",t.style.display="";const e=this.options.get("transitionClass");t.classList.contains(e)||t.classList.add(e),requestAnimationFrame((()=>{requestAnimationFrame((()=>{t.style.opacity="1",t.style.transform="scale(1)"}))}));const s=this.options.get("animation.duration")||300;setTimeout((()=>{i.has(t)&&(t.style.transform="",t.style.opacity="")}),s)}hideItem(t){const i=this.state.getState().items.visible;i.delete(t),this.state.setState("items.visible",i);const e=this.options.get("transitionClass");t.classList.contains(e)||t.classList.add(e),requestAnimationFrame((()=>{t.style.opacity="0",t.style.transform="scale(0.95)"}));const s=this.options.get("animation.duration")||300;setTimeout((()=>{i.has(t)||(t.classList.add(this.options.get("hiddenClass")),t.style.transform="",t.style.opacity="")}),s)}addItems(t){const i=Array.isArray(t)?t:[t],e=document.createDocumentFragment();i.forEach((t=>{e.appendChild(t),this.state.getState().items.visible.add(t)})),this.container.appendChild(e),this.items=this.container.querySelectorAll(this.options.get("itemSelector")),this.filter.applyFilters()}removeItems(t){const i=Array.isArray(t)?t:[t],e=this.state.getState().items.visible;i.forEach((t=>{e.delete(t),t.remove()})),this.items=this.container.querySelectorAll(this.options.get("itemSelector")),this.updateCounter()}saveState(){if(!this.options.get("preserveState"))return;const t={filters:Array.from(this.filter.getActiveFilters()),search:this.search.getValue(),sort:this.sort.getCurrentSort(),pagination:this.pagination.getPageInfo(),timestamp:Date.now()};sessionStorage.setItem("afs_state",JSON.stringify(t)),this.logger.debug("State saved")}restoreState(){if(this.options.get("preserveState"))try{const t=sessionStorage.getItem("afs_state");if(!t)return;const i=JSON.parse(t);if(Date.now()-i.timestamp>this.options.get("stateExpiry"))return void localStorage.removeItem("afs_state");this.setState(i),this.logger.debug("State restored")}catch(t){this.logger.error("Error restoring state:",t)}}getState(){return this.state.export()}setState(t){this.state.import(t),this.refresh()}updateCounter(){const t=document.querySelector(this.options.get("counterSelector"));if(t)try{const e=this.items.length,s=this.state.getState().items.visible.size,n=e-s,r=this.options.get("counter")||i.defaults.counter,a=r.template||"Showing {visible} of {total}",o=r.formatter||(t=>t.toLocaleString()),h=o(s),c=o(e),l=o(n);let u=a.replace("{visible}",h).replace("{total}",c).replace("{filtered}",l);n>0&&r.showFiltered&&(u+=" "+(r.filteredTemplate||"({filtered} filtered)").replace("{filtered}",l)),0===s&&r.noResultsTemplate&&(u=r.noResultsTemplate),t.textContent=u,this.emit("counterUpdated",{total:e,visible:s,filtered:n,formattedTotal:c,formattedVisible:h,formattedFiltered:l})}catch(i){this.logger.error("Error updating counter:",i),t.textContent=`${this.state.getState().items.visible.size}/${this.items.length}`}}updateOptions(t){this.options.update(t),this.styleManager.updateStyles(t),this.refresh()}refresh(){this.logger.debug("Refreshing AFS"),this.items=this.container.querySelectorAll(this.options.get("itemSelector")),this.state.setState("items.total",this.items.length),this.filter.applyFilters(),this.search.search(this.search.getValue()),this.options.get("pagination.enabled")&&this.pagination.update(),this.emit("refreshed",{itemCount:this.items.length})}handleResize=(()=>o((()=>{this.emit("resize")}),250))();handleVisibilityChange(){document.hidden?(this.emit("hidden"),this.saveState()):(this.emit("visible"),this.restoreState())}setupMutationObserver(){new MutationObserver((t=>{t.some((t=>"childList"===t.type))&&this.refresh()})).observe(this.container,{childList:!0,subtree:!0})}getVersion(){return f}isFeatureSupported(t){return!!{search:!!this.search,pagination:!0,animation:void 0!==document.createElement("div").style.transition,urlState:"function"==typeof window.history.pushState,localStorage:(()=>{try{return localStorage.setItem("test","test"),localStorage.removeItem("test"),!0}catch(t){return!1}})()}[t]}destroy(){this.logger.debug("Destroying AFS instance"),window.removeEventListener("resize",this.handleResize),document.removeEventListener("visibilitychange",this.handleVisibilityChange),this.filter.destroy(),this.search.destroy(),this.sort.destroy(),this.pagination.destroy(),this.rangeFilter.destroy(),this.styleManager.removeStyles(),this.state.reset(),sessionStorage.removeItem("afs_state"),this.items.forEach((t=>{t.style="",t.classList.remove(this.options.get("hiddenClass"),this.options.get("activeClass"))})),this.emit("destroyed")}}export{g as AFS,f as VERSION};
+
//# sourceMappingURL=afs.modern.js.map
+66
hugo/assets/js/home.js
···
+
const startContent = document.getElementById('startDate') ? document.getElementById('startDate').textContent : null;
+
const startDate = document.getElementById('startDate') ? document.getElementById('startDate').getAttribute('data-raw') : null;
+
const endContent = document.getElementById('endDate') ? document.getElementById('endDate').textContent : null;
+
const endDate = document.getElementById('endDate') ? document.getElementById('endDate').getAttribute('data-raw') : null;
+
+
// Date formatting stuff. You probably only need to touch locale and time zone.
+
const locale = 'en-US';
+
const timeZone = 'America/Chicago';
+
+
// DON'T EDIT BELOW THIS LINE
+
// unless you know what you're doing.
+
+
const start = new Date(startDate);
+
const end = new Date(endDate);
+
const now = Date.now();
+
+
const dateElt = document.getElementById('dates');
+
+
const daysElt = document.getElementById('days');
+
const hoursElt = document.getElementById('hours');
+
const minutesElt = document.getElementById('minutes');
+
const secondsElt = document.getElementById('seconds');
+
+
const list = document.getElementById('list');
+
+
const dayMult = 24*60*60;
+
const hourMult = 60*60;
+
const minuteMult = 60;
+
+
const countdownTick = () => {
+
const now = Date.now();
+
let diff;
+
if (now < start.getTime()) {
+
// Jam hasn't started yet
+
diff = (start.getTime() - now) / 1000; // get total # of seconds
+
} else if (now < end.getTime()) {
+
// Jam has started but not ended
+
diff = (end.getTime() - now) / 1000;
+
} else {
+
// Jam has ended
+
dates.innerHTML = `The jam is now over. It ran from <b>${startContent}</b> to <b>${endContent}</b>. <a href="submissions.html">View ${numEntries} ${numEntries !== 1 ? 'entries' : 'entry'}`
+
}
+
+
if (diff) {
+
const days = Math.floor(diff / dayMult);
+
diff = diff - (days * dayMult);
+
const hours = Math.floor(diff / hourMult);
+
diff = diff - (hours * hourMult);
+
const minutes = Math.floor(diff / minuteMult);
+
diff = diff - (minutes * minuteMult);
+
const seconds = Math.floor(diff);
+
daysElt.textContent = days;
+
hoursElt.textContent = hours;
+
minutesElt.textContent = minutes;
+
secondsElt.textContent = seconds;
+
}
+
}
+
+
if (document.querySelector('.clock')) {
+
countdownTick();
+
if (now < end.getTime()) {
+
setInterval(() => {
+
countdownTick();
+
}, 1000);
+
}
+
}
+3
hugo/assets/scss/_partials/_fonts.scss
···
+
@import url('https://fonts.googleapis.com/css2?family=Knewave&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap');
+
/* if you want to use different fonts, you can use other stuff from google fonts
+
if you don't want to use google, you may want to look into hosting your own fonts locally */
+116
hugo/assets/scss/_partials/_game.scss
···
+
.game {
+
main {
+
display: grid;
+
grid-template-areas: "header header" "screenshots stuff";
+
text-align: left;
+
border-bottom: 1px var(--accent) solid;
+
padding-bottom: 0;
+
+
h2 {
+
margin: 0;
+
+
a {
+
font-size: .9rem;
+
margin-left: 10px;
+
display: inline-block;
+
vertical-align: middle;
+
}
+
}
+
+
h3 {
+
margin: 0;
+
}
+
+
.blurb {
+
margin: 1em 0;
+
}
+
+
.game-header {
+
margin: -20px -20px 0;
+
width: calc(100% + 40px);
+
border-bottom: 1px var(--accent) solid;
+
padding: 20px;
+
text-align: left;
+
grid-area: header;
+
}
+
+
.jamsub {
+
font-size: .8em;
+
font-style: italic;
+
color: color-mix(in srgb-linear, var(--foreground), var(--background) 15%);
+
margin: 0;
+
}
+
}
+
+
.screenshots {
+
border-right: 1px var(--accent) solid;
+
grid-area: screenshots;
+
padding: 20px;
+
+
.gallery {
+
display: grid;
+
gap: 10px;
+
grid-template-columns: repeat(2, 1fr);
+
grid-template-rows: auto;
+
grid-template-areas: "featured featured";
+
+
a, button {
+
position: relative;
+
padding-top: 75%;
+
width: 100%;
+
+
img {
+
position: absolute;
+
top: 0;
+
left: 0;
+
width: 100%;
+
height: 100%;
+
object-fit: cover;
+
}
+
}
+
+
& > :first-child {
+
grid-area: featured;
+
}
+
}
+
}
+
+
.interaction {
+
grid-area: stuff;
+
}
+
+
.downloads {
+
padding: 20px;
+
+
ul {
+
list-style: none;
+
margin: 1em 0;
+
padding: 0;
+
+
li {
+
margin-bottom: 10px;
+
}
+
}
+
+
.size {
+
color: color-mix(in srgb-linear, var(--foreground), var(--background) 20%);
+
}
+
+
.platforms-label {
+
display: inline-block;
+
width: 1px;
+
overflow: hidden;
+
text-indent: -999px;
+
}
+
+
.icon {
+
width: 24px;
+
height: 24px;
+
background-color: color-mix(in srgb-linear, var(--foreground), var(--background) 20%);
+
}
+
}
+
+
.comments {
+
border-top: 1px var(--accent) solid;
+
}
+
}
+52
hugo/assets/scss/_partials/_game_list_item.scss
···
+
.item {
+
text-align: left;
+
border: 1px red solid;
+
+
h3 {
+
margin: 0;
+
font-size: 1.25em;
+
+
a {
+
color: var(--foreground);
+
text-decoration: none;
+
+
&:hover {
+
text-decoration: underline;
+
}
+
}
+
}
+
+
.thumb {
+
position: relative;
+
padding-top: 75%;
+
+
img {
+
position: absolute;
+
top: 0;
+
left: 0;
+
width: 100%;
+
height: 100%;
+
object-fit: cover;
+
}
+
}
+
+
.authors {
+
font-size: .9em;
+
margin: 5px 0;
+
+
a {
+
color: color-mix(in srgb-linear, var(--foreground), #FFFFFF 10%);
+
text-decoration: none;
+
+
&:hover {
+
text-decoration: underline;
+
}
+
}
+
}
+
+
.blurb {
+
margin-top: 5px;
+
font-size: .8em;
+
color: color-mix(in srgb-linear, var(--foreground), #FFFFFF 10%);
+
}
+
}
+192
hugo/assets/scss/_partials/_global.scss
···
+
* {
+
box-sizing: border-box;
+
}
+
+
body {
+
background-color: var(--background);
+
background-image: url(--pageBgImage);
+
color: var(--foreground);
+
font-family: var(--mainfont);
+
font-size: 1em;
+
}
+
+
a {
+
color: var(--accent);
+
text-decoration: underline;
+
+
&:hover {
+
color: color-mix(in srgb-linear, var(--accent), #000000 50%);
+
}
+
}
+
+
.icon {
+
width: 16px;
+
height: 16px;
+
text-indent: -999px;
+
overflow: hidden;
+
display: inline-block;
+
vertical-align: middle;
+
margin-right: 5px;
+
background-color: var(--foreground);
+
+
&.web {
+
mask: url(../images/web.svg);
+
}
+
+
&.windows {
+
mask: url(../images/windows.svg);
+
}
+
+
&.macos {
+
mask: url(../images/macos.svg);
+
}
+
+
&.linux {
+
mask: url(../images/linux.svg);
+
}
+
+
&.android {
+
mask: url(../images/android.svg);
+
}
+
+
&.random {
+
mask: url(../images/random.svg);
+
}
+
+
&.sort-asc {
+
mask: url(../images/sort-asc.svg);
+
}
+
+
&.sort-desc {
+
mask: url(../images/sort-desc.svg);
+
}
+
+
.active & {
+
background-color: var(--accent);
+
}
+
}
+
+
.btn {
+
padding: 5px 10px;
+
font-size: 1em;
+
font-weight: bold;
+
border-radius: 5px;
+
background-color: var(--accent);
+
color: var(--background);
+
text-decoration: none;
+
white-space: pre;
+
+
&:hover {
+
background-color: color-mix(in srgb-linear, var(--accent), #000000 50%);
+
color: var(--background);
+
}
+
}
+
+
#page {
+
max-width: 960px;
+
margin: 50px auto;
+
background-color: color-mix(in srgb-linear, var(--background), #FFFFFF 50%);
+
background-image: var(--contentBgImage);
+
border-radius: var(--roundedCorners);
+
+
body.wide & {
+
max-width: none;
+
margin: 0;
+
}
+
}
+
+
header {
+
padding: 20px 20px 0;
+
position: relative;
+
background-color: color-mix(in srgb-linear, var(--background), #FFFFFF 25%);
+
+
h1 {
+
font-size: 2.5em;
+
font-weight: bold;
+
margin: 0;
+
}
+
+
.hosted {
+
margin: 0;
+
}
+
+
.joined,
+
.entries {
+
text-align: center;
+
position: absolute;
+
top: 20px;
+
right: 20px;
+
+
.count {
+
font-size: 2.25em;
+
display: block;
+
}
+
+
.caption {
+
font-size: .8em;
+
display: block;
+
color: color-mix(in srgb-linear, var(--foreground) #FFFFFF, 25%);
+
}
+
}
+
+
nav {
+
margin-top: 20px;
+
padding-bottom: 10px;
+
+
ul {
+
margin-bottom: 0;
+
display: flex;
+
gap: 10px;
+
list-style: none;
+
padding: 0;
+
+
li {
+
a {
+
text-decoration: none;
+
padding: 5px 0;
+
border-bottom: 5px transparent solid;
+
color: var(--foreground);
+
+
&.current,
+
&:hover {
+
border-bottom: 5px var(--accent) solid;
+
color: var(--foreground);
+
}
+
}
+
}
+
}
+
}
+
}
+
+
main {
+
padding: 20px;
+
text-align: center;
+
+
.submissions & {
+
display: grid;
+
grid-template-areas: "filters list";
+
grid-template-columns: 250px 1fr;
+
}
+
}
+
+
footer {
+
text-align: center;
+
font-size: .8em;
+
padding: 5px 10px;
+
margin-top: 20px;
+
+
a {
+
text-decoration: none;
+
}
+
}
+
+
[popover] {
+
position: fixed;
+
z-index: 99;
+
max-width: 90%;
+
max-height: 90%;
+
}
+
+
[popover]:-internal-popover-in-top-layer::backdrop {
+
background-color: rgba(0,0,0,.5);
+
}
+83
hugo/assets/scss/_partials/_homepage.scss
···
+
.clock {
+
border: 1px var(--accent) solid;
+
border-radius: 5px;
+
display: inline-grid;
+
grid-template-areas: "date date" "countdown join";
+
margin: 50px auto;
+
+
.dates {
+
border-bottom: 1px var(--accent) solid;
+
padding: 10px;
+
grid-area: date;
+
text-align: center;
+
}
+
+
.countdown {
+
grid-area: countdown;
+
border-right: 1px var(--accent) solid;
+
padding: 20px;
+
text-align: right;
+
display: flex;
+
align-items: center;
+
justify-content: flex-end;
+
+
.counters {
+
display: flex;
+
align-items: stretch;
+
+
& > div {
+
padding: 10px;
+
border-right: 2px var(--accent) solid;
+
display: flex;
+
flex-direction: column;
+
justify-content: center;
+
align-items: center;
+
white-space: pre;
+
+
&:last-child {
+
border-right: none;
+
}
+
}
+
+
span {
+
display: block;
+
text-align: center;
+
+
&.num {
+
font-weight: bold;
+
}
+
+
&.caption {
+
font-size: .8em;
+
font-style: italic;
+
}
+
}
+
}
+
}
+
+
.join {
+
display: flex;
+
align-items: center;
+
justify-content: flex-start;
+
padding: 20px;
+
}
+
+
.joinbtn {
+
padding: 10px 20px;
+
font-size: 1.25em;
+
font-weight: bold;
+
border-radius: 5px;
+
background-color: var(--accent);
+
color: var(--background);
+
text-decoration: none;
+
white-space: pre;
+
+
&:hover {
+
background-color: color-mix(in srgb-linear, var(--accent), #000000 50%);
+
}
+
}
+
}
+
+
.content {
+
text-align: left;
+
}
+17
hugo/assets/scss/_partials/_posts.scss
···
+
.post-list {
+
list-style: none;
+
margin: 0;
+
padding: 0;
+
text-align: left;
+
+
h3 {
+
font-weight: normal;
+
font-size: 1em;
+
+
.date {
+
margin-left: 5px;
+
font-size: .8em;
+
color: color-mix(in srgb-linear, var(--foreground), var(--background) 20%);
+
}
+
}
+
}
+106
hugo/assets/scss/_partials/_submissions.scss
···
+
#filters {
+
grid-area: filters;
+
text-align: left;
+
+
#tags {
+
display: flex;
+
flex-wrap: wrap;
+
gap: 5px;
+
justify-content: flex-start;
+
+
button {
+
white-space: pre;
+
}
+
}
+
+
details {
+
margin-bottom: 10px;
+
+
ul {
+
list-style: none;
+
margin: 0;
+
padding: 0;
+
}
+
}
+
+
p.label,
+
details summary {
+
font-size: .8em;
+
color: color-mix(in srgb-linear, var(--foreground), var(--background) 10%);
+
padding: 5px 0;
+
margin-bottom: 0;
+
}
+
+
ul#sorts {
+
list-style: none;
+
margin: 0 0 10px;
+
padding: 0;
+
+
li {
+
button {
+
appearance: none;
+
border: none;
+
background-color: transparent;
+
color: var(--foreground);
+
border-radius: 0;
+
font-family: inherit;
+
font-size: inherit;
+
font-size: .9em;
+
+
img {
+
width: 16px;
+
height: 16px;
+
margin-right: 5px;
+
display: inline-block;
+
vertical-align: middle;
+
}
+
+
&.sort-active {
+
color: color-mix(in srgb-linear, var(--accent), #000000 10%);
+
font-weight: bold;
+
}
+
}
+
}
+
}
+
+
.afs-btn-filter {
+
appearance: none;
+
padding: 3px 0;
+
border: none;
+
border-radius: 0;
+
font-family: inherit;
+
background-color: transparent;
+
+
&.active {
+
color: color-mix(in srgb-linear, var(--accent), #000000 10%);
+
background-color: transparent;
+
font-weight: bold;
+
}
+
}
+
+
.afs-filter-search {
+
width: 100%;
+
padding: 0.5rem;
+
border: 1px solid var(--accent);
+
border-radius: 0.25rem;
+
font-size: 0.875rem;
+
color: var(--foreground);
+
transition: border-color 0.2s ease;
+
margin-bottom: 10px;
+
font-family: inherit;
+
}
+
+
.afs-filter-counter {
+
text-align: center;
+
font-style: italic;
+
font-size: .9em;
+
}
+
}
+
+
#list {
+
display: grid;
+
grid-area: list;
+
grid-template-columns: repeat(4, 1fr);
+
grid-template-rows: fit-content(300px);
+
gap: 10px;
+
}
+13
hugo/assets/scss/_partials/_variables.scss
···
+
/* display variables! skip the images if you don't want them */
+
+
:root {
+
--background: #ECEBDE;
+
--foreground: #000000;
+
--accent: #A59D84;
+
--mainfont: 'Work Sans', Helvetica, Arial, sans-serif;
+
--headingfont: 'Knewave', 'Arial Black', sans-serif;
+
--roundedCorners: 0px;
+
+
--pageBgImage: url();
+
--contentBgImage: url();
+
}
+7
hugo/assets/scss/style.scss
···
+
@use '_partials/_fonts';
+
@use '_partials/_variables';
+
@use '_partials/_global';
+
@use '_partials/_homepage';
+
@use '_partials/_submissions';
+
@use '_partials/_game_list_item';
+
@use '_partials/_game';
-27
hugo/exampleSite/content/_index.md
···
-
+++
-
title = "Home"
-
menu = "main"
-
weight = 1
-
+++
-
-
# A match made in heaven
-
-
There is a website obesity crisis. Bloated websites full of scripts, ads, and trackers are slowing your readers down every time they try to read your well-crafted content.
-
-
Hugo Bear Blog is all you need to build a fantastic and optimized site or blog. It works perfectly on **any** viewing device. All you need to focus on is writing good content.
-
-
[Go to the original bear blog](https://bearblog.dev/).
-
-
---
-
-
What happens when you combine the worlds' fastest, most lightweight static site generator with a design theme built to provide you with free, no-nonsense, super-fast blogging capabilities?
-
-
**Use this theme, and find out!**
-
-
Made with ๐Ÿ’Ÿ by [Jan Raasch](https://www.janraasch.com).
-
-
---
-
-
Simply publish content online, grow an audience, and keep your pages tiny, fast, and **optimized for search engines**.
-
-
Each page is ~5kb, and you can **host your blog yourself**.
-19
hugo/exampleSite/content/bear.md
···
-
+++
-
title = "Bear"
-
menu = "main"
-
weight = 20
-
+++
-
-
# Bear
-
-
Website: https://bearblog.dev
-
-
There is a website obesity crisis. Bloated websites are full of scripts, ads, and trackers slowing your readers down every time they try to read your well-crafted content.
-
-
Bear is all you need to build a fantastic and optimized site or blog. It works perfectly on **any** viewing device. All you need to focus on is writing good content.
-
-
Bear makes it simple to publish content online and grow an audience while keeping pages tiny, fast, and **optimized for search engines.**
-
-
Each page is ~5kb.
-
-
Learn more and contribute on [GitHub](https://github.com/HermanMartinus/bearblog).
-5
hugo/exampleSite/content/blog/_index.md
···
-
+++
-
title = "Blog"
-
menu = "main"
-
weight = 100
-
+++
-144
hugo/exampleSite/content/blog/markdown-syntax.md
···
-
+++
-
title = "Markdown Syntax Guide"
-
date = "2020-01-03"
-
description = "Sample article showcasing basic Markdown syntax and formatting for HTML elements."
-
tags = [
-
"markdown",
-
"syntax",
-
]
-
+++
-
-
For a quick cheatsheet, check out https://simplemde.com/markdown-guide.
-
-
---
-
-
This article offers a sample of basic Markdown syntax that can be used in Hugo content files, also it shows whether basic HTML elements are decorated with CSS in a Hugo theme.
-
<!--more-->
-
-
## Headings
-
-
The following HTML `<h1>`โ€”`<h6>` elements represent six levels of section headings. `<h1>` is the highest section level while `<h6>` is the lowest.
-
-
# H1
-
## H2
-
### H3
-
#### H4
-
##### H5
-
###### H6
-
-
## Paragraph
-
-
Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.
-
-
Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.
-
-
## Blockquotes
-
-
The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations.
-
-
#### Blockquote without attribution
-
-
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
-
> **Note** that you can use *Markdown syntax* within a blockquote.
-
-
#### Blockquote with attribution
-
-
> Don't communicate by sharing memory, share memory by communicating.<br>
-
> โ€” <cite>Rob Pike[^1]</cite>
-
-
[^1]: The above quote is excerpted from Rob Pike's [talk](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015.
-
-
## Tables
-
-
Tables aren't part of the core Markdown spec, but Hugo supports supports them out-of-the-box.
-
-
Name | Age
-
--------|------
-
Bob | 27
-
Alice | 23
-
-
#### Inline Markdown within tables
-
-
| Italics | Bold | Code |
-
| -------- | -------- | ------ |
-
| *italics* | **bold** | `code` |
-
-
## Code Blocks
-
-
#### Code block with backticks
-
-
```html
-
<!doctype html>
-
<html lang="en">
-
<head>
-
<meta charset="utf-8">
-
<title>Example HTML5 Document</title>
-
</head>
-
<body>
-
<p>Test</p>
-
</body>
-
</html>
-
```
-
-
#### Code block indented with four spaces
-
-
<!doctype html>
-
<html lang="en">
-
<head>
-
<meta charset="utf-8">
-
<title>Example HTML5 Document</title>
-
</head>
-
<body>
-
<p>Test</p>
-
</body>
-
</html>
-
-
#### Code block with Hugo's internal highlight shortcode
-
{{< highlight html >}}
-
<!doctype html>
-
<html lang="en">
-
<head>
-
<meta charset="utf-8">
-
<title>Example HTML5 Document</title>
-
</head>
-
<body>
-
<p>Test</p>
-
</body>
-
</html>
-
{{< /highlight >}}
-
-
## List Types
-
-
#### Ordered List
-
-
1. First item
-
2. Second item
-
3. Third item
-
-
#### Unordered List
-
-
* List item
-
* Another item
-
* And another item
-
-
#### Nested list
-
-
* Fruit
-
* Apple
-
* Orange
-
* Banana
-
* Dairy
-
* Milk
-
* Cheese
-
-
## Other Elements โ€” abbr, sub, sup, kbd, mark
-
-
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
-
-
H<sub>2</sub>O
-
-
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
-
-
Press <kbd><kbd>CTRL</kbd>+<kbd>ALT</kbd>+<kbd>Delete</kbd></kbd> to end the session.
-
-
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
-27
hugo/exampleSite/content/hugo.md
···
-
+++
-
title = "Hugo"
-
menu = "main"
-
weight = 10
-
+++
-
-
# Hugo
-
-
Website: https://gohugo.io
-
-
Written in Go, Hugo is an open-source static site generator available under the [Apache Licence 2.0.](https://github.com/gohugoio/hugo/blob/master/LICENSE) Hugo supports TOML, YAML, and JSON data file types, Markdown and HTML content files, and uses shortcodes to add rich content. Other notable features are taxonomies, multilingual mode, image processing, custom output formats, HTML/CSS/JS minification, and support for Sass SCSS workflows.
-
-
Hugo makes use of a variety of open source projects including:
-
-
* https://github.com/yuin/goldmark
-
* https://github.com/alecthomas/chroma
-
* https://github.com/muesli/smartcrop
-
* https://github.com/spf13/cobra
-
* https://github.com/spf13/viper
-
-
Hugo is ideal for blogs, corporate websites, creative portfolios, online magazines, single-page applications, or even a website with thousands of pages.
-
-
Hugo is for people who want to hand-code their own website without worrying about setting up complicated runtimes, dependencies, and databases.
-
-
Websites built with Hugo are swift, secure and can be deployed anywhere including, AWS, GitHub Pages, Heroku, Netlify, and any other hosting provider.
-
-
Learn more and contribute on [GitHub](https://github.com/gohugoio).
-66
hugo/exampleSite/hugo.toml
···
-
# Base URL used when generating links to your pages
-
# Set to the URL for your site
-
baseURL = "https://example.com"
-
-
# The name of this wonderful theme ;-).
-
theme = 'hugo-bearblog'
-
-
# Basic metadata configuration for your blog.
-
title = "Hugo ส•โ€ขแดฅโ€ขส” Bear Blog"
-
author = "Jane Doe"
-
copyright = "Copyright ยฉ 2020, Jane Doe."
-
languageCode = "en-US"
-
-
# Generate a nice robots.txt for SEO
-
enableRobotsTXT = true
-
-
# Generate "Bearblog"-like URLs !only!, see https://bearblog.dev/.
-
disableKinds = ["taxonomy"]
-
ignoreErrors = ["error-disable-taxonomy"]
-
[permalinks]
-
blog = "/:slug/"
-
tags = "/blog/:slug"
-
-
[params]
-
# The "description" of your website. This is used in the meta data of your generated html.
-
description = "Hugo + Bear = :heart:"
-
-
# The path to your "favicon". This should be a square (at least 32px x 32px) png-file.
-
# Hint: It's good practise to also put a "favicon.ico"-file into your "static"-folder.
-
favicon = "images/favicon.png"
-
-
# These "images" are used for the structured data templates. This will show up, when
-
# services like Twitter or Slack want to generate a preview of a link to your site.
-
# See https://gohugo.io/templates/internal#twitter-cards and
-
# https://gohugo.io/templates/internal#open-graph.
-
images = ["images/share.png"]
-
-
# Another "title" :-). This one is used as the site_name on the Hugo's internal
-
# opengraph structured data template.
-
# See https://ogp.me/ and https://gohugo.io/templates/internal#open-graph.
-
title = "Hugo ส•โ€ขแดฅโ€ขส” Bear"
-
-
# This theme will, by default, inject a made-with-line at the bottom of the page.
-
# You can turn it off, but we would really appreciate if you donโ€™t :-).
-
# hideMadeWithLine = true
-
-
# By default, if you want to read more than one blog post you have to always go
-
# back to the /blog page.
-
# By enabling this feature each blog post will have at the end a navigator
-
# enablePostNavigator = true
-
-
# By default, this theme displays dates with a format like "02 Jan, 2006", but
-
# you can customize it by setting the `dateFormat` param in your site's config
-
# file. See [Hugo's Format function docs](https://gohugo.io/functions/format/)
-
# for details. An example TOML config that uses [ISO
-
# 8601](https://en.wikipedia.org/wiki/ISO_8601) format:
-
# dateFormat = "2006-01-02"
-
-
# Configure markup highlighter to match "Bearblog" aesthetics, see
-
# https://gohugo.io/configuration/markup/#highlight
-
[markup]
-
[markup.highlight]
-
style = 'friendly'
-
lineNos = true
-
lineNumbersInTable = false
-
codeFences = true
hugo/exampleSite/static/favicon.ico

This is a binary file and will not be displayed.

hugo/exampleSite/static/images/favicon.png

This is a binary file and will not be displayed.

hugo/exampleSite/static/images/share.png

This is a binary file and will not be displayed.

hugo/images/android-chrome-192x192.png

This is a binary file and will not be displayed.

hugo/images/android-chrome-512x512.png

This is a binary file and will not be displayed.

-1
hugo/images/android.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M452.5 317.9C465.8 317.9 476.5 328.6 476.5 341.9C476.5 355.2 465.8 365.9 452.5 365.9C439.2 365.9 428.5 355.2 428.5 341.9C428.5 328.6 439.2 317.9 452.5 317.9zM187.4 317.9C200.7 317.9 211.4 328.6 211.4 341.9C211.4 355.2 200.7 365.9 187.4 365.9C174.1 365.9 163.4 355.2 163.4 341.9C163.4 328.6 174.1 317.9 187.4 317.9zM461.1 221.4L509 138.4C509.8 137.3 510.3 136 510.5 134.6C510.7 133.2 510.7 131.9 510.4 130.5C510.1 129.1 509.5 127.9 508.7 126.8C507.9 125.7 506.9 124.8 505.7 124.1C504.5 123.4 503.2 123 501.8 122.8C500.4 122.6 499.1 122.8 497.8 123.2C496.5 123.6 495.3 124.3 494.2 125.1C493.1 125.9 492.3 127.1 491.7 128.3L443.2 212.4C404.4 195 362.4 186 319.9 186C277.4 186 235.4 195 196.6 212.4L148.2 128.4C147.6 127.2 146.7 126.1 145.7 125.2C144.7 124.3 143.4 123.7 142.1 123.3C140.8 122.9 139.4 122.8 138.1 122.9C136.8 123 135.4 123.5 134.2 124.2C133 124.9 132 125.8 131.2 126.9C130.4 128 129.8 129.3 129.5 130.6C129.2 131.9 129.2 133.3 129.4 134.7C129.6 136.1 130.2 137.3 130.9 138.5L178.8 221.5C96.5 266.2 40.2 349.5 32 448L608 448C599.8 349.5 543.5 266.2 461.1 221.4z"/></svg>
hugo/images/apple-touch-icon.png

This is a binary file and will not be displayed.

-1
hugo/images/bluesky.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M439.8 358.7C436.5 358.3 433.1 357.9 429.8 357.4C433.2 357.8 436.5 358.3 439.8 358.7zM320 291.1C293.9 240.4 222.9 145.9 156.9 99.3C93.6 54.6 69.5 62.3 53.6 69.5C35.3 77.8 32 105.9 32 122.4C32 138.9 41.1 258 47 277.9C66.5 343.6 136.1 365.8 200.2 358.6C203.5 358.1 206.8 357.7 210.2 357.2C206.9 357.7 203.6 358.2 200.2 358.6C106.3 372.6 22.9 406.8 132.3 528.5C252.6 653.1 297.1 501.8 320 425.1C342.9 501.8 369.2 647.6 505.6 528.5C608 425.1 533.7 372.5 439.8 358.6C436.5 358.2 433.1 357.8 429.8 357.3C433.2 357.7 436.5 358.2 439.8 358.6C503.9 365.7 573.4 343.5 593 277.9C598.9 258 608 139 608 122.4C608 105.8 604.7 77.7 586.4 69.5C570.6 62.4 546.4 54.6 483.2 99.3C417.1 145.9 346.1 240.4 320 291.1z"/></svg>
-1
hugo/images/facebook.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 440 146.7 540.8 258.2 568.5L258.2 398.2L205.4 398.2L205.4 320L258.2 320L258.2 286.3C258.2 199.2 297.6 158.8 383.2 158.8C399.4 158.8 427.4 162 438.9 165.2L438.9 236C432.9 235.4 422.4 235 409.3 235C367.3 235 351.1 250.9 351.1 292.2L351.1 320L434.7 320L420.3 398.2L351 398.2L351 574.1C477.8 558.8 576 450.9 576 320z"/></svg>
hugo/images/favicon-16x16.png

This is a binary file and will not be displayed.

hugo/images/favicon-32x32.png

This is a binary file and will not be displayed.

hugo/images/favicon.ico

This is a binary file and will not be displayed.

-1
hugo/images/linux.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M316.9 187.3C317.9 187.8 318.7 189 319.9 189C321 189 322.7 188.6 322.8 187.5C323 186.1 320.9 185.2 319.6 184.6C317.9 183.9 315.7 183.6 314.1 184.5C313.7 184.7 313.3 185.2 313.5 185.6C313.8 186.9 315.8 186.7 316.9 187.3zM295 189C296.2 189 297 187.8 298 187.3C299.1 186.7 301.1 186.9 301.5 185.7C301.7 185.3 301.3 184.8 300.9 184.6C299.3 183.7 297.1 184 295.4 184.7C294.1 185.3 292 186.2 292.2 187.6C292.3 188.6 294 189.1 295 189zM516 467.8C512.4 463.8 510.7 456.2 508.8 448.1C507 440 504.9 431.3 498.3 425.7C497 424.6 495.7 423.6 494.3 422.8C493 422 491.6 421.3 490.2 420.8C499.4 393.5 495.8 366.3 486.5 341.7C475.1 311.6 455.2 285.3 440 267.3C422.9 245.8 406.3 225.4 406.6 195.3C407.1 149.4 411.7 64.1 330.8 64C228.4 63.8 254 167.4 252.9 199.2C251.2 222.6 246.5 241 230.4 263.9C211.5 286.4 184.9 322.7 172.3 360.6C166.3 378.5 163.5 396.7 166.1 413.9C159.6 419.7 154.7 428.6 149.5 434.1C145.3 438.4 139.2 440 132.5 442.4C125.8 444.8 118.5 448.4 114 456.9C111.9 460.8 111.2 465 111.2 469.3C111.2 473.2 111.8 477.2 112.4 481.1C113.6 489.2 114.9 496.8 113.2 501.9C108 516.3 107.3 526.3 111 533.6C114.8 540.9 122.4 544.1 131.1 545.9C148.4 549.5 171.9 548.6 190.4 558.4C210.2 568.8 230.3 572.5 246.3 568.8C257.9 566.2 267.4 559.2 272.2 548.6C284.7 548.5 298.5 543.2 320.5 542C335.4 540.8 354.1 547.3 375.6 546.1C376.2 548.4 377 550.7 378.1 552.8L378.1 552.9C386.4 569.6 401.9 577.2 418.4 575.9C435 574.6 452.5 564.9 466.7 548C480.3 531.6 502.7 524.8 517.6 515.8C525 511.3 531 505.7 531.5 497.5C531.9 489.3 527.1 480.2 516 467.8zM319.8 151.3C329.6 129.1 354 129.5 363.8 150.9C370.3 165.1 367.4 181.8 359.5 191.3C357.9 190.5 353.6 188.7 346.9 186.4C348 185.2 350 183.7 350.8 181.8C355.6 170 350.6 154.8 341.7 154.5C334.4 154 327.8 165.3 329.9 177.5C325.8 175.5 320.5 174 316.9 173.1C315.9 166.2 316.6 158.5 319.8 151.3zM279.1 139.8C289.2 139.8 299.9 154 298.2 173.3C294.7 174.3 291.1 175.8 288 177.9C289.2 169 284.7 157.8 278.4 158.3C270 159 268.6 179.5 276.6 186.4C277.6 187.2 278.5 186.2 270.7 191.9C255.1 177.3 260.2 139.8 279.1 139.8zM265.5 200.5C271.7 195.9 279.1 190.5 279.6 190C284.3 185.6 293.1 175.8 307.5 175.8C314.6 175.8 323.1 178.1 333.4 184.7C339.7 188.8 344.7 189.1 356 194C364.4 197.5 369.7 203.7 366.5 212.2C363.9 219.3 355.5 226.6 343.8 230.3C332.7 233.9 324 246.3 305.6 245.2C301.7 245 298.6 244.2 296 243.1C288 239.6 283.8 232.7 276 228.1C267.4 223.3 262.8 217.7 261.3 212.8C259.9 207.9 261.3 203.8 265.5 200.5zM268.8 534.5C266.1 569.6 224.9 568.9 193.5 552.5C163.6 536.7 124.9 546 117 530.6C114.6 525.9 114.6 517.9 119.6 504.2L119.6 504C122 496.4 120.2 488 119 480.1C117.8 472.3 117.2 465.1 119.9 460.1C123.4 453.4 128.4 451 134.7 448.8C145 445.1 146.5 445.4 154.3 438.9C159.8 433.2 163.8 426 168.6 420.9C173.7 415.4 178.6 412.8 186.3 414C194.4 415.2 201.4 420.8 208.2 430L227.8 465.6C237.3 485.5 270.9 514 268.8 534.5zM267.4 508.6C263.3 502 257.8 495 253 489C260.1 489 267.2 486.8 269.7 480.1C272 473.9 269.7 465.2 262.3 455.2C248.8 437 224 422.7 224 422.7C210.5 414.3 202.9 404 199.4 392.8C195.9 381.6 196.4 369.5 199.1 357.6C204.3 334.7 217.7 312.4 226.3 298.4C228.6 296.7 227.1 301.6 217.6 319.2C209.1 335.3 193.2 372.5 215 401.6C215.6 380.9 220.5 359.8 228.8 340.1C240.8 312.7 266.1 265.2 268.1 227.4C269.2 228.2 272.7 230.6 274.3 231.5C278.9 234.2 282.4 238.2 286.9 241.8C299.3 251.8 315.4 251 329.3 243C335.5 239.5 340.5 235.5 345.2 234C355.1 230.9 363 225.4 367.5 219C375.2 249.4 393.2 293.3 404.7 314.7C410.8 326.1 423 350.2 428.3 379.3C431.6 379.2 435.3 379.7 439.2 380.7C453 345 427.5 306.5 415.9 295.8C411.2 291.2 411 289.2 413.3 289.3C425.9 300.5 442.5 323 448.5 348.3C451.3 359.9 451.8 372 448.9 384C465.3 390.8 484.8 401.9 479.6 418.8C477.4 418.7 476.4 418.8 475.4 418.8C478.6 408.7 471.5 401.2 452.6 392.7C433 384.1 416.6 384.1 414.3 405.2C402.2 409.4 396 419.9 392.9 432.5C390.1 443.7 389.3 457.2 388.5 472.4C388 480.1 384.9 490.4 381.7 501.4C349.6 524.3 305 534.3 267.4 508.6zM524.8 497.1C523.9 513.9 483.6 517 461.6 543.6C448.4 559.3 432.2 568 418 569.1C403.8 570.2 391.5 564.3 384.3 549.8C379.6 538.7 381.9 526.7 385.4 513.5C389.1 499.3 394.6 484.7 395.3 472.9C396.1 457.7 397 444.4 399.5 434.2C402.1 423.9 406.1 417 413.2 413.1C413.5 412.9 413.9 412.8 414.2 412.6C415 425.8 421.5 439.2 433 442.1C445.6 445.4 463.7 434.6 471.4 425.8C480.4 425.5 487.1 424.9 494 430.9C503.9 439.4 501.1 461.2 511.1 472.5C521.7 484.1 525.1 492 524.8 497.1zM269.4 212.7C271.4 214.6 274.1 217.2 277.4 219.8C284 225 293.2 230.4 304.7 230.4C316.3 230.4 327.2 224.5 336.5 219.6C341.4 217 347.4 212.6 351.3 209.2C355.2 205.8 357.2 202.9 354.4 202.6C351.6 202.3 351.8 205.2 348.4 207.7C344 210.9 338.7 215.1 334.5 217.5C327.1 221.7 315 227.7 304.6 227.7C294.2 227.7 285.9 222.9 279.7 218C276.6 215.5 274 213 272 211.1C270.5 209.7 270.1 206.5 267.7 206.2C266.3 206.1 265.9 209.9 269.4 212.7z"/></svg>
-1
hugo/images/macos.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M320 176C311.2 176 304 168.8 304 160L304 144C304 99.8 339.8 64 384 64L400 64C408.8 64 416 71.2 416 80L416 96C416 140.2 380.2 176 336 176L320 176zM96 352C96 275.7 131.7 192 208 192C235.3 192 267.7 202.3 290.7 211.3C309.5 218.6 330.6 218.6 349.4 211.3C372.3 202.4 404.8 192 432.1 192C508.4 192 544.1 275.7 544.1 352C544.1 480 464.1 576 384.1 576C367.6 576 346 569.4 332.6 564.7C324.5 561.9 315.7 561.9 307.6 564.7C294.2 569.4 272.6 576 256.1 576C176.1 576 96.1 480 96.1 352z"/></svg>
-1
hugo/images/mastodon.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M529 243.1C529 145.9 465.3 117.4 465.3 117.4C402.8 88.7 236.7 89 174.8 117.4C174.8 117.4 111.1 145.9 111.1 243.1C111.1 358.8 104.5 502.5 216.7 532.2C257.2 542.9 292 545.2 320 543.6C370.8 540.8 399.3 525.5 399.3 525.5L397.6 488.6C397.6 488.6 361.3 500 320.5 498.7C280.1 497.3 237.5 494.3 230.9 444.7C230.3 440.1 230 435.4 230 430.8C315.6 451.7 388.7 439.9 408.7 437.5C464.8 430.8 513.7 396.2 519.9 364.6C529.7 314.8 528.9 243.1 528.9 243.1zM453.9 368.3L407.3 368.3L407.3 254.1C407.3 204.4 343.3 202.5 343.3 261L343.3 323.5L297 323.5L297 261C297 202.5 233 204.4 233 254.1L233 368.3L186.3 368.3C186.3 246.2 181.1 220.4 204.7 193.3C230.6 164.4 284.5 162.5 308.5 199.4L320.1 218.9L331.7 199.4C355.8 162.3 409.8 164.6 435.5 193.3C459.2 220.6 453.9 246.3 453.9 368.3L453.9 368.3z"/></svg>
-1
hugo/images/random.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M467.8 98.4C479.8 93.4 493.5 96.2 502.7 105.3L566.7 169.3C572.7 175.3 576.1 183.4 576.1 191.9C576.1 200.4 572.7 208.5 566.7 214.5L502.7 278.5C493.5 287.7 479.8 290.4 467.8 285.4C455.8 280.4 448 268.9 448 256L448 224L416 224C405.9 224 396.4 228.7 390.4 236.8L358 280L318 226.7L339.2 198.4C357.3 174.2 385.8 160 416 160L448 160L448 128C448 115.1 455.8 103.4 467.8 98.4zM218 360L258 413.3L236.8 441.6C218.7 465.8 190.2 480 160 480L96 480C78.3 480 64 465.7 64 448C64 430.3 78.3 416 96 416L160 416C170.1 416 179.6 411.3 185.6 403.2L218 360zM502.6 534.6C493.4 543.8 479.7 546.5 467.7 541.5C455.7 536.5 448 524.9 448 512L448 480L416 480C385.8 480 357.3 465.8 339.2 441.6L185.6 236.8C179.6 228.7 170.1 224 160 224L96 224C78.3 224 64 209.7 64 192C64 174.3 78.3 160 96 160L160 160C190.2 160 218.7 174.2 236.8 198.4L390.4 403.2C396.4 411.3 405.9 416 416 416L448 416L448 384C448 371.1 455.8 359.4 467.8 354.4C479.8 349.4 493.5 352.2 502.7 361.3L566.7 425.3C572.7 431.3 576.1 439.4 576.1 447.9C576.1 456.4 572.7 464.5 566.7 470.5L502.7 534.5z"/></svg>
hugo/images/screenshot-dark.png

This is a binary file and will not be displayed.

hugo/images/screenshot.png

This is a binary file and will not be displayed.

-1
hugo/images/sort-asc.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M278.6 438.6L182.6 534.6C170.1 547.1 149.8 547.1 137.3 534.6L41.3 438.6C28.8 426.1 28.8 405.8 41.3 393.3C53.8 380.8 74.1 380.8 86.6 393.3L128 434.7L128 128C128 110.3 142.3 96 160 96C177.7 96 192 110.3 192 128L192 434.7L233.4 393.3C245.9 380.8 266.2 380.8 278.7 393.3C291.2 405.8 291.2 426.1 278.7 438.6zM352 96L384 96C401.7 96 416 110.3 416 128C416 145.7 401.7 160 384 160L352 160C334.3 160 320 145.7 320 128C320 110.3 334.3 96 352 96zM352 224L448 224C465.7 224 480 238.3 480 256C480 273.7 465.7 288 448 288L352 288C334.3 288 320 273.7 320 256C320 238.3 334.3 224 352 224zM352 352L512 352C529.7 352 544 366.3 544 384C544 401.7 529.7 416 512 416L352 416C334.3 416 320 401.7 320 384C320 366.3 334.3 352 352 352zM352 480L576 480C593.7 480 608 494.3 608 512C608 529.7 593.7 544 576 544L352 544C334.3 544 320 529.7 320 512C320 494.3 334.3 480 352 480z"/></svg>
-1
hugo/images/sort-desc.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M278.6 438.6L182.6 534.6C170.1 547.1 149.8 547.1 137.3 534.6L41.3 438.6C28.8 426.1 28.8 405.8 41.3 393.3C53.8 380.8 74.1 380.8 86.6 393.3L128 434.7L128 128C128 110.3 142.3 96 160 96C177.7 96 192 110.3 192 128L192 434.7L233.4 393.3C245.9 380.8 266.2 380.8 278.7 393.3C291.2 405.8 291.2 426.1 278.7 438.6zM352 544C334.3 544 320 529.7 320 512C320 494.3 334.3 480 352 480L384 480C401.7 480 416 494.3 416 512C416 529.7 401.7 544 384 544L352 544zM352 416C334.3 416 320 401.7 320 384C320 366.3 334.3 352 352 352L448 352C465.7 352 480 366.3 480 384C480 401.7 465.7 416 448 416L352 416zM352 288C334.3 288 320 273.7 320 256C320 238.3 334.3 224 352 224L512 224C529.7 224 544 238.3 544 256C544 273.7 529.7 288 512 288L352 288zM352 160C334.3 160 320 145.7 320 128C320 110.3 334.3 96 352 96L576 96C593.7 96 608 110.3 608 128C608 145.7 593.7 160 576 160L352 160z"/></svg>
hugo/images/tn.png

This is a binary file and will not be displayed.

-1
hugo/images/twitter.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M523.4 215.7C523.7 220.2 523.7 224.8 523.7 229.3C523.7 368 418.1 527.9 225.1 527.9C165.6 527.9 110.4 510.7 64 480.8C72.4 481.8 80.6 482.1 89.3 482.1C138.4 482.1 183.5 465.5 219.6 437.3C173.5 436.3 134.8 406.1 121.5 364.5C128 365.5 134.5 366.1 141.3 366.1C150.7 366.1 160.1 364.8 168.9 362.5C120.8 352.8 84.8 310.5 84.8 259.5L84.8 258.2C98.8 266 115 270.9 132.2 271.5C103.9 252.7 85.4 220.5 85.4 184.1C85.4 164.6 90.6 146.7 99.7 131.1C151.4 194.8 229 236.4 316.1 240.9C314.5 233.1 313.5 225 313.5 216.9C313.5 159.1 360.3 112 418.4 112C448.6 112 475.9 124.7 495.1 145.1C518.8 140.6 541.6 131.8 561.7 119.8C553.9 144.2 537.3 164.6 515.6 177.6C536.7 175.3 557.2 169.5 576 161.4C561.7 182.2 543.8 200.7 523.4 215.7z"/></svg>
-1
hugo/images/web.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M415.9 344L225 344C227.9 408.5 242.2 467.9 262.5 511.4C273.9 535.9 286.2 553.2 297.6 563.8C308.8 574.3 316.5 576 320.5 576C324.5 576 332.2 574.3 343.4 563.8C354.8 553.2 367.1 535.8 378.5 511.4C398.8 467.9 413.1 408.5 416 344zM224.9 296L415.8 296C413 231.5 398.7 172.1 378.4 128.6C367 104.2 354.7 86.8 343.3 76.2C332.1 65.7 324.4 64 320.4 64C316.4 64 308.7 65.7 297.5 76.2C286.1 86.8 273.8 104.2 262.4 128.6C242.1 172.1 227.8 231.5 224.9 296zM176.9 296C180.4 210.4 202.5 130.9 234.8 78.7C142.7 111.3 74.9 195.2 65.5 296L176.9 296zM65.5 344C74.9 444.8 142.7 528.7 234.8 561.3C202.5 509.1 180.4 429.6 176.9 344L65.5 344zM463.9 344C460.4 429.6 438.3 509.1 406 561.3C498.1 528.6 565.9 444.8 575.3 344L463.9 344zM575.3 296C565.9 195.2 498.1 111.3 406 78.7C438.3 130.9 460.4 210.4 463.9 296L575.3 296z"/></svg>
-1
hugo/images/windows.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M96 157.7L279.6 132.4L279.6 309.8L96 309.8L96 157.7zM96 482.3L279.6 507.6L279.6 332.4L96 332.4L96 482.3zM299.8 510.3L544 544L544 332.4L299.8 332.4L299.8 510.3zM299.8 129.7L299.8 309.8L544 309.8L544 96L299.8 129.7z"/></svg>
-1
hugo/images/xtwitter.svg
···
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M453.2 112L523.8 112L369.6 288.2L551 528L409 528L297.7 382.6L170.5 528L99.8 528L264.7 339.5L90.8 112L236.4 112L336.9 244.9L453.2 112zM428.4 485.8L467.5 485.8L215.1 152L173.1 152L428.4 485.8z"/></svg>
-43
hugo/layouts/_default/baseof.html
···
-
<!DOCTYPE html>
-
<html lang="{{ with .Site.LanguageCode }}{{ . }}{{ else }}en-US{{ end }}">
-
-
<head>
-
<meta http-equiv="X-Clacks-Overhead" content="GNU Terry Pratchett" />
-
<meta charset="utf-8">
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
-
{{- partial "favicon.html" . -}}
-
<title>{{- block "title" . }}{{ with .Title }}{{ . }} | {{ end }}{{ .Site.Title }}{{- end }}</title>
-
-
{{- partial "seo_tags.html" . -}}
-
<meta name="referrer" content="no-referrer-when-downgrade" />
-
-
{{ with .OutputFormats.Get "rss" -}}
-
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
-
{{ end -}}
-
-
{{- partial "style.html" . -}}
-
-
<!-- A partial to be overwritten by the user.
-
Simply place a custom_head.html into
-
your local /layouts/partials-directory -->
-
{{- partial "custom_head.html" . -}}
-
</head>
-
-
<body>
-
<header>
-
{{- partial "header.html" . -}}
-
</header>
-
<main>
-
{{- block "main" . }}{{- end }}
-
</main>
-
<footer>
-
{{- partial "footer.html" . -}}
-
</footer>
-
-
<!-- A partial to be overwritten by the user.
-
Simply place a custom_body.html into
-
your local /layouts/partials-directory -->
-
{{- partial "custom_body.html" . -}}
-
</body>
-
-
</html>
-37
hugo/layouts/_default/list.html
···
-
{{ define "main" }}
-
<content>
-
{{ if .Data.Singular }}
-
<h3 style="margin-bottom:0">Filtering for "{{ .Title }}"</h3>
-
<small>
-
<a href="{{ "blog" | relURL }}">Remove filter</a>
-
</small>
-
{{ end }}
-
<ul class="blog-posts">
-
{{ range .Pages }}
-
<li>
-
<span>
-
<i>
-
<time datetime='{{ .Date.Format "2006-01-02" }}'>
-
{{ .Date.Format (default "02 Jan, 2006" .Site.Params.dateFormat) }}
-
</time>
-
</i>
-
</span>
-
<a href="{{ .Permalink }}">{{ .Title }}</a>
-
</li>
-
{{ else }}
-
<li>
-
No posts yet
-
</li>
-
{{ end }}
-
</ul>
-
{{ if not .Data.Singular }}
-
<small>
-
<div>
-
{{ range .Site.Taxonomies.tags }}
-
<a href="{{ .Page.Permalink }}">#{{ .Page.Title }}</a>&nbsp;
-
{{ end }}
-
</div>
-
</small>
-
{{ end }}
-
</content>
-
{{ end }}
-25
hugo/layouts/_default/single.html
···
-
{{ define "main" }}
-
{{ if eq .Type "blog" }}{{ if not .Params.menu }}
-
<h1>{{ .Title }}</h1>
-
<p>
-
<i>
-
<time datetime='{{ .Date.Format "2006-01-02" }}'>
-
{{ .Date.Format (default "02 Jan, 2006" .Site.Params.dateFormat) }}
-
</time>
-
</i>
-
</p>
-
{{ end }}{{ end }}
-
<content>
-
{{ .Content }}
-
</content>
-
-
{{ if eq .Type "blog" }}{{ if (.Param "enablePostNavigator")}}
-
{{- partial "post_navigator.html" . -}}
-
{{ end }}{{ end }}
-
-
<p>
-
{{ range (.GetTerms "tags") }}
-
<a href="{{ .Permalink }}">#{{ .LinkTitle }}</a>
-
{{ end }}
-
</p>
-
{{ end }}
+20
hugo/layouts/_partials/favicon.html
···
+
{{ with .Site.Params.favicon }}
+
{{ with resources.Get . }}
+
<link rel="shortcut icon" href="{{ .RelPermalink }}" />
+
{{ end }}
+
{{ end }}
+
{{ with .Site.Params.favicon32 }}
+
{{ with resources.Get . }}
+
<link rel="icon" type="image/png" sizes="32x32" href="{{ .RelPermalink }}">
+
{{ end }}
+
{{ end }}
+
{{ with .Site.Params.favicon16 }}
+
{{ with resources.Get . }}
+
<link rel="icon" type="image/png" sizes="16x16" href="{{ .RelPermalink }}">
+
{{ end }}
+
{{ end }}
+
{{ with .Site.Params.appletouchicon }}
+
{{ with resources.Get . }}
+
<link rel="apple-touch-icon" sizes="180x180" href="{{ .RelPermalink }}">
+
{{ end }}
+
{{ end }}
+3
hugo/layouts/_partials/footer.html
···
+
<footer>
+
<a href="https://veryroundbird.house" target="_blank">โ™ฅ๏ธŽ</a>
+
</footer>
+9
hugo/layouts/_partials/header.html
···
+
<header>
+
<h1>{{ .Site.Title }}</h1>
+
<p class="hosted">Hosted by <a href="!!YOURLINK!!" target="_blank">!!YOURNAME!!</a> &bull; <a href="!!LINK TO HASHTAG FILTER!!" target="_blank">#!!HASHTAG!!</a></p>
+
<div class="joined">
+
<span class="count" id="joinedCount">!!#!!</span>
+
<span class="caption">Joined</span>
+
</div>
+
{{- partial "nav.html" . -}}
+
</header>
+3
hugo/layouts/_partials/home_scripts.html
···
+
{{ with resources.Get "js/home.js" }}
+
<script type="text/javascript" src="{{ .RelPermalink }}"></script>
+
{{ end }}
+8
hugo/layouts/_partials/nav.html
···
+
<nav>
+
<ul>
+
{{ $currentPage := . }}
+
{{ range .Site.Menus.main }}
+
<li><a href="{{ .URL }}"{{ if $currentPage.IsMenuCurrent .Menu . }} class="current"{{ end }}{{ if .Params.External }} rel="external" target="_blank"{{ end }}>{{ .Name }}</a></li>
+
{{ end }}
+
</ul>
+
</nav>
+19
hugo/layouts/_partials/post_navigator.html
···
+
<div style="font-size:0.8em;display:flex;gap:16px;justify-content:center;">
+
<p>
+
{{ if .PrevInSection }}
+
<a href="{{ .PrevInSection.Permalink }}">
+
<< Previous Post</a>
+
{{ else }}
+
<strike>
+
<< Previous Post</strike>
+
{{ end }}
+
</p>
+
<p>|</p>
+
<p>
+
{{ if .NextInSection }}
+
<a href="{{ .NextInSection.Permalink }}">Next Post >></a>
+
{{ else }}
+
<strike>Next Post >></strike>
+
{{ end }}
+
</p>
+
</div>
+13
hugo/layouts/_partials/seo_tags.html
···
+
<!-- Primary Meta Tags -->
+
<meta name="title" content="{{ with .Title }}{{ . }}{{ else }}{{ .Site.Title }}{{ end }}" />
+
<meta name="description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" />
+
<meta name="keywords" content="{{ if .IsPage}}{{ range $index, $tag := .Params.tags }}{{ $tag }},{{ end }}{{ else }}{{ range $plural, $terms := .Site.Taxonomies }}{{ range $term, $val := $terms }}{{ printf "%s," $term }}{{ end }}{{ end }}{{ end }}" />
+
+
<!-- Open Graph / Facebook -->
+
{{ template "_internal/opengraph.html" . }}
+
+
<!-- Twitter -->
+
{{ template "_internal/twitter_cards.html" . }}
+
+
<!-- Microdata -->
+
{{ template "_internal/schema.html" . }}
+104
hugo/layouts/_partials/submissions_scripts.html
···
+
{{ with resources.Get "js/afs.modern.js" }}
+
<script type="module">
+
import { AFS } from '{{ .Permalink }}';
+
const afs = new AFS({
+
// Required Selectors
+
containerSelector: '#list',
+
itemSelector: '.item',
+
+
// CSS Classes
+
activeClass: 'active',
+
hiddenClass: 'hidden',
+
transitionClass: 'afs-transition',
+
searchKeys: ['title', 'authors', 'tags'],
+
debounceTime: 200, // search input delay
+
+
// Date Handling
+
dateFormat: 'YYYY-MM-DD',
+
dateFilter: {
+
enabled: true,
+
format: 'YYYY-MM-DDThh:mm:ss'
+
},
+
+
// Counter Configuration
+
counter: {
+
template: 'Showing {visible} of {total}',
+
showFiltered: true,
+
filteredTemplate: '({filtered} filtered)',
+
noResultsTemplate: 'No items found',
+
formatter: (num) => num.toLocaleString()
+
},
+
+
sort: {
+
enabled: true,
+
buttonSelector: '.afs-btn-sort'
+
},
+
+
// Animation Configuration
+
animation: {
+
type: 'fade',
+
duration: 200,
+
easing: 'ease-out',
+
inClass: 'afs-animation-enter',
+
outClass: 'afs-animation-leave'
+
},
+
+
// Lifecycle Options
+
responsive: true,
+
preserveState: false,
+
stateExpiry: 86400000, // 24 hours
+
observeDOM: false,
+
+
// Style Configuration
+
styles: {
+
colors: {
+
primary: '#000',
+
background: '#e5e7eb',
+
text: '#000',
+
textHover: '#fff'
+
}
+
}
+
});
+
+
// add date range filter
+
afs.dateFilter.addDateRange({
+
key: 'date',
+
container: document.querySelector('#date-filter'),
+
format: 'YYYY-MM-DD',
+
minDate: new Date("{{ site.Params.StartDate }}".match(/[0-9]{4}-[0-9]{2}-[0-9]{2}/)[0]),
+
maxDate: new Date("{{ site.Params.EndDate }}".match(/[0-9]{4}-[0-9]{2}-[0-9]{2}/)[0])
+
});
+
+
// fixes some behavior of the sort buttons
+
document.querySelectorAll('button.custom-sort:not([data-sort-key="shuffle"])').forEach((elt) => {
+
elt.addEventListener('click', (e) => {
+
e.preventDefault();
+
e.stopPropagation();
+
const btn = e.target.closest('button');
+
document.querySelectorAll('button.custom-sort:not([data-sort-key="'+btn.getAttribute('data-sort-key')+'"])').forEach((s) => {
+
s.classList.remove('sort-active');
+
});
+
if (btn.classList.contains('sort-active')) {
+
if (btn.getAttribute('data-sort-direction') === 'asc') {
+
btn.setAttribute('data-sort-direction', 'desc');
+
btn.querySelector('.icon').classList.remove('sort-asc');
+
btn.querySelector('.icon').classList.add('sort-desc');
+
} else {
+
btn.setAttribute('data-sort-direction', 'asc');
+
btn.querySelector('.icon').classList.remove('sort-desc');
+
btn.querySelector('.icon').classList.add('sort-asc');
+
}
+
afs.sort.sort(btn.getAttribute('data-sort-key'), btn.getAttribute('data-sort-direction'));
+
} else {
+
btn.classList.add('sort-active');
+
afs.sort.sort(btn.getAttribute('data-sort-key'), btn.getAttribute('data-sort-direction'));
+
}
+
});
+
});
+
+
// random sort button
+
document.querySelector('[data-sort-key="shuffle"]').addEventListener('click', (e) => {
+
afs.sort.shuffle();
+
});
+
</script>
+
{{ end }}
+36
hugo/layouts/baseof.html
···
+
<!DOCTYPE html>
+
<html lang="{{ with .Site.LanguageCode }}{{ . }}{{ else }}en-US{{ end }}">
+
+
<head>
+
<meta charset="utf-8">
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
{{- partial "favicon.html" . -}}
+
<title>{{- block "title" . }}{{ .Site.Title }}{{ with .Title }} | {{ . }}{{ end }}{{- end }}</title>
+
+
{{- partial "seo_tags.html" . -}}
+
<meta name="referrer" content="no-referrer-when-downgrade" />
+
<link rel="manifest" href="./site.webmanifest">
+
+
{{ with .OutputFormats.Get "rss" -}}
+
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
+
{{ end -}}
+
+
{{- partial "style.html" . -}}
+
</head>
+
+
<body class="{{- block 'bodyClass' .}}{{- end }}">
+
<div id="banner">
+
<!-- uncomment the below line if banner is desired -->
+
<!-- <img src="!!YOURBANNER!!" alt="!!BANNERALT!!" /> -->
+
</div>
+
<div id="page">
+
{{- partial "header.html" . -}}
+
<main>
+
{{- block "main" . }}{{- end }}
+
</main>
+
<main>
+
{{- block "main" . }}{{- end }}
+
</main>
+
{{- partial "footer.html" . -}}
+
</body>
+
</html>
hugo/layouts/games/page.html

This is a binary file and will not be displayed.

+79
hugo/layouts/games/section.html
···
+
{{ define "bodyClass" }}submissions wide{{ end }}
+
+
{{ define "main" }}
+
<aside id="filters">
+
<div class="afs-filter-container">
+
<!-- Filter Controls -->
+
<div class="afs-filter-controls">
+
<!-- Basic Filters -->
+
+
<!-- Search Input -->
+
<input type="text" class="afs-filter-search" placeholder="Search by title, author, or tags" />
+
+
<p class="label">Sort entries by:</p>
+
<ul id="sorts">
+
<li><button class="custom-sort" data-sort-key="date" data-sort-direction="desc"> <span class="afs-sort-direction"><span class="icon sort-desc"></span></span> Date</button></li>
+
<li><button class="custom-sort" data-sort-key="title" data-sort-direction="asc"> <span class="afs-sort-direction"><span class="icon sort-desc"></span></span> Title</button></li>
+
<li><button class="custom-sort" data-sort-key="shuffle" data-sort-direction="desc"> <span class="afs-sort-direction"><span class="icon random"></span></span> Random</button></li>
+
</ul>
+
+
<details open><summary>Platform</summary>
+
<ul>
+
<li><button class="afs-btn-filter" data-filter="platforms:browser"><span class="icon web"></span> Play in browser</button></li>
+
<li><button class="afs-btn-filter" data-filter="platforms:windows"><span class="icon windows"></span> Windows</button></li>
+
<li><button class="afs-btn-filter" data-filter="platforms:macos"><span class="icon macos"></span> Mac OS</button></li>
+
<li><button class="afs-btn-filter" data-filter="platforms:linux"><span class="icon linux"></span> Linux</button></li>
+
<li><button class="afs-btn-filter" data-filter="platforms:android"><span class="icon android"></span> Android</button></li>
+
</ul>
+
</details>
+
+
<details><summary>Tags</summary>
+
<div id="tags"></div>
+
</details>
+
+
<details><summary>Submission Date</summary>
+
<div id="date-filter"></div>
+
</details>
+
+
<!-- Results Counter -->
+
<div class="afs-filter-counter"></div>
+
</div>
+
+
<!-- Pagination Container -->
+
<div class="afs-pagination-container"></div>
+
</div>
+
</aside>
+
<div id="list">
+
{{ range .Pages }}
+
<article class="item" data-date="{{ .Date }}" data-categories="" data-title="{{ .Title }}" data-authors="{{ if .Params.Authors }}{{ end }}">
+
<div class="thumb">
+
<a href="{{ .Permalink }}">
+
{{ $p := . }}
+
{{ with resources.Get .Params.Thumb }}
+
<img src="{{ .Permalink }}" alt="{{ $p.Title }} thumbnail image" class="thumb-img" />
+
{{ end }}
+
</a>
+
<div class="platform-icons">
+
{{ range .Params.Platforms }}
+
<span class="icon {{ . }}" title="{{ . }}">{{ . }}</span>
+
{{ end }}
+
</div>
+
</div>
+
<h3><a href="{{ .Permalink }}">{{ .Title }}</a></h3>
+
<div class="authors">
+
{{ if .Params.Authors }}
+
{{ range .Params.Authors }}
+
<a href="{{ .Link }}" target="_blank">{{ .Name }}</a>
+
{{ end }}
+
{{ else }}
+
Anonymous
+
{{ end }}
+
</div>
+
</article>
+
{{ end }}
+
</div>
+
{{ end }}
+
+
{{ define "scripts" }}
+
{{- partial "submissions_scripts.html" . -}}
+
{{ end }}
+33
hugo/layouts/home.html
···
+
{{ define "main" }}
+
<div class="clock">
+
<div class="dates" id="dates">
+
{{ $t2 := time.AsTime .Site.Params.EndDate }}
+
{{ if $t2.After time.Now }}
+
Submissions open from <b id="startDate" data-raw="{{ .Site.Params.StartDate }}">{{ .Site.Params.StartDate | time.Format "January 2, 2006 at 3:04pm" }}</b> to <b id="endDate" data-raw="{{ .Site.Params.EndDate}}">{{ .Site.Params.EndDate | time.Format "January 2, 2006 at 3:04pm" }}</b>
+
{{ else }}
+
The jam is now over. It ran from <b>{{ .Site.Params.StartDate | time.Format "January 2, 2006 at 3:04pm" }}</b> to <b>{{ .Site.Params.EndDate | time.Format "January 2, 2006 at 3:04pm" }}</b>. <a href="submissions.html">View X entr(y/ies)
+
{{ end }}
+
</div>
+
{{ if $t2.After time.Now }}
+
<div class="countdown">
+
<div class="counters">
+
<div class="verb">Starts in</div>
+
<div class="days"><span class="num" id="days">#</span><span class="caption">days</span></div>
+
<div class="hours"><span class="num" id="hours">#</span><span class="caption">hours</span></div>
+
<div class="minutes"><span class="num" id="minutes">#</span><span class="caption">minutes</span></div>
+
<div class="seconds"><span class="num" id="seconds">#</span><span class="caption">seconds</span></div>
+
</div>
+
</div>
+
<div class="join">
+
<a href="{{ .Site.Params.JoinLink }}" class="joinbtn">Join Jam</a>
+
</div>
+
{{ end }}
+
</div>
+
<div class="content">
+
{{ .Content }}
+
</div>
+
{{ end }}
+
+
{{ define "scripts" }}
+
{{- partial "home_scripts.html" . -}}
+
{{ end }}
-3
hugo/layouts/index.html
···
-
{{ define "main" }}
-
{{ .Content }}
-
{{ end }}
+37
hugo/layouts/list.html
···
+
{{ define "main" }}
+
<content>
+
{{ if .Data.Singular }}
+
<h3 style="margin-bottom:0">Filtering for "{{ .Title }}"</h3>
+
<small>
+
<a href="{{ "blog" | relURL }}">Remove filter</a>
+
</small>
+
{{ end }}
+
<ul class="blog-posts">
+
{{ range .Pages }}
+
<li>
+
<span>
+
<i>
+
<time datetime='{{ .Date.Format "2006-01-02" }}'>
+
{{ .Date.Format (default "02 Jan, 2006" .Site.Params.dateFormat) }}
+
</time>
+
</i>
+
</span>
+
<a href="{{ .Permalink }}">{{ .Title }}</a>
+
</li>
+
{{ else }}
+
<li>
+
No posts yet
+
</li>
+
{{ end }}
+
</ul>
+
{{ if not .Data.Singular }}
+
<small>
+
<div>
+
{{ range .Site.Taxonomies.tags }}
+
<a href="{{ .Page.Permalink }}">#{{ .Page.Title }}</a>&nbsp;
+
{{ end }}
+
</div>
+
</small>
+
{{ end }}
+
</content>
+
{{ end }}
-3
hugo/layouts/partials/custom_body.html
···
-
<!-- A partial to be overwritten by the user.
-
Simply place a custom_body.html into
-
your local /layouts/partials-directory -->
-3
hugo/layouts/partials/custom_head.html
···
-
<!-- A partial to be overwritten by the user.
-
Simply place a custom_head.html into
-
your local /layouts/partials-directory -->
-2
hugo/layouts/partials/favicon.html
···
-
{{ with .Site.Params.favicon }}
-
<link rel="shortcut icon" href="{{ . | absURL }}" />{{ end }}
-1
hugo/layouts/partials/footer.html
···
-
{{ if not (.Param "hideMadeWithLine") }}Made with <a href="https://github.com/janraasch/hugo-bearblog/">Hugo ส•โ€ขแดฅโ€ขส” Bear</a>{{ end }}
-4
hugo/layouts/partials/header.html
···
-
<a href="{{ "" | relURL }}" class="title">
-
<h2>{{ .Site.Title }}</h2>
-
</a>
-
<nav>{{- partial "nav.html" . -}}</nav>
-3
hugo/layouts/partials/nav.html
···
-
{{ range .Site.Menus.main }}
-
<a href="{{ .URL }}">{{ .Name }}</a>
-
{{ end }}
-19
hugo/layouts/partials/post_navigator.html
···
-
<div style="font-size:0.8em;display:flex;gap:16px;justify-content:center;">
-
<p>
-
{{ if .PrevInSection }}
-
<a href="{{ .PrevInSection.Permalink }}">
-
<< Previous Post</a>
-
{{ else }}
-
<strike>
-
<< Previous Post</strike>
-
{{ end }}
-
</p>
-
<p>|</p>
-
<p>
-
{{ if .NextInSection }}
-
<a href="{{ .NextInSection.Permalink }}">Next Post >></a>
-
{{ else }}
-
<strike>Next Post >></strike>
-
{{ end }}
-
</p>
-
</div>
-13
hugo/layouts/partials/seo_tags.html
···
-
<!-- Primary Meta Tags -->
-
<meta name="title" content="{{ with .Title }}{{ . }}{{ else }}{{ .Site.Title }}{{ end }}" />
-
<meta name="description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" />
-
<meta name="keywords" content="{{ if .IsPage}}{{ range $index, $tag := .Params.tags }}{{ $tag }},{{ end }}{{ else }}{{ range $plural, $terms := .Site.Taxonomies }}{{ range $term, $val := $terms }}{{ printf "%s," $term }}{{ end }}{{ end }}{{ end }}" />
-
-
<!-- Open Graph / Facebook -->
-
{{ template "_internal/opengraph.html" . }}
-
-
<!-- Twitter -->
-
{{ template "_internal/twitter_cards.html" . }}
-
-
<!-- Microdata -->
-
{{ template "_internal/schema.html" . }}
-153
hugo/layouts/partials/style.html
···
-
<style>
-
:root {
-
--width: 720px;
-
--font-main: Verdana, sans-serif;
-
--font-secondary: Verdana, sans-serif;
-
--font-scale: 1em;
-
--background-color: #fff;
-
--heading-color: #222;
-
--text-color: #444;
-
--link-color: #3273dc;
-
--visited-color: #8b6fcb;
-
--blockquote-color: #222;
-
}
-
-
@media (prefers-color-scheme: dark) {
-
:root {
-
--background-color: #01242e;
-
--heading-color: #eee;
-
--text-color: #ddd;
-
--link-color: #8cc2dd;
-
--visited-color: #8b6fcb;
-
--blockquote-color: #ccc;
-
}
-
}
-
-
body {
-
font-family: var(--font-secondary);
-
font-size: var(--font-scale);
-
margin: auto;
-
padding: 20px;
-
max-width: var(--width);
-
text-align: left;
-
background-color: var(--background-color);
-
word-wrap: break-word;
-
overflow-wrap: break-word;
-
line-height: 1.5;
-
color: var(--text-color);
-
}
-
-
h1,
-
h2,
-
h3,
-
h4,
-
h5,
-
h6 {
-
font-family: var(--font-main);
-
color: var(--heading-color);
-
}
-
-
a {
-
color: var(--link-color);
-
cursor: pointer;
-
text-decoration: none;
-
}
-
-
a:hover {
-
text-decoration: underline;
-
}
-
-
nav a {
-
margin-right: 8px;
-
}
-
-
strong,
-
b {
-
color: var(--heading-color);
-
}
-
-
button {
-
margin: 0;
-
cursor: pointer;
-
}
-
-
time {
-
font-family: monospace;
-
font-style: normal;
-
font-size: 15px;
-
}
-
-
main {
-
line-height: 1.6;
-
}
-
-
table {
-
width: 100%;
-
}
-
-
hr {
-
border: 0;
-
border-top: 1px dashed;
-
}
-
-
img {
-
max-width: 100%;
-
}
-
-
code {
-
font-family: monospace;
-
padding: 2px;
-
border-radius: 3px;
-
}
-
-
blockquote {
-
border-left: 1px solid #999;
-
color: var(--blockquote-color);
-
padding-left: 20px;
-
font-style: italic;
-
}
-
-
footer {
-
padding: 25px 0;
-
text-align: center;
-
}
-
-
.title:hover {
-
text-decoration: none;
-
}
-
-
.title h1 {
-
font-size: 1.5em;
-
}
-
-
.inline {
-
width: auto !important;
-
}
-
-
.highlight,
-
.code {
-
border-radius: 3px;
-
margin-block-start: 1em;
-
margin-block-end: 1em;
-
overflow-x: auto;
-
}
-
-
/* blog post list */
-
ul.blog-posts {
-
list-style-type: none;
-
padding: unset;
-
}
-
-
ul.blog-posts li {
-
display: flex;
-
}
-
-
ul.blog-posts li span {
-
flex: 0 0 130px;
-
}
-
-
ul.blog-posts li a:visited {
-
color: var(--visited-color);
-
}
-
-
</style>
+25
hugo/layouts/single.html
···
+
{{ define "main" }}
+
{{ if eq .Type "blog" }}{{ if not .Params.menu }}
+
<h1>{{ .Title }}</h1>
+
<p>
+
<i>
+
<time datetime='{{ .Date.Format "2006-01-02" }}'>
+
{{ .Date.Format (default "02 Jan, 2006" .Site.Params.dateFormat) }}
+
</time>
+
</i>
+
</p>
+
{{ end }}{{ end }}
+
<content>
+
{{ .Content }}
+
</content>
+
+
{{ if eq .Type "blog" }}{{ if (.Param "enablePostNavigator")}}
+
{{- partial "post_navigator.html" . -}}
+
{{ end }}{{ end }}
+
+
<p>
+
{{ range (.GetTerms "tags") }}
+
<a href="{{ .Permalink }}">#{{ .LinkTitle }}</a>
+
{{ end }}
+
</p>
+
{{ end }}
+5 -5
hugo/package.json
···
{
-
"name": "hugo-bearblog",
+
"name": "homemade jam",
"private": true,
"version": "1.0.0",
-
"description": "๐Ÿงธ A [Hugo](https://gohugo.io/)-theme based on [Bear Blog](https://bearblog.dev).",
+
"description": "A [Hugo](https://gohugo.io/) theme for running game (and other creative) jams.",
"main": "index.js",
"devDependencies": {
"js-beautify": "^1.15.4"
···
},
"repository": {
"type": "git",
-
"url": "git+https://github.com/janraasch/hugo-bearblog.git"
+
"url": "git+https://tangled.sh/@veryroundbird.house/homemadejam"
},
"author": {
"name": "Jan Raasch",
···
},
"license": "MIT",
"bugs": {
-
"url": "https://github.com/janraasch/hugo-bearblog/issues"
+
"url": "https://tangled.sh/@veryroundbird.house/homemadejam/issues"
},
-
"homepage": "https://github.com/janraasch/hugo-bearblog#readme"
+
"homepage": "https://tangled.sh/@veryroundbird.house/homemadejam"
}
-3
hugo/scss/_partials/_fonts.scss
···
-
@import url('https://fonts.googleapis.com/css2?family=Knewave&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap');
-
/* if you want to use different fonts, you can use other stuff from google fonts
-
if you don't want to use google, you may want to look into hosting your own fonts locally */
-116
hugo/scss/_partials/_game.scss
···
-
.game {
-
main {
-
display: grid;
-
grid-template-areas: "header header" "screenshots stuff";
-
text-align: left;
-
border-bottom: 1px var(--accent) solid;
-
padding-bottom: 0;
-
-
h2 {
-
margin: 0;
-
-
a {
-
font-size: .9rem;
-
margin-left: 10px;
-
display: inline-block;
-
vertical-align: middle;
-
}
-
}
-
-
h3 {
-
margin: 0;
-
}
-
-
.blurb {
-
margin: 1em 0;
-
}
-
-
.game-header {
-
margin: -20px -20px 0;
-
width: calc(100% + 40px);
-
border-bottom: 1px var(--accent) solid;
-
padding: 20px;
-
text-align: left;
-
grid-area: header;
-
}
-
-
.jamsub {
-
font-size: .8em;
-
font-style: italic;
-
color: color-mix(in srgb-linear, var(--foreground), var(--background) 15%);
-
margin: 0;
-
}
-
}
-
-
.screenshots {
-
border-right: 1px var(--accent) solid;
-
grid-area: screenshots;
-
padding: 20px;
-
-
.gallery {
-
display: grid;
-
gap: 10px;
-
grid-template-columns: repeat(2, 1fr);
-
grid-template-rows: auto;
-
grid-template-areas: "featured featured";
-
-
a, button {
-
position: relative;
-
padding-top: 75%;
-
width: 100%;
-
-
img {
-
position: absolute;
-
top: 0;
-
left: 0;
-
width: 100%;
-
height: 100%;
-
object-fit: cover;
-
}
-
}
-
-
& > :first-child {
-
grid-area: featured;
-
}
-
}
-
}
-
-
.interaction {
-
grid-area: stuff;
-
}
-
-
.downloads {
-
padding: 20px;
-
-
ul {
-
list-style: none;
-
margin: 1em 0;
-
padding: 0;
-
-
li {
-
margin-bottom: 10px;
-
}
-
}
-
-
.size {
-
color: color-mix(in srgb-linear, var(--foreground), var(--background) 20%);
-
}
-
-
.platforms-label {
-
display: inline-block;
-
width: 1px;
-
overflow: hidden;
-
text-indent: -999px;
-
}
-
-
.icon {
-
width: 24px;
-
height: 24px;
-
background-color: color-mix(in srgb-linear, var(--foreground), var(--background) 20%);
-
}
-
}
-
-
.comments {
-
border-top: 1px var(--accent) solid;
-
}
-
}
-52
hugo/scss/_partials/_game_list_item.scss
···
-
.item {
-
text-align: left;
-
border: 1px red solid;
-
-
h3 {
-
margin: 0;
-
font-size: 1.25em;
-
-
a {
-
color: var(--foreground);
-
text-decoration: none;
-
-
&:hover {
-
text-decoration: underline;
-
}
-
}
-
}
-
-
.thumb {
-
position: relative;
-
padding-top: 75%;
-
-
img {
-
position: absolute;
-
top: 0;
-
left: 0;
-
width: 100%;
-
height: 100%;
-
object-fit: cover;
-
}
-
}
-
-
.authors {
-
font-size: .9em;
-
margin: 5px 0;
-
-
a {
-
color: color-mix(in srgb-linear, var(--foreground), #FFFFFF 10%);
-
text-decoration: none;
-
-
&:hover {
-
text-decoration: underline;
-
}
-
}
-
}
-
-
.blurb {
-
margin-top: 5px;
-
font-size: .8em;
-
color: color-mix(in srgb-linear, var(--foreground), #FFFFFF 10%);
-
}
-
}
-181
hugo/scss/_partials/_global.scss
···
-
* {
-
box-sizing: border-box;
-
}
-
-
body {
-
background-color: var(--background);
-
background-image: url(--pageBgImage);
-
color: var(--foreground);
-
font-family: var(--mainfont);
-
font-size: 1em;
-
}
-
-
a {
-
color: var(--accent);
-
text-decoration: underline;
-
-
&:hover {
-
color: color-mix(in srgb-linear, var(--accent), #000000 50%);
-
}
-
}
-
-
.icon {
-
width: 16px;
-
height: 16px;
-
text-indent: -999px;
-
overflow: hidden;
-
display: inline-block;
-
vertical-align: middle;
-
margin-right: 5px;
-
-
&.web {
-
mask: url(../images/web.svg);
-
}
-
-
&.windows {
-
mask: url(../images/windows.svg);
-
}
-
-
&.macos {
-
mask: url(../images/macos.svg);
-
}
-
-
&.linux {
-
mask: url(../images/linux.svg);
-
}
-
-
&.android {
-
mask: url(../images/android.svg);
-
}
-
-
&.random {
-
mask: url(../images/random.svg);
-
}
-
-
&.sort-asc {
-
mask: url(../images/sort-asc.svg);
-
}
-
-
&.sort-desc {
-
mask: url(../images/sort-desc.svg);
-
}
-
}
-
-
.btn {
-
padding: 5px 10px;
-
font-size: 1em;
-
font-weight: bold;
-
border-radius: 5px;
-
background-color: var(--accent);
-
color: var(--background);
-
text-decoration: none;
-
white-space: pre;
-
-
&:hover {
-
background-color: color-mix(in srgb-linear, var(--accent), #000000 50%);
-
color: var(--background);
-
}
-
}
-
-
#page {
-
max-width: 960px;
-
margin: 50px auto;
-
background-color: color-mix(in srgb-linear, var(--background), #FFFFFF 50%);
-
background-image: var(--contentBgImage);
-
border-radius: var(--roundedCorners);
-
-
body.wide & {
-
max-width: none;
-
margin: 0;
-
}
-
}
-
-
header {
-
padding: 20px 20px 0;
-
position: relative;
-
background-color: color-mix(in srgb-linear, var(--background), #FFFFFF 25%);
-
-
h1 {
-
font-size: 2.5em;
-
font-weight: bold;
-
margin: 0;
-
}
-
-
.hosted {
-
margin: 0;
-
}
-
-
.joined,
-
.entries {
-
text-align: center;
-
position: absolute;
-
top: 20px;
-
right: 20px;
-
-
.count {
-
font-size: 2.25em;
-
display: block;
-
}
-
-
.caption {
-
font-size: .8em;
-
display: block;
-
color: color-mix(in srgb-linear, var(--foreground) #FFFFFF, 25%);
-
}
-
}
-
-
nav {
-
margin-top: 20px;
-
padding-bottom: 10px;
-
-
ul {
-
margin-bottom: 0;
-
display: flex;
-
gap: 10px;
-
list-style: none;
-
padding: 0;
-
-
li {
-
a {
-
text-decoration: none;
-
padding: 5px 0;
-
border-bottom: 5px transparent solid;
-
color: var(--foreground);
-
-
&.current,
-
&:hover {
-
border-bottom: 5px var(--accent) solid;
-
color: var(--foreground);
-
}
-
}
-
}
-
}
-
}
-
}
-
-
main {
-
padding: 20px;
-
text-align: center;
-
}
-
-
footer {
-
text-align: center;
-
font-size: .8em;
-
padding: 5px 10px;
-
margin-top: 20px;
-
-
a {
-
text-decoration: none;
-
}
-
}
-
-
[popover] {
-
position: fixed;
-
z-index: 99;
-
max-width: 90%;
-
max-height: 90%;
-
}
-
-
[popover]:-internal-popover-in-top-layer::backdrop {
-
background-color: rgba(0,0,0,.5);
-
}
-83
hugo/scss/_partials/_homepage.scss
···
-
.clock {
-
border: 1px var(--accent) solid;
-
border-radius: 5px;
-
display: inline-grid;
-
grid-template-areas: "date date" "countdown join";
-
margin: 50px auto;
-
-
.dates {
-
border-bottom: 1px var(--accent) solid;
-
padding: 10px;
-
grid-area: date;
-
text-align: center;
-
}
-
-
.countdown {
-
grid-area: countdown;
-
border-right: 1px var(--accent) solid;
-
padding: 20px;
-
text-align: right;
-
display: flex;
-
align-items: center;
-
justify-content: flex-end;
-
-
.counters {
-
display: flex;
-
align-items: stretch;
-
-
& > div {
-
padding: 10px;
-
border-right: 2px var(--accent) solid;
-
display: flex;
-
flex-direction: column;
-
justify-content: center;
-
align-items: center;
-
white-space: pre;
-
-
&:last-child {
-
border-right: none;
-
}
-
}
-
-
span {
-
display: block;
-
text-align: center;
-
-
&.num {
-
font-weight: bold;
-
}
-
-
&.caption {
-
font-size: .8em;
-
font-style: italic;
-
}
-
}
-
}
-
}
-
-
.join {
-
display: flex;
-
align-items: center;
-
justify-content: flex-start;
-
padding: 20px;
-
}
-
-
.joinbtn {
-
padding: 10px 20px;
-
font-size: 1.25em;
-
font-weight: bold;
-
border-radius: 5px;
-
background-color: var(--accent);
-
color: var(--background);
-
text-decoration: none;
-
white-space: pre;
-
-
&:hover {
-
background-color: color-mix(in srgb-linear, var(--accent), #000000 50%);
-
}
-
}
-
}
-
-
.content {
-
text-align: left;
-
}
-17
hugo/scss/_partials/_posts.scss
···
-
.post-list {
-
list-style: none;
-
margin: 0;
-
padding: 0;
-
text-align: left;
-
-
h3 {
-
font-weight: normal;
-
font-size: 1em;
-
-
.date {
-
margin-left: 5px;
-
font-size: .8em;
-
color: color-mix(in srgb-linear, var(--foreground), var(--background) 20%);
-
}
-
}
-
}
-106
hugo/scss/_partials/_submissions.scss
···
-
#filters {
-
grid-area: filters;
-
text-align: left;
-
-
#tags {
-
display: flex;
-
flex-wrap: wrap;
-
gap: 5px;
-
justify-content: flex-start;
-
-
button {
-
white-space: pre;
-
}
-
}
-
-
details {
-
margin-bottom: 10px;
-
-
ul {
-
list-style: none;
-
margin: 0;
-
padding: 0;
-
}
-
}
-
-
p.label,
-
details summary {
-
font-size: .8em;
-
color: color-mix(in srgb-linear, var(--foreground), var(--background) 10%);
-
padding: 5px 0;
-
margin-bottom: 0;
-
}
-
-
ul#sorts {
-
list-style: none;
-
margin: 0 0 10px;
-
padding: 0;
-
-
li {
-
button {
-
appearance: none;
-
border: none;
-
background-color: transparent;
-
color: var(--foreground);
-
border-radius: 0;
-
font-family: inherit;
-
font-size: inherit;
-
font-size: .9em;
-
-
img {
-
width: 16px;
-
height: 16px;
-
margin-right: 5px;
-
display: inline-block;
-
vertical-align: middle;
-
}
-
-
&.sort-active {
-
color: color-mix(in srgb-linear, var(--accent), #000000 10%);
-
font-weight: bold;
-
}
-
}
-
}
-
}
-
-
.afs-btn-filter {
-
appearance: none;
-
padding: 3px 0;
-
border: none;
-
border-radius: 0;
-
font-family: inherit;
-
background-color: transparent;
-
-
&.active {
-
color: color-mix(in srgb-linear, var(--accent), #000000 10%);
-
background-color: transparent;
-
font-weight: bold;
-
}
-
}
-
-
.afs-filter-search {
-
width: 100%;
-
padding: 0.5rem;
-
border: 1px solid var(--accent);
-
border-radius: 0.25rem;
-
font-size: 0.875rem;
-
color: var(--foreground);
-
transition: border-color 0.2s ease;
-
margin-bottom: 10px;
-
font-family: inherit;
-
}
-
-
.afs-filter-counter {
-
text-align: center;
-
font-style: italic;
-
font-size: .9em;
-
}
-
}
-
-
#list {
-
display: grid;
-
grid-area: list;
-
grid-template-columns: repeat(4, 1fr);
-
grid-template-rows: auto;
-
gap: 10px;
-
}
-13
hugo/scss/_partials/_variables.scss
···
-
/* display variables! skip the images if you don't want them */
-
-
:root {
-
--background: #ECEBDE;
-
--foreground: #000000;
-
--accent: #A59D84;
-
--mainfont: 'Work Sans', Helvetica, Arial, sans-serif;
-
--headingfont: 'Knewave', 'Arial Black', sans-serif;
-
--roundedCorners: 0px;
-
-
--pageBgImage: url();
-
--contentBgImage: url();
-
}
-7
hugo/scss/style.scss
···
-
@use '_partials/_fonts';
-
@use '_partials/_variables';
-
@use '_partials/_global';
-
@use '_partials/_homepage';
-
@use '_partials/_submissions';
-
@use '_partials/_game_list_item';
-
@use '_partials/_game';
hugo/static/images/android-chrome-192x192.png

This is a binary file and will not be displayed.

hugo/static/images/android-chrome-512x512.png

This is a binary file and will not be displayed.

+1
hugo/static/images/android.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M452.5 317.9C465.8 317.9 476.5 328.6 476.5 341.9C476.5 355.2 465.8 365.9 452.5 365.9C439.2 365.9 428.5 355.2 428.5 341.9C428.5 328.6 439.2 317.9 452.5 317.9zM187.4 317.9C200.7 317.9 211.4 328.6 211.4 341.9C211.4 355.2 200.7 365.9 187.4 365.9C174.1 365.9 163.4 355.2 163.4 341.9C163.4 328.6 174.1 317.9 187.4 317.9zM461.1 221.4L509 138.4C509.8 137.3 510.3 136 510.5 134.6C510.7 133.2 510.7 131.9 510.4 130.5C510.1 129.1 509.5 127.9 508.7 126.8C507.9 125.7 506.9 124.8 505.7 124.1C504.5 123.4 503.2 123 501.8 122.8C500.4 122.6 499.1 122.8 497.8 123.2C496.5 123.6 495.3 124.3 494.2 125.1C493.1 125.9 492.3 127.1 491.7 128.3L443.2 212.4C404.4 195 362.4 186 319.9 186C277.4 186 235.4 195 196.6 212.4L148.2 128.4C147.6 127.2 146.7 126.1 145.7 125.2C144.7 124.3 143.4 123.7 142.1 123.3C140.8 122.9 139.4 122.8 138.1 122.9C136.8 123 135.4 123.5 134.2 124.2C133 124.9 132 125.8 131.2 126.9C130.4 128 129.8 129.3 129.5 130.6C129.2 131.9 129.2 133.3 129.4 134.7C129.6 136.1 130.2 137.3 130.9 138.5L178.8 221.5C96.5 266.2 40.2 349.5 32 448L608 448C599.8 349.5 543.5 266.2 461.1 221.4z"/></svg>
hugo/static/images/apple-touch-icon.png

This is a binary file and will not be displayed.

+1
hugo/static/images/bluesky.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M439.8 358.7C436.5 358.3 433.1 357.9 429.8 357.4C433.2 357.8 436.5 358.3 439.8 358.7zM320 291.1C293.9 240.4 222.9 145.9 156.9 99.3C93.6 54.6 69.5 62.3 53.6 69.5C35.3 77.8 32 105.9 32 122.4C32 138.9 41.1 258 47 277.9C66.5 343.6 136.1 365.8 200.2 358.6C203.5 358.1 206.8 357.7 210.2 357.2C206.9 357.7 203.6 358.2 200.2 358.6C106.3 372.6 22.9 406.8 132.3 528.5C252.6 653.1 297.1 501.8 320 425.1C342.9 501.8 369.2 647.6 505.6 528.5C608 425.1 533.7 372.5 439.8 358.6C436.5 358.2 433.1 357.8 429.8 357.3C433.2 357.7 436.5 358.2 439.8 358.6C503.9 365.7 573.4 343.5 593 277.9C598.9 258 608 139 608 122.4C608 105.8 604.7 77.7 586.4 69.5C570.6 62.4 546.4 54.6 483.2 99.3C417.1 145.9 346.1 240.4 320 291.1z"/></svg>
+1
hugo/static/images/facebook.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 440 146.7 540.8 258.2 568.5L258.2 398.2L205.4 398.2L205.4 320L258.2 320L258.2 286.3C258.2 199.2 297.6 158.8 383.2 158.8C399.4 158.8 427.4 162 438.9 165.2L438.9 236C432.9 235.4 422.4 235 409.3 235C367.3 235 351.1 250.9 351.1 292.2L351.1 320L434.7 320L420.3 398.2L351 398.2L351 574.1C477.8 558.8 576 450.9 576 320z"/></svg>
hugo/static/images/favicon-16x16.png

This is a binary file and will not be displayed.

hugo/static/images/favicon-32x32.png

This is a binary file and will not be displayed.

hugo/static/images/favicon.ico

This is a binary file and will not be displayed.

+1
hugo/static/images/linux.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M316.9 187.3C317.9 187.8 318.7 189 319.9 189C321 189 322.7 188.6 322.8 187.5C323 186.1 320.9 185.2 319.6 184.6C317.9 183.9 315.7 183.6 314.1 184.5C313.7 184.7 313.3 185.2 313.5 185.6C313.8 186.9 315.8 186.7 316.9 187.3zM295 189C296.2 189 297 187.8 298 187.3C299.1 186.7 301.1 186.9 301.5 185.7C301.7 185.3 301.3 184.8 300.9 184.6C299.3 183.7 297.1 184 295.4 184.7C294.1 185.3 292 186.2 292.2 187.6C292.3 188.6 294 189.1 295 189zM516 467.8C512.4 463.8 510.7 456.2 508.8 448.1C507 440 504.9 431.3 498.3 425.7C497 424.6 495.7 423.6 494.3 422.8C493 422 491.6 421.3 490.2 420.8C499.4 393.5 495.8 366.3 486.5 341.7C475.1 311.6 455.2 285.3 440 267.3C422.9 245.8 406.3 225.4 406.6 195.3C407.1 149.4 411.7 64.1 330.8 64C228.4 63.8 254 167.4 252.9 199.2C251.2 222.6 246.5 241 230.4 263.9C211.5 286.4 184.9 322.7 172.3 360.6C166.3 378.5 163.5 396.7 166.1 413.9C159.6 419.7 154.7 428.6 149.5 434.1C145.3 438.4 139.2 440 132.5 442.4C125.8 444.8 118.5 448.4 114 456.9C111.9 460.8 111.2 465 111.2 469.3C111.2 473.2 111.8 477.2 112.4 481.1C113.6 489.2 114.9 496.8 113.2 501.9C108 516.3 107.3 526.3 111 533.6C114.8 540.9 122.4 544.1 131.1 545.9C148.4 549.5 171.9 548.6 190.4 558.4C210.2 568.8 230.3 572.5 246.3 568.8C257.9 566.2 267.4 559.2 272.2 548.6C284.7 548.5 298.5 543.2 320.5 542C335.4 540.8 354.1 547.3 375.6 546.1C376.2 548.4 377 550.7 378.1 552.8L378.1 552.9C386.4 569.6 401.9 577.2 418.4 575.9C435 574.6 452.5 564.9 466.7 548C480.3 531.6 502.7 524.8 517.6 515.8C525 511.3 531 505.7 531.5 497.5C531.9 489.3 527.1 480.2 516 467.8zM319.8 151.3C329.6 129.1 354 129.5 363.8 150.9C370.3 165.1 367.4 181.8 359.5 191.3C357.9 190.5 353.6 188.7 346.9 186.4C348 185.2 350 183.7 350.8 181.8C355.6 170 350.6 154.8 341.7 154.5C334.4 154 327.8 165.3 329.9 177.5C325.8 175.5 320.5 174 316.9 173.1C315.9 166.2 316.6 158.5 319.8 151.3zM279.1 139.8C289.2 139.8 299.9 154 298.2 173.3C294.7 174.3 291.1 175.8 288 177.9C289.2 169 284.7 157.8 278.4 158.3C270 159 268.6 179.5 276.6 186.4C277.6 187.2 278.5 186.2 270.7 191.9C255.1 177.3 260.2 139.8 279.1 139.8zM265.5 200.5C271.7 195.9 279.1 190.5 279.6 190C284.3 185.6 293.1 175.8 307.5 175.8C314.6 175.8 323.1 178.1 333.4 184.7C339.7 188.8 344.7 189.1 356 194C364.4 197.5 369.7 203.7 366.5 212.2C363.9 219.3 355.5 226.6 343.8 230.3C332.7 233.9 324 246.3 305.6 245.2C301.7 245 298.6 244.2 296 243.1C288 239.6 283.8 232.7 276 228.1C267.4 223.3 262.8 217.7 261.3 212.8C259.9 207.9 261.3 203.8 265.5 200.5zM268.8 534.5C266.1 569.6 224.9 568.9 193.5 552.5C163.6 536.7 124.9 546 117 530.6C114.6 525.9 114.6 517.9 119.6 504.2L119.6 504C122 496.4 120.2 488 119 480.1C117.8 472.3 117.2 465.1 119.9 460.1C123.4 453.4 128.4 451 134.7 448.8C145 445.1 146.5 445.4 154.3 438.9C159.8 433.2 163.8 426 168.6 420.9C173.7 415.4 178.6 412.8 186.3 414C194.4 415.2 201.4 420.8 208.2 430L227.8 465.6C237.3 485.5 270.9 514 268.8 534.5zM267.4 508.6C263.3 502 257.8 495 253 489C260.1 489 267.2 486.8 269.7 480.1C272 473.9 269.7 465.2 262.3 455.2C248.8 437 224 422.7 224 422.7C210.5 414.3 202.9 404 199.4 392.8C195.9 381.6 196.4 369.5 199.1 357.6C204.3 334.7 217.7 312.4 226.3 298.4C228.6 296.7 227.1 301.6 217.6 319.2C209.1 335.3 193.2 372.5 215 401.6C215.6 380.9 220.5 359.8 228.8 340.1C240.8 312.7 266.1 265.2 268.1 227.4C269.2 228.2 272.7 230.6 274.3 231.5C278.9 234.2 282.4 238.2 286.9 241.8C299.3 251.8 315.4 251 329.3 243C335.5 239.5 340.5 235.5 345.2 234C355.1 230.9 363 225.4 367.5 219C375.2 249.4 393.2 293.3 404.7 314.7C410.8 326.1 423 350.2 428.3 379.3C431.6 379.2 435.3 379.7 439.2 380.7C453 345 427.5 306.5 415.9 295.8C411.2 291.2 411 289.2 413.3 289.3C425.9 300.5 442.5 323 448.5 348.3C451.3 359.9 451.8 372 448.9 384C465.3 390.8 484.8 401.9 479.6 418.8C477.4 418.7 476.4 418.8 475.4 418.8C478.6 408.7 471.5 401.2 452.6 392.7C433 384.1 416.6 384.1 414.3 405.2C402.2 409.4 396 419.9 392.9 432.5C390.1 443.7 389.3 457.2 388.5 472.4C388 480.1 384.9 490.4 381.7 501.4C349.6 524.3 305 534.3 267.4 508.6zM524.8 497.1C523.9 513.9 483.6 517 461.6 543.6C448.4 559.3 432.2 568 418 569.1C403.8 570.2 391.5 564.3 384.3 549.8C379.6 538.7 381.9 526.7 385.4 513.5C389.1 499.3 394.6 484.7 395.3 472.9C396.1 457.7 397 444.4 399.5 434.2C402.1 423.9 406.1 417 413.2 413.1C413.5 412.9 413.9 412.8 414.2 412.6C415 425.8 421.5 439.2 433 442.1C445.6 445.4 463.7 434.6 471.4 425.8C480.4 425.5 487.1 424.9 494 430.9C503.9 439.4 501.1 461.2 511.1 472.5C521.7 484.1 525.1 492 524.8 497.1zM269.4 212.7C271.4 214.6 274.1 217.2 277.4 219.8C284 225 293.2 230.4 304.7 230.4C316.3 230.4 327.2 224.5 336.5 219.6C341.4 217 347.4 212.6 351.3 209.2C355.2 205.8 357.2 202.9 354.4 202.6C351.6 202.3 351.8 205.2 348.4 207.7C344 210.9 338.7 215.1 334.5 217.5C327.1 221.7 315 227.7 304.6 227.7C294.2 227.7 285.9 222.9 279.7 218C276.6 215.5 274 213 272 211.1C270.5 209.7 270.1 206.5 267.7 206.2C266.3 206.1 265.9 209.9 269.4 212.7z"/></svg>
+1
hugo/static/images/macos.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M320 176C311.2 176 304 168.8 304 160L304 144C304 99.8 339.8 64 384 64L400 64C408.8 64 416 71.2 416 80L416 96C416 140.2 380.2 176 336 176L320 176zM96 352C96 275.7 131.7 192 208 192C235.3 192 267.7 202.3 290.7 211.3C309.5 218.6 330.6 218.6 349.4 211.3C372.3 202.4 404.8 192 432.1 192C508.4 192 544.1 275.7 544.1 352C544.1 480 464.1 576 384.1 576C367.6 576 346 569.4 332.6 564.7C324.5 561.9 315.7 561.9 307.6 564.7C294.2 569.4 272.6 576 256.1 576C176.1 576 96.1 480 96.1 352z"/></svg>
+1
hugo/static/images/mastodon.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M529 243.1C529 145.9 465.3 117.4 465.3 117.4C402.8 88.7 236.7 89 174.8 117.4C174.8 117.4 111.1 145.9 111.1 243.1C111.1 358.8 104.5 502.5 216.7 532.2C257.2 542.9 292 545.2 320 543.6C370.8 540.8 399.3 525.5 399.3 525.5L397.6 488.6C397.6 488.6 361.3 500 320.5 498.7C280.1 497.3 237.5 494.3 230.9 444.7C230.3 440.1 230 435.4 230 430.8C315.6 451.7 388.7 439.9 408.7 437.5C464.8 430.8 513.7 396.2 519.9 364.6C529.7 314.8 528.9 243.1 528.9 243.1zM453.9 368.3L407.3 368.3L407.3 254.1C407.3 204.4 343.3 202.5 343.3 261L343.3 323.5L297 323.5L297 261C297 202.5 233 204.4 233 254.1L233 368.3L186.3 368.3C186.3 246.2 181.1 220.4 204.7 193.3C230.6 164.4 284.5 162.5 308.5 199.4L320.1 218.9L331.7 199.4C355.8 162.3 409.8 164.6 435.5 193.3C459.2 220.6 453.9 246.3 453.9 368.3L453.9 368.3z"/></svg>
+1
hugo/static/images/random.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M467.8 98.4C479.8 93.4 493.5 96.2 502.7 105.3L566.7 169.3C572.7 175.3 576.1 183.4 576.1 191.9C576.1 200.4 572.7 208.5 566.7 214.5L502.7 278.5C493.5 287.7 479.8 290.4 467.8 285.4C455.8 280.4 448 268.9 448 256L448 224L416 224C405.9 224 396.4 228.7 390.4 236.8L358 280L318 226.7L339.2 198.4C357.3 174.2 385.8 160 416 160L448 160L448 128C448 115.1 455.8 103.4 467.8 98.4zM218 360L258 413.3L236.8 441.6C218.7 465.8 190.2 480 160 480L96 480C78.3 480 64 465.7 64 448C64 430.3 78.3 416 96 416L160 416C170.1 416 179.6 411.3 185.6 403.2L218 360zM502.6 534.6C493.4 543.8 479.7 546.5 467.7 541.5C455.7 536.5 448 524.9 448 512L448 480L416 480C385.8 480 357.3 465.8 339.2 441.6L185.6 236.8C179.6 228.7 170.1 224 160 224L96 224C78.3 224 64 209.7 64 192C64 174.3 78.3 160 96 160L160 160C190.2 160 218.7 174.2 236.8 198.4L390.4 403.2C396.4 411.3 405.9 416 416 416L448 416L448 384C448 371.1 455.8 359.4 467.8 354.4C479.8 349.4 493.5 352.2 502.7 361.3L566.7 425.3C572.7 431.3 576.1 439.4 576.1 447.9C576.1 456.4 572.7 464.5 566.7 470.5L502.7 534.5z"/></svg>
hugo/static/images/screenshot-dark.png

This is a binary file and will not be displayed.

hugo/static/images/screenshot.png

This is a binary file and will not be displayed.

+1
hugo/static/images/sort-asc.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M278.6 438.6L182.6 534.6C170.1 547.1 149.8 547.1 137.3 534.6L41.3 438.6C28.8 426.1 28.8 405.8 41.3 393.3C53.8 380.8 74.1 380.8 86.6 393.3L128 434.7L128 128C128 110.3 142.3 96 160 96C177.7 96 192 110.3 192 128L192 434.7L233.4 393.3C245.9 380.8 266.2 380.8 278.7 393.3C291.2 405.8 291.2 426.1 278.7 438.6zM352 96L384 96C401.7 96 416 110.3 416 128C416 145.7 401.7 160 384 160L352 160C334.3 160 320 145.7 320 128C320 110.3 334.3 96 352 96zM352 224L448 224C465.7 224 480 238.3 480 256C480 273.7 465.7 288 448 288L352 288C334.3 288 320 273.7 320 256C320 238.3 334.3 224 352 224zM352 352L512 352C529.7 352 544 366.3 544 384C544 401.7 529.7 416 512 416L352 416C334.3 416 320 401.7 320 384C320 366.3 334.3 352 352 352zM352 480L576 480C593.7 480 608 494.3 608 512C608 529.7 593.7 544 576 544L352 544C334.3 544 320 529.7 320 512C320 494.3 334.3 480 352 480z"/></svg>
+1
hugo/static/images/sort-desc.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M278.6 438.6L182.6 534.6C170.1 547.1 149.8 547.1 137.3 534.6L41.3 438.6C28.8 426.1 28.8 405.8 41.3 393.3C53.8 380.8 74.1 380.8 86.6 393.3L128 434.7L128 128C128 110.3 142.3 96 160 96C177.7 96 192 110.3 192 128L192 434.7L233.4 393.3C245.9 380.8 266.2 380.8 278.7 393.3C291.2 405.8 291.2 426.1 278.7 438.6zM352 544C334.3 544 320 529.7 320 512C320 494.3 334.3 480 352 480L384 480C401.7 480 416 494.3 416 512C416 529.7 401.7 544 384 544L352 544zM352 416C334.3 416 320 401.7 320 384C320 366.3 334.3 352 352 352L448 352C465.7 352 480 366.3 480 384C480 401.7 465.7 416 448 416L352 416zM352 288C334.3 288 320 273.7 320 256C320 238.3 334.3 224 352 224L512 224C529.7 224 544 238.3 544 256C544 273.7 529.7 288 512 288L352 288zM352 160C334.3 160 320 145.7 320 128C320 110.3 334.3 96 352 96L576 96C593.7 96 608 110.3 608 128C608 145.7 593.7 160 576 160L352 160z"/></svg>
hugo/static/images/tn.png

This is a binary file and will not be displayed.

+1
hugo/static/images/twitter.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M523.4 215.7C523.7 220.2 523.7 224.8 523.7 229.3C523.7 368 418.1 527.9 225.1 527.9C165.6 527.9 110.4 510.7 64 480.8C72.4 481.8 80.6 482.1 89.3 482.1C138.4 482.1 183.5 465.5 219.6 437.3C173.5 436.3 134.8 406.1 121.5 364.5C128 365.5 134.5 366.1 141.3 366.1C150.7 366.1 160.1 364.8 168.9 362.5C120.8 352.8 84.8 310.5 84.8 259.5L84.8 258.2C98.8 266 115 270.9 132.2 271.5C103.9 252.7 85.4 220.5 85.4 184.1C85.4 164.6 90.6 146.7 99.7 131.1C151.4 194.8 229 236.4 316.1 240.9C314.5 233.1 313.5 225 313.5 216.9C313.5 159.1 360.3 112 418.4 112C448.6 112 475.9 124.7 495.1 145.1C518.8 140.6 541.6 131.8 561.7 119.8C553.9 144.2 537.3 164.6 515.6 177.6C536.7 175.3 557.2 169.5 576 161.4C561.7 182.2 543.8 200.7 523.4 215.7z"/></svg>
+1
hugo/static/images/web.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M415.9 344L225 344C227.9 408.5 242.2 467.9 262.5 511.4C273.9 535.9 286.2 553.2 297.6 563.8C308.8 574.3 316.5 576 320.5 576C324.5 576 332.2 574.3 343.4 563.8C354.8 553.2 367.1 535.8 378.5 511.4C398.8 467.9 413.1 408.5 416 344zM224.9 296L415.8 296C413 231.5 398.7 172.1 378.4 128.6C367 104.2 354.7 86.8 343.3 76.2C332.1 65.7 324.4 64 320.4 64C316.4 64 308.7 65.7 297.5 76.2C286.1 86.8 273.8 104.2 262.4 128.6C242.1 172.1 227.8 231.5 224.9 296zM176.9 296C180.4 210.4 202.5 130.9 234.8 78.7C142.7 111.3 74.9 195.2 65.5 296L176.9 296zM65.5 344C74.9 444.8 142.7 528.7 234.8 561.3C202.5 509.1 180.4 429.6 176.9 344L65.5 344zM463.9 344C460.4 429.6 438.3 509.1 406 561.3C498.1 528.6 565.9 444.8 575.3 344L463.9 344zM575.3 296C565.9 195.2 498.1 111.3 406 78.7C438.3 130.9 460.4 210.4 463.9 296L575.3 296z"/></svg>
+1
hugo/static/images/windows.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M96 157.7L279.6 132.4L279.6 309.8L96 309.8L96 157.7zM96 482.3L279.6 507.6L279.6 332.4L96 332.4L96 482.3zM299.8 510.3L544 544L544 332.4L299.8 332.4L299.8 510.3zM299.8 129.7L299.8 309.8L544 309.8L544 96L299.8 129.7z"/></svg>
+1
hugo/static/images/xtwitter.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M453.2 112L523.8 112L369.6 288.2L551 528L409 528L297.7 382.6L170.5 528L99.8 528L264.7 339.5L90.8 112L236.4 112L336.9 244.9L453.2 112zM428.4 485.8L467.5 485.8L215.1 152L173.1 152L428.4 485.8z"/></svg>
+1
hugo/static/site.webmanifest
···
+
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
+1 -1
hugo/theme.toml
···
[taxonomies]
gametags = "gametags"
-
platforms = "platforms"
+
platforms = "platforms"
+11
jekyll/_sass/_partials/_global.scss
···
display: inline-block;
vertical-align: middle;
margin-right: 5px;
+
background-color: var(--foreground);
&.web {
mask: url(../images/web.svg);
···
&.sort-desc {
mask: url(../images/sort-desc.svg);
+
}
+
+
.active & {
+
background-color: var(--accent);
}
}
···
main {
padding: 20px;
text-align: center;
+
+
.submissions & {
+
display: grid;
+
grid-template-areas: "filters list";
+
grid-template-columns: 250px 1fr;
+
}
}
footer {
+1 -1
jekyll/_sass/_partials/_submissions.scss
···
display: grid;
grid-area: list;
grid-template-columns: repeat(4, 1fr);
-
grid-template-rows: auto;
+
grid-template-rows: fit-content(300px);
gap: 10px;
}
+10 -1
plain-html/css/style.css
···
display: inline-block;
vertical-align: middle;
margin-right: 5px;
+
background-color: var(--foreground);
}
.icon.web {
mask: url(../images/web.svg);
···
}
.icon.sort-desc {
mask: url(../images/sort-desc.svg);
+
}
+
.active .icon {
+
background-color: var(--accent);
}
.btn {
···
main {
padding: 20px;
text-align: center;
+
}
+
.submissions main {
+
display: grid;
+
grid-template-areas: "filters list";
+
grid-template-columns: 250px 1fr;
}
footer {
···
display: grid;
grid-area: list;
grid-template-columns: repeat(4, 1fr);
-
grid-template-rows: auto;
+
grid-template-rows: fit-content(300px);
gap: 10px;
}
+1 -1
plain-html/css/style.css.map
···
-
{"version":3,"sourceRoot":"","sources":["../../raw-scss/_partials/_fonts.scss","../../raw-scss/_partials/_variables.scss","../../raw-scss/_partials/_global.scss","../../raw-scss/_partials/_homepage.scss","../../raw-scss/_partials/_submissions.scss","../../raw-scss/_partials/_game_list_item.scss","../../raw-scss/_partials/_game.scss"],"names":[],"mappings":"AAAQ;AACR;AAAA;ACDA;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;ACXD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;AAEA;EACC;;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;;AAIF;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAGD;EACC;;AAGD;AAAA;EAEC;EACA;EACA;EACA;;AAEA;AAAA;EACC;EACA;;AAGD;AAAA;EACC;EACA;EACA;;AAIF;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAGC;EACC;EACA;EACA;EACA;;AAEA;EAEC;EACA;;;AAQN;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;;AAEA;EACC;;;AAIF;EACC;EACA;EACA;EACA;;;AAGD;EACC;;;ACnLD;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAIF;EACC;EACA;;AAEA;EACC;;AAGD;EACC;EACA;;AAMJ;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;;AAKH;EACC;;;ACjFD;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;;AAEA;EACC;;AAIF;EACC;;AAEA;EACC;EACA;EACA;;AAIF;AAAA;EAEC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;;AAGC;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;;AAMJ;EACC;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAIF;EACC;EACC;EACA;EACA;EACA;EACA;EACA;EACD;EACA;;AAGD;EACC;EACA;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;;;ACxGD;EACC;EACA;;AAEA;EACC;EACA;;AAEA;EACC;EACA;;AAEA;EACC;;AAKH;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAIF;EACC;EACA;;AAEA;EACC;EACA;;AAEA;EACC;;AAKH;EACC;EACA;EACA;;;AChDD;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAEA;EACC;EACA;EACA;EACA;;AAIF;EACC;;AAGD;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;;AAIF;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAIF;EACC;;AAKH;EACC;;AAGD;EACC;;AAEA;EACC;EACA;EACA;;AAEA;EACC;;AAIF;EACC;;AAGD;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;;AAIF;EACC","file":"style.css"}
+
{"version":3,"sourceRoot":"","sources":["../../_raw-assets/scss/_partials/_fonts.scss","../../_raw-assets/scss/_partials/_variables.scss","../../_raw-assets/scss/_partials/_global.scss","../../_raw-assets/scss/_partials/_homepage.scss","../../_raw-assets/scss/_partials/_submissions.scss","../../_raw-assets/scss/_partials/_game_list_item.scss","../../_raw-assets/scss/_partials/_game.scss"],"names":[],"mappings":"AAAQ;AACR;AAAA;ACDA;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;ACXD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;AAEA;EACC;;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;;AAIF;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAGD;EACC;;AAGD;AAAA;EAEC;EACA;EACA;EACA;;AAEA;AAAA;EACC;EACA;;AAGD;AAAA;EACC;EACA;EACA;;AAIF;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAGC;EACC;EACA;EACA;EACA;;AAEA;EAEC;EACA;;;AAQN;EACC;EACA;;AAEA;EACC;EACA;EACA;;;AAIF;EACC;EACA;EACA;EACA;;AAEA;EACC;;;AAIF;EACC;EACA;EACA;EACA;;;AAGD;EACC;;;AC9LD;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAIF;EACC;EACA;;AAEA;EACC;;AAGD;EACC;EACA;;AAMJ;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;;AAKH;EACC;;;ACjFD;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;;AAEA;EACC;;AAIF;EACC;;AAEA;EACC;EACA;EACA;;AAIF;AAAA;EAEC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;;AAGC;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;;AAMJ;EACC;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAIF;EACC;EACC;EACA;EACA;EACA;EACA;EACA;EACD;EACA;;AAGD;EACC;EACA;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;;;ACxGD;EACC;EACA;;AAEA;EACC;EACA;;AAEA;EACC;EACA;;AAEA;EACC;;AAKH;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAIF;EACC;EACA;;AAEA;EACC;EACA;;AAEA;EACC;;AAKH;EACC;EACA;EACA;;;AChDD;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAEA;EACC;EACA;EACA;EACA;;AAIF;EACC;;AAGD;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;;AAIF;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAIF;EACC;;AAKH;EACC;;AAGD;EACC;;AAEA;EACC;EACA;EACA;;AAEA;EACC;;AAIF;EACC;;AAGD;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;;AAIF;EACC","file":"style.css"}
+490
plain-php/css/style.css
···
+
@import url("https://fonts.googleapis.com/css2?family=Knewave&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap");
+
/* if you want to use different fonts, you can use other stuff from google fonts
+
if you don't want to use google, you may want to look into hosting your own fonts locally */
+
/* display variables! skip the images if you don't want them */
+
:root {
+
--background: #ECEBDE;
+
--foreground: #000000;
+
--accent: #A59D84;
+
--mainfont: "Work Sans", Helvetica, Arial, sans-serif;
+
--headingfont: "Knewave", "Arial Black", sans-serif;
+
--roundedCorners: 0px;
+
--pageBgImage: url();
+
--contentBgImage: url();
+
}
+
+
* {
+
box-sizing: border-box;
+
}
+
+
body {
+
background-color: var(--background);
+
background-image: url(--pageBgImage);
+
color: var(--foreground);
+
font-family: var(--mainfont);
+
font-size: 1em;
+
}
+
+
a {
+
color: var(--accent);
+
text-decoration: underline;
+
}
+
a:hover {
+
color: color-mix(in srgb-linear, var(--accent), #000000 50%);
+
}
+
+
.icon {
+
width: 16px;
+
height: 16px;
+
text-indent: -999px;
+
overflow: hidden;
+
display: inline-block;
+
vertical-align: middle;
+
margin-right: 5px;
+
background-color: var(--foreground);
+
}
+
.icon.web {
+
mask: url(../images/web.svg);
+
}
+
.icon.windows {
+
mask: url(../images/windows.svg);
+
}
+
.icon.macos {
+
mask: url(../images/macos.svg);
+
}
+
.icon.linux {
+
mask: url(../images/linux.svg);
+
}
+
.icon.android {
+
mask: url(../images/android.svg);
+
}
+
.icon.random {
+
mask: url(../images/random.svg);
+
}
+
.icon.sort-asc {
+
mask: url(../images/sort-asc.svg);
+
}
+
.icon.sort-desc {
+
mask: url(../images/sort-desc.svg);
+
}
+
.active .icon {
+
background-color: var(--accent);
+
}
+
+
.btn {
+
padding: 5px 10px;
+
font-size: 1em;
+
font-weight: bold;
+
border-radius: 5px;
+
background-color: var(--accent);
+
color: var(--background);
+
text-decoration: none;
+
white-space: pre;
+
}
+
.btn:hover {
+
background-color: color-mix(in srgb-linear, var(--accent), #000000 50%);
+
color: var(--background);
+
}
+
+
#page {
+
max-width: 960px;
+
margin: 50px auto;
+
background-color: color-mix(in srgb-linear, var(--background), #FFFFFF 50%);
+
background-image: var(--contentBgImage);
+
border-radius: var(--roundedCorners);
+
}
+
body.wide #page {
+
max-width: none;
+
margin: 0;
+
}
+
+
header {
+
padding: 20px 20px 0;
+
position: relative;
+
background-color: color-mix(in srgb-linear, var(--background), #FFFFFF 25%);
+
}
+
header h1 {
+
font-size: 2.5em;
+
font-weight: bold;
+
margin: 0;
+
}
+
header .hosted {
+
margin: 0;
+
}
+
header .joined,
+
header .entries {
+
text-align: center;
+
position: absolute;
+
top: 20px;
+
right: 20px;
+
}
+
header .joined .count,
+
header .entries .count {
+
font-size: 2.25em;
+
display: block;
+
}
+
header .joined .caption,
+
header .entries .caption {
+
font-size: 0.8em;
+
display: block;
+
color: color-mix(in srgb-linear, var(--foreground) #FFFFFF, 25%);
+
}
+
header nav {
+
margin-top: 20px;
+
padding-bottom: 10px;
+
}
+
header nav ul {
+
margin-bottom: 0;
+
display: flex;
+
gap: 10px;
+
list-style: none;
+
padding: 0;
+
}
+
header nav ul li a {
+
text-decoration: none;
+
padding: 5px 0;
+
border-bottom: 5px transparent solid;
+
color: var(--foreground);
+
}
+
header nav ul li a.current, header nav ul li a:hover {
+
border-bottom: 5px var(--accent) solid;
+
color: var(--foreground);
+
}
+
+
main {
+
padding: 20px;
+
text-align: center;
+
}
+
.submissions main {
+
display: grid;
+
grid-template-areas: "filters list";
+
grid-template-columns: 250px 1fr;
+
}
+
+
footer {
+
text-align: center;
+
font-size: 0.8em;
+
padding: 5px 10px;
+
margin-top: 20px;
+
}
+
footer a {
+
text-decoration: none;
+
}
+
+
[popover] {
+
position: fixed;
+
z-index: 99;
+
max-width: 90%;
+
max-height: 90%;
+
}
+
+
[popover]:-internal-popover-in-top-layer::backdrop {
+
background-color: rgba(0, 0, 0, 0.5);
+
}
+
+
.clock {
+
border: 1px var(--accent) solid;
+
border-radius: 5px;
+
display: inline-grid;
+
grid-template-areas: "date date" "countdown join";
+
margin: 50px auto;
+
}
+
.clock .dates {
+
border-bottom: 1px var(--accent) solid;
+
padding: 10px;
+
grid-area: date;
+
text-align: center;
+
}
+
.clock .countdown {
+
grid-area: countdown;
+
border-right: 1px var(--accent) solid;
+
padding: 20px;
+
text-align: right;
+
display: flex;
+
align-items: center;
+
justify-content: flex-end;
+
}
+
.clock .countdown .counters {
+
display: flex;
+
align-items: stretch;
+
}
+
.clock .countdown .counters > div {
+
padding: 10px;
+
border-right: 2px var(--accent) solid;
+
display: flex;
+
flex-direction: column;
+
justify-content: center;
+
align-items: center;
+
white-space: pre;
+
}
+
.clock .countdown .counters > div:last-child {
+
border-right: none;
+
}
+
.clock .countdown .counters span {
+
display: block;
+
text-align: center;
+
}
+
.clock .countdown .counters span.num {
+
font-weight: bold;
+
}
+
.clock .countdown .counters span.caption {
+
font-size: 0.8em;
+
font-style: italic;
+
}
+
.clock .join {
+
display: flex;
+
align-items: center;
+
justify-content: flex-start;
+
padding: 20px;
+
}
+
.clock .joinbtn {
+
padding: 10px 20px;
+
font-size: 1.25em;
+
font-weight: bold;
+
border-radius: 5px;
+
background-color: var(--accent);
+
color: var(--background);
+
text-decoration: none;
+
white-space: pre;
+
}
+
.clock .joinbtn:hover {
+
background-color: color-mix(in srgb-linear, var(--accent), #000000 50%);
+
}
+
+
.content {
+
text-align: left;
+
}
+
+
#filters {
+
grid-area: filters;
+
text-align: left;
+
}
+
#filters #tags {
+
display: flex;
+
flex-wrap: wrap;
+
gap: 5px;
+
justify-content: flex-start;
+
}
+
#filters #tags button {
+
white-space: pre;
+
}
+
#filters details {
+
margin-bottom: 10px;
+
}
+
#filters details ul {
+
list-style: none;
+
margin: 0;
+
padding: 0;
+
}
+
#filters p.label,
+
#filters details summary {
+
font-size: 0.8em;
+
color: color-mix(in srgb-linear, var(--foreground), var(--background) 10%);
+
padding: 5px 0;
+
margin-bottom: 0;
+
}
+
#filters ul#sorts {
+
list-style: none;
+
margin: 0 0 10px;
+
padding: 0;
+
}
+
#filters ul#sorts li button {
+
appearance: none;
+
border: none;
+
background-color: transparent;
+
color: var(--foreground);
+
border-radius: 0;
+
font-family: inherit;
+
font-size: inherit;
+
font-size: 0.9em;
+
}
+
#filters ul#sorts li button img {
+
width: 16px;
+
height: 16px;
+
margin-right: 5px;
+
display: inline-block;
+
vertical-align: middle;
+
}
+
#filters ul#sorts li button.sort-active {
+
color: color-mix(in srgb-linear, var(--accent), #000000 10%);
+
font-weight: bold;
+
}
+
#filters .afs-btn-filter {
+
appearance: none;
+
padding: 3px 0;
+
border: none;
+
border-radius: 0;
+
font-family: inherit;
+
background-color: transparent;
+
}
+
#filters .afs-btn-filter.active {
+
color: color-mix(in srgb-linear, var(--accent), #000000 10%);
+
background-color: transparent;
+
font-weight: bold;
+
}
+
#filters .afs-filter-search {
+
width: 100%;
+
padding: 0.5rem;
+
border: 1px solid var(--accent);
+
border-radius: 0.25rem;
+
font-size: 0.875rem;
+
color: var(--foreground);
+
transition: border-color 0.2s ease;
+
margin-bottom: 10px;
+
font-family: inherit;
+
}
+
#filters .afs-filter-counter {
+
text-align: center;
+
font-style: italic;
+
font-size: 0.9em;
+
}
+
+
#list {
+
display: grid;
+
grid-area: list;
+
grid-template-columns: repeat(4, 1fr);
+
grid-template-rows: fit-content(300px);
+
gap: 10px;
+
}
+
+
.item {
+
text-align: left;
+
border: 1px red solid;
+
}
+
.item h3 {
+
margin: 0;
+
font-size: 1.25em;
+
}
+
.item h3 a {
+
color: var(--foreground);
+
text-decoration: none;
+
}
+
.item h3 a:hover {
+
text-decoration: underline;
+
}
+
.item .thumb {
+
position: relative;
+
padding-top: 75%;
+
}
+
.item .thumb img {
+
position: absolute;
+
top: 0;
+
left: 0;
+
width: 100%;
+
height: 100%;
+
object-fit: cover;
+
}
+
.item .authors {
+
font-size: 0.9em;
+
margin: 5px 0;
+
}
+
.item .authors a {
+
color: color-mix(in srgb-linear, var(--foreground), #FFFFFF 10%);
+
text-decoration: none;
+
}
+
.item .authors a:hover {
+
text-decoration: underline;
+
}
+
.item .blurb {
+
margin-top: 5px;
+
font-size: 0.8em;
+
color: color-mix(in srgb-linear, var(--foreground), #FFFFFF 10%);
+
}
+
+
.game main {
+
display: grid;
+
grid-template-areas: "header header" "screenshots stuff";
+
text-align: left;
+
border-bottom: 1px var(--accent) solid;
+
padding-bottom: 0;
+
}
+
.game main h2 {
+
margin: 0;
+
}
+
.game main h2 a {
+
font-size: 0.9rem;
+
margin-left: 10px;
+
display: inline-block;
+
vertical-align: middle;
+
}
+
.game main h3 {
+
margin: 0;
+
}
+
.game main .blurb {
+
margin: 1em 0;
+
}
+
.game main .game-header {
+
margin: -20px -20px 0;
+
width: calc(100% + 40px);
+
border-bottom: 1px var(--accent) solid;
+
padding: 20px;
+
text-align: left;
+
grid-area: header;
+
}
+
.game main .jamsub {
+
font-size: 0.8em;
+
font-style: italic;
+
color: color-mix(in srgb-linear, var(--foreground), var(--background) 15%);
+
margin: 0;
+
}
+
.game .screenshots {
+
border-right: 1px var(--accent) solid;
+
grid-area: screenshots;
+
padding: 20px;
+
}
+
.game .screenshots .gallery {
+
display: grid;
+
gap: 10px;
+
grid-template-columns: repeat(2, 1fr);
+
grid-template-rows: auto;
+
grid-template-areas: "featured featured";
+
}
+
.game .screenshots .gallery a, .game .screenshots .gallery button {
+
position: relative;
+
padding-top: 75%;
+
width: 100%;
+
}
+
.game .screenshots .gallery a img, .game .screenshots .gallery button img {
+
position: absolute;
+
top: 0;
+
left: 0;
+
width: 100%;
+
height: 100%;
+
object-fit: cover;
+
}
+
.game .screenshots .gallery > :first-child {
+
grid-area: featured;
+
}
+
.game .interaction {
+
grid-area: stuff;
+
}
+
.game .downloads {
+
padding: 20px;
+
}
+
.game .downloads ul {
+
list-style: none;
+
margin: 1em 0;
+
padding: 0;
+
}
+
.game .downloads ul li {
+
margin-bottom: 10px;
+
}
+
.game .downloads .size {
+
color: color-mix(in srgb-linear, var(--foreground), var(--background) 20%);
+
}
+
.game .downloads .platforms-label {
+
display: inline-block;
+
width: 1px;
+
overflow: hidden;
+
text-indent: -999px;
+
}
+
.game .downloads .icon {
+
width: 24px;
+
height: 24px;
+
background-color: color-mix(in srgb-linear, var(--foreground), var(--background) 20%);
+
}
+
.game .comments {
+
border-top: 1px var(--accent) solid;
+
}
+
+
/*# sourceMappingURL=style.css.map */
+1
plain-php/css/style.css.map
···
+
{"version":3,"sourceRoot":"","sources":["../../_raw-assets/scss/_partials/_fonts.scss","../../_raw-assets/scss/_partials/_variables.scss","../../_raw-assets/scss/_partials/_global.scss","../../_raw-assets/scss/_partials/_homepage.scss","../../_raw-assets/scss/_partials/_submissions.scss","../../_raw-assets/scss/_partials/_game_list_item.scss","../../_raw-assets/scss/_partials/_game.scss"],"names":[],"mappings":"AAAQ;AACR;AAAA;ACDA;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;ACXD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;AAEA;EACC;;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;;AAIF;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAGD;EACC;;AAGD;AAAA;EAEC;EACA;EACA;EACA;;AAEA;AAAA;EACC;EACA;;AAGD;AAAA;EACC;EACA;EACA;;AAIF;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAGC;EACC;EACA;EACA;EACA;;AAEA;EAEC;EACA;;;AAQN;EACC;EACA;;AAEA;EACC;EACA;EACA;;;AAIF;EACC;EACA;EACA;EACA;;AAEA;EACC;;;AAIF;EACC;EACA;EACA;EACA;;;AAGD;EACC;;;AC9LD;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAIF;EACC;EACA;;AAEA;EACC;;AAGD;EACC;EACA;;AAMJ;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;;AAKH;EACC;;;ACjFD;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;;AAEA;EACC;;AAIF;EACC;;AAEA;EACC;EACA;EACA;;AAIF;AAAA;EAEC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;;AAGC;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;;AAMJ;EACC;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAIF;EACC;EACC;EACA;EACA;EACA;EACA;EACA;EACD;EACA;;AAGD;EACC;EACA;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;;;ACxGD;EACC;EACA;;AAEA;EACC;EACA;;AAEA;EACC;EACA;;AAEA;EACC;;AAKH;EACC;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAIF;EACC;EACA;;AAEA;EACC;EACA;;AAEA;EACC;;AAKH;EACC;EACA;EACA;;;AChDD;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAEA;EACC;EACA;EACA;EACA;;AAIF;EACC;;AAGD;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;;AAIF;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAIF;EACC;;AAKH;EACC;;AAGD;EACC;;AAEA;EACC;EACA;EACA;;AAEA;EACC;;AAIF;EACC;;AAGD;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;;AAIF;EACC","file":"style.css"}
plain-php/images/android-chrome-192x192.png

This is a binary file and will not be displayed.

plain-php/images/android-chrome-512x512.png

This is a binary file and will not be displayed.

+1
plain-php/images/android.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M452.5 317.9C465.8 317.9 476.5 328.6 476.5 341.9C476.5 355.2 465.8 365.9 452.5 365.9C439.2 365.9 428.5 355.2 428.5 341.9C428.5 328.6 439.2 317.9 452.5 317.9zM187.4 317.9C200.7 317.9 211.4 328.6 211.4 341.9C211.4 355.2 200.7 365.9 187.4 365.9C174.1 365.9 163.4 355.2 163.4 341.9C163.4 328.6 174.1 317.9 187.4 317.9zM461.1 221.4L509 138.4C509.8 137.3 510.3 136 510.5 134.6C510.7 133.2 510.7 131.9 510.4 130.5C510.1 129.1 509.5 127.9 508.7 126.8C507.9 125.7 506.9 124.8 505.7 124.1C504.5 123.4 503.2 123 501.8 122.8C500.4 122.6 499.1 122.8 497.8 123.2C496.5 123.6 495.3 124.3 494.2 125.1C493.1 125.9 492.3 127.1 491.7 128.3L443.2 212.4C404.4 195 362.4 186 319.9 186C277.4 186 235.4 195 196.6 212.4L148.2 128.4C147.6 127.2 146.7 126.1 145.7 125.2C144.7 124.3 143.4 123.7 142.1 123.3C140.8 122.9 139.4 122.8 138.1 122.9C136.8 123 135.4 123.5 134.2 124.2C133 124.9 132 125.8 131.2 126.9C130.4 128 129.8 129.3 129.5 130.6C129.2 131.9 129.2 133.3 129.4 134.7C129.6 136.1 130.2 137.3 130.9 138.5L178.8 221.5C96.5 266.2 40.2 349.5 32 448L608 448C599.8 349.5 543.5 266.2 461.1 221.4z"/></svg>
plain-php/images/apple-touch-icon.png

This is a binary file and will not be displayed.

+1
plain-php/images/bluesky.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M439.8 358.7C436.5 358.3 433.1 357.9 429.8 357.4C433.2 357.8 436.5 358.3 439.8 358.7zM320 291.1C293.9 240.4 222.9 145.9 156.9 99.3C93.6 54.6 69.5 62.3 53.6 69.5C35.3 77.8 32 105.9 32 122.4C32 138.9 41.1 258 47 277.9C66.5 343.6 136.1 365.8 200.2 358.6C203.5 358.1 206.8 357.7 210.2 357.2C206.9 357.7 203.6 358.2 200.2 358.6C106.3 372.6 22.9 406.8 132.3 528.5C252.6 653.1 297.1 501.8 320 425.1C342.9 501.8 369.2 647.6 505.6 528.5C608 425.1 533.7 372.5 439.8 358.6C436.5 358.2 433.1 357.8 429.8 357.3C433.2 357.7 436.5 358.2 439.8 358.6C503.9 365.7 573.4 343.5 593 277.9C598.9 258 608 139 608 122.4C608 105.8 604.7 77.7 586.4 69.5C570.6 62.4 546.4 54.6 483.2 99.3C417.1 145.9 346.1 240.4 320 291.1z"/></svg>
+1
plain-php/images/facebook.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 440 146.7 540.8 258.2 568.5L258.2 398.2L205.4 398.2L205.4 320L258.2 320L258.2 286.3C258.2 199.2 297.6 158.8 383.2 158.8C399.4 158.8 427.4 162 438.9 165.2L438.9 236C432.9 235.4 422.4 235 409.3 235C367.3 235 351.1 250.9 351.1 292.2L351.1 320L434.7 320L420.3 398.2L351 398.2L351 574.1C477.8 558.8 576 450.9 576 320z"/></svg>
plain-php/images/favicon-16x16.png

This is a binary file and will not be displayed.

plain-php/images/favicon-32x32.png

This is a binary file and will not be displayed.

plain-php/images/favicon.ico

This is a binary file and will not be displayed.

+1
plain-php/images/linux.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M316.9 187.3C317.9 187.8 318.7 189 319.9 189C321 189 322.7 188.6 322.8 187.5C323 186.1 320.9 185.2 319.6 184.6C317.9 183.9 315.7 183.6 314.1 184.5C313.7 184.7 313.3 185.2 313.5 185.6C313.8 186.9 315.8 186.7 316.9 187.3zM295 189C296.2 189 297 187.8 298 187.3C299.1 186.7 301.1 186.9 301.5 185.7C301.7 185.3 301.3 184.8 300.9 184.6C299.3 183.7 297.1 184 295.4 184.7C294.1 185.3 292 186.2 292.2 187.6C292.3 188.6 294 189.1 295 189zM516 467.8C512.4 463.8 510.7 456.2 508.8 448.1C507 440 504.9 431.3 498.3 425.7C497 424.6 495.7 423.6 494.3 422.8C493 422 491.6 421.3 490.2 420.8C499.4 393.5 495.8 366.3 486.5 341.7C475.1 311.6 455.2 285.3 440 267.3C422.9 245.8 406.3 225.4 406.6 195.3C407.1 149.4 411.7 64.1 330.8 64C228.4 63.8 254 167.4 252.9 199.2C251.2 222.6 246.5 241 230.4 263.9C211.5 286.4 184.9 322.7 172.3 360.6C166.3 378.5 163.5 396.7 166.1 413.9C159.6 419.7 154.7 428.6 149.5 434.1C145.3 438.4 139.2 440 132.5 442.4C125.8 444.8 118.5 448.4 114 456.9C111.9 460.8 111.2 465 111.2 469.3C111.2 473.2 111.8 477.2 112.4 481.1C113.6 489.2 114.9 496.8 113.2 501.9C108 516.3 107.3 526.3 111 533.6C114.8 540.9 122.4 544.1 131.1 545.9C148.4 549.5 171.9 548.6 190.4 558.4C210.2 568.8 230.3 572.5 246.3 568.8C257.9 566.2 267.4 559.2 272.2 548.6C284.7 548.5 298.5 543.2 320.5 542C335.4 540.8 354.1 547.3 375.6 546.1C376.2 548.4 377 550.7 378.1 552.8L378.1 552.9C386.4 569.6 401.9 577.2 418.4 575.9C435 574.6 452.5 564.9 466.7 548C480.3 531.6 502.7 524.8 517.6 515.8C525 511.3 531 505.7 531.5 497.5C531.9 489.3 527.1 480.2 516 467.8zM319.8 151.3C329.6 129.1 354 129.5 363.8 150.9C370.3 165.1 367.4 181.8 359.5 191.3C357.9 190.5 353.6 188.7 346.9 186.4C348 185.2 350 183.7 350.8 181.8C355.6 170 350.6 154.8 341.7 154.5C334.4 154 327.8 165.3 329.9 177.5C325.8 175.5 320.5 174 316.9 173.1C315.9 166.2 316.6 158.5 319.8 151.3zM279.1 139.8C289.2 139.8 299.9 154 298.2 173.3C294.7 174.3 291.1 175.8 288 177.9C289.2 169 284.7 157.8 278.4 158.3C270 159 268.6 179.5 276.6 186.4C277.6 187.2 278.5 186.2 270.7 191.9C255.1 177.3 260.2 139.8 279.1 139.8zM265.5 200.5C271.7 195.9 279.1 190.5 279.6 190C284.3 185.6 293.1 175.8 307.5 175.8C314.6 175.8 323.1 178.1 333.4 184.7C339.7 188.8 344.7 189.1 356 194C364.4 197.5 369.7 203.7 366.5 212.2C363.9 219.3 355.5 226.6 343.8 230.3C332.7 233.9 324 246.3 305.6 245.2C301.7 245 298.6 244.2 296 243.1C288 239.6 283.8 232.7 276 228.1C267.4 223.3 262.8 217.7 261.3 212.8C259.9 207.9 261.3 203.8 265.5 200.5zM268.8 534.5C266.1 569.6 224.9 568.9 193.5 552.5C163.6 536.7 124.9 546 117 530.6C114.6 525.9 114.6 517.9 119.6 504.2L119.6 504C122 496.4 120.2 488 119 480.1C117.8 472.3 117.2 465.1 119.9 460.1C123.4 453.4 128.4 451 134.7 448.8C145 445.1 146.5 445.4 154.3 438.9C159.8 433.2 163.8 426 168.6 420.9C173.7 415.4 178.6 412.8 186.3 414C194.4 415.2 201.4 420.8 208.2 430L227.8 465.6C237.3 485.5 270.9 514 268.8 534.5zM267.4 508.6C263.3 502 257.8 495 253 489C260.1 489 267.2 486.8 269.7 480.1C272 473.9 269.7 465.2 262.3 455.2C248.8 437 224 422.7 224 422.7C210.5 414.3 202.9 404 199.4 392.8C195.9 381.6 196.4 369.5 199.1 357.6C204.3 334.7 217.7 312.4 226.3 298.4C228.6 296.7 227.1 301.6 217.6 319.2C209.1 335.3 193.2 372.5 215 401.6C215.6 380.9 220.5 359.8 228.8 340.1C240.8 312.7 266.1 265.2 268.1 227.4C269.2 228.2 272.7 230.6 274.3 231.5C278.9 234.2 282.4 238.2 286.9 241.8C299.3 251.8 315.4 251 329.3 243C335.5 239.5 340.5 235.5 345.2 234C355.1 230.9 363 225.4 367.5 219C375.2 249.4 393.2 293.3 404.7 314.7C410.8 326.1 423 350.2 428.3 379.3C431.6 379.2 435.3 379.7 439.2 380.7C453 345 427.5 306.5 415.9 295.8C411.2 291.2 411 289.2 413.3 289.3C425.9 300.5 442.5 323 448.5 348.3C451.3 359.9 451.8 372 448.9 384C465.3 390.8 484.8 401.9 479.6 418.8C477.4 418.7 476.4 418.8 475.4 418.8C478.6 408.7 471.5 401.2 452.6 392.7C433 384.1 416.6 384.1 414.3 405.2C402.2 409.4 396 419.9 392.9 432.5C390.1 443.7 389.3 457.2 388.5 472.4C388 480.1 384.9 490.4 381.7 501.4C349.6 524.3 305 534.3 267.4 508.6zM524.8 497.1C523.9 513.9 483.6 517 461.6 543.6C448.4 559.3 432.2 568 418 569.1C403.8 570.2 391.5 564.3 384.3 549.8C379.6 538.7 381.9 526.7 385.4 513.5C389.1 499.3 394.6 484.7 395.3 472.9C396.1 457.7 397 444.4 399.5 434.2C402.1 423.9 406.1 417 413.2 413.1C413.5 412.9 413.9 412.8 414.2 412.6C415 425.8 421.5 439.2 433 442.1C445.6 445.4 463.7 434.6 471.4 425.8C480.4 425.5 487.1 424.9 494 430.9C503.9 439.4 501.1 461.2 511.1 472.5C521.7 484.1 525.1 492 524.8 497.1zM269.4 212.7C271.4 214.6 274.1 217.2 277.4 219.8C284 225 293.2 230.4 304.7 230.4C316.3 230.4 327.2 224.5 336.5 219.6C341.4 217 347.4 212.6 351.3 209.2C355.2 205.8 357.2 202.9 354.4 202.6C351.6 202.3 351.8 205.2 348.4 207.7C344 210.9 338.7 215.1 334.5 217.5C327.1 221.7 315 227.7 304.6 227.7C294.2 227.7 285.9 222.9 279.7 218C276.6 215.5 274 213 272 211.1C270.5 209.7 270.1 206.5 267.7 206.2C266.3 206.1 265.9 209.9 269.4 212.7z"/></svg>
+1
plain-php/images/macos.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M320 176C311.2 176 304 168.8 304 160L304 144C304 99.8 339.8 64 384 64L400 64C408.8 64 416 71.2 416 80L416 96C416 140.2 380.2 176 336 176L320 176zM96 352C96 275.7 131.7 192 208 192C235.3 192 267.7 202.3 290.7 211.3C309.5 218.6 330.6 218.6 349.4 211.3C372.3 202.4 404.8 192 432.1 192C508.4 192 544.1 275.7 544.1 352C544.1 480 464.1 576 384.1 576C367.6 576 346 569.4 332.6 564.7C324.5 561.9 315.7 561.9 307.6 564.7C294.2 569.4 272.6 576 256.1 576C176.1 576 96.1 480 96.1 352z"/></svg>
+1
plain-php/images/mastodon.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M529 243.1C529 145.9 465.3 117.4 465.3 117.4C402.8 88.7 236.7 89 174.8 117.4C174.8 117.4 111.1 145.9 111.1 243.1C111.1 358.8 104.5 502.5 216.7 532.2C257.2 542.9 292 545.2 320 543.6C370.8 540.8 399.3 525.5 399.3 525.5L397.6 488.6C397.6 488.6 361.3 500 320.5 498.7C280.1 497.3 237.5 494.3 230.9 444.7C230.3 440.1 230 435.4 230 430.8C315.6 451.7 388.7 439.9 408.7 437.5C464.8 430.8 513.7 396.2 519.9 364.6C529.7 314.8 528.9 243.1 528.9 243.1zM453.9 368.3L407.3 368.3L407.3 254.1C407.3 204.4 343.3 202.5 343.3 261L343.3 323.5L297 323.5L297 261C297 202.5 233 204.4 233 254.1L233 368.3L186.3 368.3C186.3 246.2 181.1 220.4 204.7 193.3C230.6 164.4 284.5 162.5 308.5 199.4L320.1 218.9L331.7 199.4C355.8 162.3 409.8 164.6 435.5 193.3C459.2 220.6 453.9 246.3 453.9 368.3L453.9 368.3z"/></svg>
+1
plain-php/images/random.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M467.8 98.4C479.8 93.4 493.5 96.2 502.7 105.3L566.7 169.3C572.7 175.3 576.1 183.4 576.1 191.9C576.1 200.4 572.7 208.5 566.7 214.5L502.7 278.5C493.5 287.7 479.8 290.4 467.8 285.4C455.8 280.4 448 268.9 448 256L448 224L416 224C405.9 224 396.4 228.7 390.4 236.8L358 280L318 226.7L339.2 198.4C357.3 174.2 385.8 160 416 160L448 160L448 128C448 115.1 455.8 103.4 467.8 98.4zM218 360L258 413.3L236.8 441.6C218.7 465.8 190.2 480 160 480L96 480C78.3 480 64 465.7 64 448C64 430.3 78.3 416 96 416L160 416C170.1 416 179.6 411.3 185.6 403.2L218 360zM502.6 534.6C493.4 543.8 479.7 546.5 467.7 541.5C455.7 536.5 448 524.9 448 512L448 480L416 480C385.8 480 357.3 465.8 339.2 441.6L185.6 236.8C179.6 228.7 170.1 224 160 224L96 224C78.3 224 64 209.7 64 192C64 174.3 78.3 160 96 160L160 160C190.2 160 218.7 174.2 236.8 198.4L390.4 403.2C396.4 411.3 405.9 416 416 416L448 416L448 384C448 371.1 455.8 359.4 467.8 354.4C479.8 349.4 493.5 352.2 502.7 361.3L566.7 425.3C572.7 431.3 576.1 439.4 576.1 447.9C576.1 456.4 572.7 464.5 566.7 470.5L502.7 534.5z"/></svg>
+1
plain-php/images/sort-asc.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M278.6 438.6L182.6 534.6C170.1 547.1 149.8 547.1 137.3 534.6L41.3 438.6C28.8 426.1 28.8 405.8 41.3 393.3C53.8 380.8 74.1 380.8 86.6 393.3L128 434.7L128 128C128 110.3 142.3 96 160 96C177.7 96 192 110.3 192 128L192 434.7L233.4 393.3C245.9 380.8 266.2 380.8 278.7 393.3C291.2 405.8 291.2 426.1 278.7 438.6zM352 96L384 96C401.7 96 416 110.3 416 128C416 145.7 401.7 160 384 160L352 160C334.3 160 320 145.7 320 128C320 110.3 334.3 96 352 96zM352 224L448 224C465.7 224 480 238.3 480 256C480 273.7 465.7 288 448 288L352 288C334.3 288 320 273.7 320 256C320 238.3 334.3 224 352 224zM352 352L512 352C529.7 352 544 366.3 544 384C544 401.7 529.7 416 512 416L352 416C334.3 416 320 401.7 320 384C320 366.3 334.3 352 352 352zM352 480L576 480C593.7 480 608 494.3 608 512C608 529.7 593.7 544 576 544L352 544C334.3 544 320 529.7 320 512C320 494.3 334.3 480 352 480z"/></svg>
+1
plain-php/images/sort-desc.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M278.6 438.6L182.6 534.6C170.1 547.1 149.8 547.1 137.3 534.6L41.3 438.6C28.8 426.1 28.8 405.8 41.3 393.3C53.8 380.8 74.1 380.8 86.6 393.3L128 434.7L128 128C128 110.3 142.3 96 160 96C177.7 96 192 110.3 192 128L192 434.7L233.4 393.3C245.9 380.8 266.2 380.8 278.7 393.3C291.2 405.8 291.2 426.1 278.7 438.6zM352 544C334.3 544 320 529.7 320 512C320 494.3 334.3 480 352 480L384 480C401.7 480 416 494.3 416 512C416 529.7 401.7 544 384 544L352 544zM352 416C334.3 416 320 401.7 320 384C320 366.3 334.3 352 352 352L448 352C465.7 352 480 366.3 480 384C480 401.7 465.7 416 448 416L352 416zM352 288C334.3 288 320 273.7 320 256C320 238.3 334.3 224 352 224L512 224C529.7 224 544 238.3 544 256C544 273.7 529.7 288 512 288L352 288zM352 160C334.3 160 320 145.7 320 128C320 110.3 334.3 96 352 96L576 96C593.7 96 608 110.3 608 128C608 145.7 593.7 160 576 160L352 160z"/></svg>
+1
plain-php/images/twitter.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M523.4 215.7C523.7 220.2 523.7 224.8 523.7 229.3C523.7 368 418.1 527.9 225.1 527.9C165.6 527.9 110.4 510.7 64 480.8C72.4 481.8 80.6 482.1 89.3 482.1C138.4 482.1 183.5 465.5 219.6 437.3C173.5 436.3 134.8 406.1 121.5 364.5C128 365.5 134.5 366.1 141.3 366.1C150.7 366.1 160.1 364.8 168.9 362.5C120.8 352.8 84.8 310.5 84.8 259.5L84.8 258.2C98.8 266 115 270.9 132.2 271.5C103.9 252.7 85.4 220.5 85.4 184.1C85.4 164.6 90.6 146.7 99.7 131.1C151.4 194.8 229 236.4 316.1 240.9C314.5 233.1 313.5 225 313.5 216.9C313.5 159.1 360.3 112 418.4 112C448.6 112 475.9 124.7 495.1 145.1C518.8 140.6 541.6 131.8 561.7 119.8C553.9 144.2 537.3 164.6 515.6 177.6C536.7 175.3 557.2 169.5 576 161.4C561.7 182.2 543.8 200.7 523.4 215.7z"/></svg>
+1
plain-php/images/web.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M415.9 344L225 344C227.9 408.5 242.2 467.9 262.5 511.4C273.9 535.9 286.2 553.2 297.6 563.8C308.8 574.3 316.5 576 320.5 576C324.5 576 332.2 574.3 343.4 563.8C354.8 553.2 367.1 535.8 378.5 511.4C398.8 467.9 413.1 408.5 416 344zM224.9 296L415.8 296C413 231.5 398.7 172.1 378.4 128.6C367 104.2 354.7 86.8 343.3 76.2C332.1 65.7 324.4 64 320.4 64C316.4 64 308.7 65.7 297.5 76.2C286.1 86.8 273.8 104.2 262.4 128.6C242.1 172.1 227.8 231.5 224.9 296zM176.9 296C180.4 210.4 202.5 130.9 234.8 78.7C142.7 111.3 74.9 195.2 65.5 296L176.9 296zM65.5 344C74.9 444.8 142.7 528.7 234.8 561.3C202.5 509.1 180.4 429.6 176.9 344L65.5 344zM463.9 344C460.4 429.6 438.3 509.1 406 561.3C498.1 528.6 565.9 444.8 575.3 344L463.9 344zM575.3 296C565.9 195.2 498.1 111.3 406 78.7C438.3 130.9 460.4 210.4 463.9 296L575.3 296z"/></svg>
+1
plain-php/images/windows.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M96 157.7L279.6 132.4L279.6 309.8L96 309.8L96 157.7zM96 482.3L279.6 507.6L279.6 332.4L96 332.4L96 482.3zM299.8 510.3L544 544L544 332.4L299.8 332.4L299.8 510.3zM299.8 129.7L299.8 309.8L544 309.8L544 96L299.8 129.7z"/></svg>
+1
plain-php/images/xtwitter.svg
···
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M453.2 112L523.8 112L369.6 288.2L551 528L409 528L297.7 382.6L170.5 528L99.8 528L264.7 339.5L90.8 112L236.4 112L336.9 244.9L453.2 112zM428.4 485.8L467.5 485.8L215.1 152L173.1 152L428.4 485.8z"/></svg>
+11
wordpress/resources/css/_partials/_global.scss
···
display: inline-block;
vertical-align: middle;
margin-right: 5px;
+
background-color: var(--foreground);
&.web {
mask: url(../images/web.svg);
···
&.sort-desc {
mask: url(../images/sort-desc.svg);
+
}
+
+
.active & {
+
background-color: var(--accent);
}
}
···
main {
padding: 20px;
text-align: center;
+
+
.submissions & {
+
display: grid;
+
grid-template-areas: "filters list";
+
grid-template-columns: 250px 1fr;
+
}
}
footer {
+1 -1
wordpress/resources/css/_partials/_submissions.scss
···
display: grid;
grid-area: list;
grid-template-columns: repeat(4, 1fr);
-
grid-template-rows: auto;
+
grid-template-rows: fit-content(300px);
gap: 10px;
}
+11
zola/sass/_partials/_global.scss
···
display: inline-block;
vertical-align: middle;
margin-right: 5px;
+
background-color: var(--foreground);
&.web {
mask: url(../images/web.svg);
···
&.sort-desc {
mask: url(../images/sort-desc.svg);
+
}
+
+
.active & {
+
background-color: var(--accent);
}
}
···
main {
padding: 20px;
text-align: center;
+
+
.submissions & {
+
display: grid;
+
grid-template-areas: "filters list";
+
grid-template-columns: 250px 1fr;
+
}
}
footer {
+1 -1
zola/sass/_partials/_submissions.scss
···
display: grid;
grid-area: list;
grid-template-columns: repeat(4, 1fr);
-
grid-template-rows: auto;
+
grid-template-rows: fit-content(300px);
gap: 10px;
}