<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://unfinishedprojects.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Anthony</id>
	<title>UnfinishedProjects - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://unfinishedprojects.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Anthony"/>
	<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/wiki/Special:Contributions/Anthony"/>
	<updated>2026-04-05T22:17:36Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1243</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1243"/>
		<updated>2026-04-05T10:12:11Z</updated>

		<summary type="html">&lt;p&gt;Anthony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   MediaWiki:Common.css&lt;br /&gt;
   UnfinishedProjects Wiki&lt;br /&gt;
   &lt;br /&gt;
   TABLE OF CONTENTS&lt;br /&gt;
   0.  Nav Forum Link&lt;br /&gt;
   1.  Brand Variables&lt;br /&gt;
   2.  Callout Boxes&lt;br /&gt;
   3.  Badges&lt;br /&gt;
   4.  Table Utilities&lt;br /&gt;
   5.  Text Utilities&lt;br /&gt;
   6.  Category Pages&lt;br /&gt;
   7.  Tag-Based Hub&lt;br /&gt;
   8.  Hub Main Page Buttons&lt;br /&gt;
   9.  License Cloud&lt;br /&gt;
   10. Tag Tokenizer&lt;br /&gt;
   11. Page Forms&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   0. Forum Link&lt;br /&gt;
   Forum header link — Gadget-sitenav.js&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link {&lt;br /&gt;
    background: var(--wiki-primary-subtle) !important;&lt;br /&gt;
    border: 1px solid var(--wiki-primary) !important;&lt;br /&gt;
    border-radius: 20px !important;&lt;br /&gt;
    color: var(--wiki-primary) !important;&lt;br /&gt;
    transition: background 0.15s, color 0.15s !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover {&lt;br /&gt;
    background: var(--wiki-primary) !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover .citizen-ui-icon {&lt;br /&gt;
    filter: brightness(0) invert(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   1. BRAND VARIABLES&lt;br /&gt;
   Edit only these lines to retheme the entire wiki.&lt;br /&gt;
   subtle  = primary at ~12% opacity (tag backgrounds, tints)&lt;br /&gt;
   overlay = primary at ~92% opacity (card hover overlays)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
    --wiki-primary:           #e46419;&lt;br /&gt;
    --wiki-primary-subtle:    rgba(228, 100, 25, 0.12);&lt;br /&gt;
    --wiki-primary-overlay:   rgba(228, 100, 25, 0.92);&lt;br /&gt;
    --wiki-secondary:         #3465a4;&lt;br /&gt;
    --wiki-secondary-subtle:  rgba(52, 101, 164, 0.12);&lt;br /&gt;
    --wiki-secondary-overlay: rgba(52, 101, 164, 0.92);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   2. CALLOUT BOXES&lt;br /&gt;
   Light mode uses tinted backgrounds.&lt;br /&gt;
   Dark mode desaturates them so they don&#039;t glow on dark surfaces.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.box-info,&lt;br /&gt;
.box-warning,&lt;br /&gt;
.box-danger,&lt;br /&gt;
.box-success {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box-info    { background: #e8f4fd; border-left: 4px solid #2196F3; }&lt;br /&gt;
.box-warning { background: #fff3cd; border-left: 4px solid #ffc107; }&lt;br /&gt;
.box-danger  { background: #f8d7da; border-left: 4px solid #dc3545; }&lt;br /&gt;
.box-success { background: #d4edda; border-left: 4px solid #28a745; }&lt;br /&gt;
&lt;br /&gt;
.box-neutral {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   3. BADGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.badge {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 2px 9px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 85%;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.badge-green  { background: #28a745; color: #fff; }&lt;br /&gt;
.badge-red    { background: #dc3545; color: #fff; }&lt;br /&gt;
.badge-yellow { background: #ffc107; color: #212529; }&lt;br /&gt;
.badge-blue   { background: #17a2b8; color: #fff; }&lt;br /&gt;
.badge-grey   { background: #6c757d; color: #fff; }&lt;br /&gt;
.badge-dark   { background: #3d3d3d; color: #fff; }&lt;br /&gt;
&lt;br /&gt;
/* Project badges */&lt;br /&gt;
.project-badge-status {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.03em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--active {&lt;br /&gt;
	background-color: rgba(40,167,69,0.15);&lt;br /&gt;
	color: #28a745;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--hiatus {&lt;br /&gt;
	background-color: rgba(255,193,7,0.20);&lt;br /&gt;
	color: #b8860b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--completed {&lt;br /&gt;
	background-color: rgba(52,101,164,0.15);&lt;br /&gt;
	color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--abandoned {&lt;br /&gt;
	background-color: rgba(108,117,125,0.15);&lt;br /&gt;
	color: #6c757d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-license {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	background: var(--color-surface-2);&lt;br /&gt;
	border: 1px solid var(--border-color-base);&lt;br /&gt;
	color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   4. TABLE UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.table-full { width: 100%; }&lt;br /&gt;
&lt;br /&gt;
.row-green  { background: #d4edda !important; }&lt;br /&gt;
.row-yellow { background: #fff3cd !important; }&lt;br /&gt;
.row-red    { background: #f8d7da !important; }&lt;br /&gt;
.row-blue   { background: #e8f4fd !important; }&lt;br /&gt;
.row-grey   { background: #e9ecef !important; }&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   5. TEXT UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.indent-1 { margin-left: 2em; }&lt;br /&gt;
.indent-2 { margin-left: 4em; }&lt;br /&gt;
&lt;br /&gt;
.text-muted { color: var(--color-base--subtle); font-size: 90%; }&lt;br /&gt;
.text-small { font-size: 85%; }&lt;br /&gt;
&lt;br /&gt;
.wiki-code {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    font-family: monospace;&lt;br /&gt;
    font-size: 90%;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   6. CATEGORY PAGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories h2,&lt;br /&gt;
#mw-pages h2,&lt;br /&gt;
#mw-category-media h2 {&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-bottom: 2px solid var(--wiki-primary);&lt;br /&gt;
    padding-bottom: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Subcategories — displayed as prominent nav blocks above pages */&lt;br /&gt;
#mw-subcategories .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Letter group heading */&lt;br /&gt;
.mw-category-group h3 {&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.1em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    border: none;&lt;br /&gt;
    margin: 20px 0 8px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pages — chip layout */&lt;br /&gt;
#mw-pages .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    min-width: 140px;&lt;br /&gt;
    max-width: 240px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-name {&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-overflow: ellipsis;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Loading shimmer on meta line until API responds */&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta:not(.loaded) {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    color: transparent;&lt;br /&gt;
    width: 80px;&lt;br /&gt;
    height: 0.75em;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    animation: cat-shimmer 1.4s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes cat-shimmer {&lt;br /&gt;
    0%   { opacity: 0.4; }&lt;br /&gt;
    50%  { opacity: 0.9; }&lt;br /&gt;
    100% { opacity: 0.4; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Red links */&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new {&lt;br /&gt;
    border-style: dashed;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new:hover {&lt;br /&gt;
    border-color: var(--border-color-base);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Search bar injected by JS */&lt;br /&gt;
.cat-search-wrap {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    max-width: 400px;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-count {&lt;br /&gt;
    margin-left: 10px;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page count note */&lt;br /&gt;
#mw-pages p,&lt;br /&gt;
#mw-subcategories p {&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   7. Tag-Based Hub — new styles added for unified Projects/Tutorials hubs&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
/* Hub wrapper */&lt;br /&gt;
.project-hub-wrapper,&lt;br /&gt;
.tutorial-hub-wrapper {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Filter bar (search, sort, count) */&lt;br /&gt;
.project-hub-filters,&lt;br /&gt;
.tutorial-hub-filters {&lt;br /&gt;
    background-color: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-search {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 200px;&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-search:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-select {&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-select:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-count,&lt;br /&gt;
.tutorial-hub-count {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Tag cloud */&lt;br /&gt;
.project-hub-tagcloud,&lt;br /&gt;
.tutorial-hub-tagcloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: nowrap;&lt;br /&gt;
    overflow-x: auto;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    scrollbar-width: thin;&lt;br /&gt;
    scrollbar-color: var(--border-color-base) transparent;&lt;br /&gt;
    -webkit-overflow-scrolling: touch;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar {&lt;br /&gt;
    height: 3px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar-thumb,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar-thumb {&lt;br /&gt;
    background: var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Clickable tag — used in cloud AND on cards */&lt;br /&gt;
.js-tag-filter,&lt;br /&gt;
.js-tutorial-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
.js-tag-filter:hover,&lt;br /&gt;
.js-tutorial-tag:hover,&lt;br /&gt;
.js-tag-filter.is-active,&lt;br /&gt;
.js-tutorial-tag.is-active {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Card grid */&lt;br /&gt;
.project-hub-grid,&lt;br /&gt;
.tutorial-hub-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    font-size: 0;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-grid .project-card-wrap,&lt;br /&gt;
.tutorial-hub-grid .tutorial-card-wrap {&lt;br /&gt;
    font-size: 1rem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Empty state */&lt;br /&gt;
.project-hub-empty {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 40px 20px;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Load more button */&lt;br /&gt;
.project-hub-loadmore,&lt;br /&gt;
.tutorial-hub-loadmore {&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    margin: 8px 0 16px;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-loadmore:hover,&lt;br /&gt;
.tutorial-hub-loadmore:hover {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   8.Hub Main Page Buttons&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.hub-buttons {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 240px;&lt;br /&gt;
    display: block;&lt;br /&gt;
    padding: 24px 20px;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    transition: opacity 0.15s, transform 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:hover {&lt;br /&gt;
    opacity: 0.92;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:first-child {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:last-child {&lt;br /&gt;
    background: rgba(228, 100, 25, 0.82);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons .hub-btn-sub {&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-size: 0.78em;&lt;br /&gt;
    font-weight: 400;&lt;br /&gt;
    opacity: 0.88;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for MediaWiki parser injecting &amp;lt;p&amp;gt; tags inside the container */&lt;br /&gt;
.hub-buttons,&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   9. License Cloud (Projects hub)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.project-hub-licensecloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 10px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-secondary-subtle);&lt;br /&gt;
    color: var(--wiki-secondary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter:hover,&lt;br /&gt;
.js-license-filter.is-active {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   10. Tag Tokenizer (Gadget-tagautocomplete.js)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    min-height: 38px;&lt;br /&gt;
    padding: 5px 8px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    cursor: text;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box:focus-within {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token {&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 4px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove {&lt;br /&gt;
    background: none;&lt;br /&gt;
    border: none;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove:hover { opacity: 1; }&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-entry {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 160px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    padding: 2px 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: calc(100% + 3px);&lt;br /&gt;
    left: 0;&lt;br /&gt;
    right: 0;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 4px 0;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    max-height: 220px;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li {&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li:hover {&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   11. Page Forms — inputs styled to match tag tokenizer&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.formtable input.createboxInput,&lt;br /&gt;
.formtable textarea.createboxInput,&lt;br /&gt;
.formtable select.createboxInput {&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    padding: 5px 8px;&lt;br /&gt;
    min-height: 38px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable input.createboxInput:focus,&lt;br /&gt;
.formtable textarea.createboxInput:focus,&lt;br /&gt;
.formtable select.createboxInput:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    outline: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable textarea.createboxInput {&lt;br /&gt;
    min-height: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable th {&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    padding-right: 16px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable td {&lt;br /&gt;
    padding: 5px 0;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1242</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1242"/>
		<updated>2026-04-05T10:03:54Z</updated>

		<summary type="html">&lt;p&gt;Anthony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   MediaWiki:Common.css&lt;br /&gt;
   UnfinishedProjects Wiki&lt;br /&gt;
   &lt;br /&gt;
   TABLE OF CONTENTS&lt;br /&gt;
   0.  Nav Forum Link&lt;br /&gt;
   1.  Brand Variables&lt;br /&gt;
   2.  Callout Boxes&lt;br /&gt;
   3.  Badges&lt;br /&gt;
   4.  Table Utilities&lt;br /&gt;
   5.  Text Utilities&lt;br /&gt;
   6.  Category Pages&lt;br /&gt;
   7.  Tag-Based Hub&lt;br /&gt;
   8.  Hub Main Page Buttons&lt;br /&gt;
   9.  License Cloud&lt;br /&gt;
   10. Tag Tokenizer&lt;br /&gt;
   11. Page Forms&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   0. Forum Link&lt;br /&gt;
   Forum header link — Gadget-sitenav.js&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link {&lt;br /&gt;
    background: var(--wiki-primary-subtle) !important;&lt;br /&gt;
    border: 1px solid var(--wiki-primary) !important;&lt;br /&gt;
    border-radius: 20px !important;&lt;br /&gt;
    color: var(--wiki-primary) !important;&lt;br /&gt;
    transition: background 0.15s, color 0.15s !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover {&lt;br /&gt;
    background: var(--wiki-primary) !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover .citizen-ui-icon {&lt;br /&gt;
    filter: brightness(0) invert(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   1. BRAND VARIABLES&lt;br /&gt;
   Edit only these lines to retheme the entire wiki.&lt;br /&gt;
   subtle  = primary at ~12% opacity (tag backgrounds, tints)&lt;br /&gt;
   overlay = primary at ~92% opacity (card hover overlays)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
    --wiki-primary:           #e46419;&lt;br /&gt;
    --wiki-primary-subtle:    rgba(228, 100, 25, 0.12);&lt;br /&gt;
    --wiki-primary-overlay:   rgba(228, 100, 25, 0.92);&lt;br /&gt;
    --wiki-secondary:         #3465a4;&lt;br /&gt;
    --wiki-secondary-subtle:  rgba(52, 101, 164, 0.12);&lt;br /&gt;
    --wiki-secondary-overlay: rgba(52, 101, 164, 0.92);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   2. CALLOUT BOXES&lt;br /&gt;
   Light mode uses tinted backgrounds.&lt;br /&gt;
   Dark mode desaturates them so they don&#039;t glow on dark surfaces.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.box-info,&lt;br /&gt;
.box-warning,&lt;br /&gt;
.box-danger,&lt;br /&gt;
.box-success {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box-info    { background: #e8f4fd; border-left: 4px solid #2196F3; }&lt;br /&gt;
.box-warning { background: #fff3cd; border-left: 4px solid #ffc107; }&lt;br /&gt;
.box-danger  { background: #f8d7da; border-left: 4px solid #dc3545; }&lt;br /&gt;
.box-success { background: #d4edda; border-left: 4px solid #28a745; }&lt;br /&gt;
&lt;br /&gt;
.box-neutral {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   3. BADGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.badge {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 2px 9px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 85%;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.badge-green  { background: #28a745; color: #fff; }&lt;br /&gt;
.badge-red    { background: #dc3545; color: #fff; }&lt;br /&gt;
.badge-yellow { background: #ffc107; color: #212529; }&lt;br /&gt;
.badge-blue   { background: #17a2b8; color: #fff; }&lt;br /&gt;
.badge-grey   { background: #6c757d; color: #fff; }&lt;br /&gt;
.badge-dark   { background: #3d3d3d; color: #fff; }&lt;br /&gt;
&lt;br /&gt;
/* Project badges */&lt;br /&gt;
.project-badge-status {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.03em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--active {&lt;br /&gt;
	background-color: rgba(40,167,69,0.15);&lt;br /&gt;
	color: #28a745;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--hiatus {&lt;br /&gt;
	background-color: rgba(255,193,7,0.20);&lt;br /&gt;
	color: #b8860b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--completed {&lt;br /&gt;
	background-color: rgba(52,101,164,0.15);&lt;br /&gt;
	color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--abandoned {&lt;br /&gt;
	background-color: rgba(108,117,125,0.15);&lt;br /&gt;
	color: #6c757d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-license {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	background: var(--color-surface-2);&lt;br /&gt;
	border: 1px solid var(--border-color-base);&lt;br /&gt;
	color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   4. TABLE UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.table-full { width: 100%; }&lt;br /&gt;
&lt;br /&gt;
.row-green  { background: #d4edda !important; }&lt;br /&gt;
.row-yellow { background: #fff3cd !important; }&lt;br /&gt;
.row-red    { background: #f8d7da !important; }&lt;br /&gt;
.row-blue   { background: #e8f4fd !important; }&lt;br /&gt;
.row-grey   { background: #e9ecef !important; }&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   5. TEXT UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.indent-1 { margin-left: 2em; }&lt;br /&gt;
.indent-2 { margin-left: 4em; }&lt;br /&gt;
&lt;br /&gt;
.text-muted { color: var(--color-base--subtle); font-size: 90%; }&lt;br /&gt;
.text-small { font-size: 85%; }&lt;br /&gt;
&lt;br /&gt;
.wiki-code {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    font-family: monospace;&lt;br /&gt;
    font-size: 90%;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   6. CATEGORY PAGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories h2,&lt;br /&gt;
#mw-pages h2,&lt;br /&gt;
#mw-category-media h2 {&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-bottom: 2px solid var(--wiki-primary);&lt;br /&gt;
    padding-bottom: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Subcategories — displayed as prominent nav blocks above pages */&lt;br /&gt;
#mw-subcategories .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Letter group heading */&lt;br /&gt;
.mw-category-group h3 {&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.1em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    border: none;&lt;br /&gt;
    margin: 20px 0 8px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pages — chip layout */&lt;br /&gt;
#mw-pages .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    min-width: 140px;&lt;br /&gt;
    max-width: 240px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-name {&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-overflow: ellipsis;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Loading shimmer on meta line until API responds */&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta:not(.loaded) {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    color: transparent;&lt;br /&gt;
    width: 80px;&lt;br /&gt;
    height: 0.75em;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    animation: cat-shimmer 1.4s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes cat-shimmer {&lt;br /&gt;
    0%   { opacity: 0.4; }&lt;br /&gt;
    50%  { opacity: 0.9; }&lt;br /&gt;
    100% { opacity: 0.4; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Red links */&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new {&lt;br /&gt;
    border-style: dashed;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new:hover {&lt;br /&gt;
    border-color: var(--border-color-base);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Search bar injected by JS */&lt;br /&gt;
.cat-search-wrap {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    max-width: 400px;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-count {&lt;br /&gt;
    margin-left: 10px;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page count note */&lt;br /&gt;
#mw-pages p,&lt;br /&gt;
#mw-subcategories p {&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   7. Tag-Based Hub — new styles added for unified Projects/Tutorials hubs&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
/* Hub wrapper */&lt;br /&gt;
.project-hub-wrapper,&lt;br /&gt;
.tutorial-hub-wrapper {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Filter bar (search, sort, count) */&lt;br /&gt;
.project-hub-filters,&lt;br /&gt;
.tutorial-hub-filters {&lt;br /&gt;
    background-color: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-search {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 200px;&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-search:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-select {&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-select:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-count,&lt;br /&gt;
.tutorial-hub-count {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Tag cloud */&lt;br /&gt;
.project-hub-tagcloud,&lt;br /&gt;
.tutorial-hub-tagcloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: nowrap;&lt;br /&gt;
    overflow-x: auto;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    scrollbar-width: thin;&lt;br /&gt;
    scrollbar-color: var(--border-color-base) transparent;&lt;br /&gt;
    -webkit-overflow-scrolling: touch;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar {&lt;br /&gt;
    height: 3px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar-thumb,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar-thumb {&lt;br /&gt;
    background: var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Clickable tag — used in cloud AND on cards */&lt;br /&gt;
.js-tag-filter,&lt;br /&gt;
.js-tutorial-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
.js-tag-filter:hover,&lt;br /&gt;
.js-tutorial-tag:hover,&lt;br /&gt;
.js-tag-filter.is-active,&lt;br /&gt;
.js-tutorial-tag.is-active {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Card grid */&lt;br /&gt;
.project-hub-grid,&lt;br /&gt;
.tutorial-hub-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    font-size: 0;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-grid .project-card-wrap,&lt;br /&gt;
.tutorial-hub-grid .tutorial-card-wrap {&lt;br /&gt;
    font-size: 1rem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Empty state */&lt;br /&gt;
.project-hub-empty {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 40px 20px;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Load more button */&lt;br /&gt;
.project-hub-loadmore,&lt;br /&gt;
.tutorial-hub-loadmore {&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    margin: 8px 0 16px;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-loadmore:hover,&lt;br /&gt;
.tutorial-hub-loadmore:hover {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   8.Hub Main Page Buttons&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.hub-buttons {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 240px;&lt;br /&gt;
    display: block;&lt;br /&gt;
    padding: 24px 20px;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    transition: opacity 0.15s, transform 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:hover {&lt;br /&gt;
    opacity: 0.92;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:first-child {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:last-child {&lt;br /&gt;
    background: rgba(228, 100, 25, 0.82);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons .hub-btn-sub {&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-size: 0.78em;&lt;br /&gt;
    font-weight: 400;&lt;br /&gt;
    opacity: 0.88;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for MediaWiki parser injecting &amp;lt;p&amp;gt; tags inside the container */&lt;br /&gt;
.hub-buttons,&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   9. License Cloud (Projects hub)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.project-hub-licensecloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 10px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-secondary-subtle);&lt;br /&gt;
    color: var(--wiki-secondary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter:hover,&lt;br /&gt;
.js-license-filter.is-active {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   10. Tag Tokenizer (Gadget-tagautocomplete.js)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    min-height: 38px;&lt;br /&gt;
    padding: 5px 8px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    cursor: text;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box:focus-within {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token {&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 4px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove {&lt;br /&gt;
    background: none;&lt;br /&gt;
    border: none;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove:hover { opacity: 1; }&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-entry {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 160px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    padding: 2px 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: calc(100% + 3px);&lt;br /&gt;
    left: 0;&lt;br /&gt;
    right: 0;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 4px 0;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    max-height: 220px;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li {&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li:hover {&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   11. Page Forms — consistent input styling to match tag tokenizer aesthetic&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.formtable input.createboxInput,&lt;br /&gt;
.formtable textarea.createboxInput {&lt;br /&gt;
    background: var(--color-surface-0, Field);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
    padding: 3px 6px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    transition: border-color 0.15s, outline 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable input.createboxInput:focus,&lt;br /&gt;
.formtable textarea.createboxInput:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    outline: 1px solid var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable select.createboxInput {&lt;br /&gt;
    background: var(--color-surface-0, Field);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
    padding: 3px 6px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable select.createboxInput:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    outline: 1px solid var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable th {&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    padding-right: 16px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable td {&lt;br /&gt;
    padding: 5px 0;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1241</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1241"/>
		<updated>2026-04-05T10:02:47Z</updated>

		<summary type="html">&lt;p&gt;Anthony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   MediaWiki:Common.css&lt;br /&gt;
   UnfinishedProjects Wiki&lt;br /&gt;
   &lt;br /&gt;
   TABLE OF CONTENTS&lt;br /&gt;
   0.  Nav Forum Link&lt;br /&gt;
   1.  Brand Variables&lt;br /&gt;
   2.  Callout Boxes&lt;br /&gt;
   3.  Badges&lt;br /&gt;
   4.  Table Utilities&lt;br /&gt;
   5.  Text Utilities&lt;br /&gt;
   6.  Category Pages&lt;br /&gt;
   7.  Tag-Based Hub&lt;br /&gt;
   8.  Hub Main Page Buttons&lt;br /&gt;
   9.  License Cloud&lt;br /&gt;
   10. Tag Tokenizer&lt;br /&gt;
   11. Page Forms&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   0. Forum Link&lt;br /&gt;
   Forum header link — Gadget-sitenav.js&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link {&lt;br /&gt;
    background: var(--wiki-primary-subtle) !important;&lt;br /&gt;
    border: 1px solid var(--wiki-primary) !important;&lt;br /&gt;
    border-radius: 20px !important;&lt;br /&gt;
    color: var(--wiki-primary) !important;&lt;br /&gt;
    transition: background 0.15s, color 0.15s !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover {&lt;br /&gt;
    background: var(--wiki-primary) !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover .citizen-ui-icon {&lt;br /&gt;
    filter: brightness(0) invert(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   1. BRAND VARIABLES&lt;br /&gt;
   Edit only these lines to retheme the entire wiki.&lt;br /&gt;
   subtle  = primary at ~12% opacity (tag backgrounds, tints)&lt;br /&gt;
   overlay = primary at ~92% opacity (card hover overlays)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
    --wiki-primary:           #e46419;&lt;br /&gt;
    --wiki-primary-subtle:    rgba(228, 100, 25, 0.12);&lt;br /&gt;
    --wiki-primary-overlay:   rgba(228, 100, 25, 0.92);&lt;br /&gt;
    --wiki-secondary:         #3465a4;&lt;br /&gt;
    --wiki-secondary-subtle:  rgba(52, 101, 164, 0.12);&lt;br /&gt;
    --wiki-secondary-overlay: rgba(52, 101, 164, 0.92);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   2. CALLOUT BOXES&lt;br /&gt;
   Light mode uses tinted backgrounds.&lt;br /&gt;
   Dark mode desaturates them so they don&#039;t glow on dark surfaces.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.box-info,&lt;br /&gt;
.box-warning,&lt;br /&gt;
.box-danger,&lt;br /&gt;
.box-success {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box-info    { background: #e8f4fd; border-left: 4px solid #2196F3; }&lt;br /&gt;
.box-warning { background: #fff3cd; border-left: 4px solid #ffc107; }&lt;br /&gt;
.box-danger  { background: #f8d7da; border-left: 4px solid #dc3545; }&lt;br /&gt;
.box-success { background: #d4edda; border-left: 4px solid #28a745; }&lt;br /&gt;
&lt;br /&gt;
.box-neutral {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   3. BADGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.badge {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 2px 9px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 85%;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.badge-green  { background: #28a745; color: #fff; }&lt;br /&gt;
.badge-red    { background: #dc3545; color: #fff; }&lt;br /&gt;
.badge-yellow { background: #ffc107; color: #212529; }&lt;br /&gt;
.badge-blue   { background: #17a2b8; color: #fff; }&lt;br /&gt;
.badge-grey   { background: #6c757d; color: #fff; }&lt;br /&gt;
.badge-dark   { background: #3d3d3d; color: #fff; }&lt;br /&gt;
&lt;br /&gt;
/* Project badges */&lt;br /&gt;
.project-badge-status {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.03em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--active {&lt;br /&gt;
	background-color: rgba(40,167,69,0.15);&lt;br /&gt;
	color: #28a745;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--hiatus {&lt;br /&gt;
	background-color: rgba(255,193,7,0.20);&lt;br /&gt;
	color: #b8860b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--completed {&lt;br /&gt;
	background-color: rgba(52,101,164,0.15);&lt;br /&gt;
	color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--abandoned {&lt;br /&gt;
	background-color: rgba(108,117,125,0.15);&lt;br /&gt;
	color: #6c757d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-license {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	background: var(--color-surface-2);&lt;br /&gt;
	border: 1px solid var(--border-color-base);&lt;br /&gt;
	color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   4. TABLE UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.table-full { width: 100%; }&lt;br /&gt;
&lt;br /&gt;
.row-green  { background: #d4edda !important; }&lt;br /&gt;
.row-yellow { background: #fff3cd !important; }&lt;br /&gt;
.row-red    { background: #f8d7da !important; }&lt;br /&gt;
.row-blue   { background: #e8f4fd !important; }&lt;br /&gt;
.row-grey   { background: #e9ecef !important; }&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   5. TEXT UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.indent-1 { margin-left: 2em; }&lt;br /&gt;
.indent-2 { margin-left: 4em; }&lt;br /&gt;
&lt;br /&gt;
.text-muted { color: var(--color-base--subtle); font-size: 90%; }&lt;br /&gt;
.text-small { font-size: 85%; }&lt;br /&gt;
&lt;br /&gt;
.wiki-code {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    font-family: monospace;&lt;br /&gt;
    font-size: 90%;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   6. CATEGORY PAGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories h2,&lt;br /&gt;
#mw-pages h2,&lt;br /&gt;
#mw-category-media h2 {&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-bottom: 2px solid var(--wiki-primary);&lt;br /&gt;
    padding-bottom: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Subcategories — displayed as prominent nav blocks above pages */&lt;br /&gt;
#mw-subcategories .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Letter group heading */&lt;br /&gt;
.mw-category-group h3 {&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.1em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    border: none;&lt;br /&gt;
    margin: 20px 0 8px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pages — chip layout */&lt;br /&gt;
#mw-pages .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    min-width: 140px;&lt;br /&gt;
    max-width: 240px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-name {&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-overflow: ellipsis;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Loading shimmer on meta line until API responds */&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta:not(.loaded) {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    color: transparent;&lt;br /&gt;
    width: 80px;&lt;br /&gt;
    height: 0.75em;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    animation: cat-shimmer 1.4s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes cat-shimmer {&lt;br /&gt;
    0%   { opacity: 0.4; }&lt;br /&gt;
    50%  { opacity: 0.9; }&lt;br /&gt;
    100% { opacity: 0.4; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Red links */&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new {&lt;br /&gt;
    border-style: dashed;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new:hover {&lt;br /&gt;
    border-color: var(--border-color-base);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Search bar injected by JS */&lt;br /&gt;
.cat-search-wrap {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    max-width: 400px;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-count {&lt;br /&gt;
    margin-left: 10px;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page count note */&lt;br /&gt;
#mw-pages p,&lt;br /&gt;
#mw-subcategories p {&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   7. Tag-Based Hub — new styles added for unified Projects/Tutorials hubs&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
/* Hub wrapper */&lt;br /&gt;
.project-hub-wrapper,&lt;br /&gt;
.tutorial-hub-wrapper {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Filter bar (search, sort, count) */&lt;br /&gt;
.project-hub-filters,&lt;br /&gt;
.tutorial-hub-filters {&lt;br /&gt;
    background-color: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-search {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 200px;&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-search:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-select {&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-select:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-count,&lt;br /&gt;
.tutorial-hub-count {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Tag cloud */&lt;br /&gt;
.project-hub-tagcloud,&lt;br /&gt;
.tutorial-hub-tagcloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: nowrap;&lt;br /&gt;
    overflow-x: auto;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    scrollbar-width: thin;&lt;br /&gt;
    scrollbar-color: var(--border-color-base) transparent;&lt;br /&gt;
    -webkit-overflow-scrolling: touch;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar {&lt;br /&gt;
    height: 3px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar-thumb,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar-thumb {&lt;br /&gt;
    background: var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Clickable tag — used in cloud AND on cards */&lt;br /&gt;
.js-tag-filter,&lt;br /&gt;
.js-tutorial-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
.js-tag-filter:hover,&lt;br /&gt;
.js-tutorial-tag:hover,&lt;br /&gt;
.js-tag-filter.is-active,&lt;br /&gt;
.js-tutorial-tag.is-active {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Card grid */&lt;br /&gt;
.project-hub-grid,&lt;br /&gt;
.tutorial-hub-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    font-size: 0;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-grid .project-card-wrap,&lt;br /&gt;
.tutorial-hub-grid .tutorial-card-wrap {&lt;br /&gt;
    font-size: 1rem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Empty state */&lt;br /&gt;
.project-hub-empty {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 40px 20px;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Load more button */&lt;br /&gt;
.project-hub-loadmore,&lt;br /&gt;
.tutorial-hub-loadmore {&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    margin: 8px 0 16px;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-loadmore:hover,&lt;br /&gt;
.tutorial-hub-loadmore:hover {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   8.Hub Main Page Buttons&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.hub-buttons {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 240px;&lt;br /&gt;
    display: block;&lt;br /&gt;
    padding: 24px 20px;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    transition: opacity 0.15s, transform 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:hover {&lt;br /&gt;
    opacity: 0.92;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:first-child {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:last-child {&lt;br /&gt;
    background: rgba(228, 100, 25, 0.82);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons .hub-btn-sub {&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-size: 0.78em;&lt;br /&gt;
    font-weight: 400;&lt;br /&gt;
    opacity: 0.88;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for MediaWiki parser injecting &amp;lt;p&amp;gt; tags inside the container */&lt;br /&gt;
.hub-buttons,&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   9. License Cloud (Projects hub)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.project-hub-licensecloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 10px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-secondary-subtle);&lt;br /&gt;
    color: var(--wiki-secondary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter:hover,&lt;br /&gt;
.js-license-filter.is-active {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   10. Tag Tokenizer (Gadget-tagautocomplete.js)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box {&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 4px;&lt;br /&gt;
    min-height: 1.75em;&lt;br /&gt;
    padding: 2px 4px;&lt;br /&gt;
    background: var(--color-surface-0, Field);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
    cursor: text;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box:focus-within {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    outline: 1px solid var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token {&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 3px;&lt;br /&gt;
    padding: 1px 7px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove {&lt;br /&gt;
    background: none;&lt;br /&gt;
    border: none;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove:hover { opacity: 1; }&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-entry {&lt;br /&gt;
    border: none;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    padding: 1px 2px;&lt;br /&gt;
    min-width: 8em;&lt;br /&gt;
    flex: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: calc(100% + 2px);&lt;br /&gt;
    left: 0;&lt;br /&gt;
    min-width: 100%;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 4px 0;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    max-height: 220px;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li {&lt;br /&gt;
    padding: 6px 14px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li:hover {&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   11. Page Forms — consistent input styling to match tag tokenizer aesthetic&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.formtable input.createboxInput,&lt;br /&gt;
.formtable textarea.createboxInput {&lt;br /&gt;
    background: var(--color-surface-0, Field);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
    padding: 3px 6px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    transition: border-color 0.15s, outline 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable input.createboxInput:focus,&lt;br /&gt;
.formtable textarea.createboxInput:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    outline: 1px solid var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable select.createboxInput {&lt;br /&gt;
    background: var(--color-surface-0, Field);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
    padding: 3px 6px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable select.createboxInput:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    outline: 1px solid var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable th {&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    padding-right: 16px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.formtable td {&lt;br /&gt;
    padding: 5px 0;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1240</id>
		<title>Form:Submit Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1240"/>
		<updated>2026-04-05T09:57:42Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Small updates to the input placeholder text.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{{info|page name=Projects/&amp;lt;ProjectMeta[name]&amp;gt;}}}&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{{for template|ProjectMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Project Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Project Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Status:&lt;br /&gt;
| {{{field|status|input type=dropdown|values=Active,Hiatus,Completed,Abandoned|default=Active}}}&lt;br /&gt;
|-&lt;br /&gt;
! License:&lt;br /&gt;
| {{{field|license|input type=dropdown|values=CC0 1.0,CC BY 4.0,CC BY-SA 4.0,MIT,Apache 2.0,GPL-3.0,AGPL-3.0,LGPL-3.0,BSD-3-Clause,MPL-2.0,EPL-2.0,EUPL-1.2}}}&lt;br /&gt;
|-&lt;br /&gt;
! Creator / Team:&lt;br /&gt;
| {{{field|creator|input type=text|size=40|placeholder=Your name or team name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown when clicking &amp;quot;read more&amp;quot; on your project card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, ambient, synthesis}}}&lt;br /&gt;
|-&lt;br /&gt;
! Website:&lt;br /&gt;
| {{{field|website|input type=text|size=60|placeholder=example.com}}}&lt;br /&gt;
|-&lt;br /&gt;
! Repository:&lt;br /&gt;
| {{{field|repository|input type=text|size=60|placeholder=https://codeberg.org/...}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Label:&lt;br /&gt;
| {{{field|field1label|input type=text|size=30|placeholder=e.g. Project Lead}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Value:&lt;br /&gt;
| {{{field|field1value|input type=text|size=30|placeholder=e.g. Aang}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Label:&lt;br /&gt;
| {{{field|field2label|input type=text|size=30|placeholder=e.g. Forked From}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Value:&lt;br /&gt;
| {{{field|field2value|input type=text|size=30|placeholder=e.g. Original Project}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Label:&lt;br /&gt;
| {{{field|field3label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Value:&lt;br /&gt;
| {{{field|field3value|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Label:&lt;br /&gt;
| {{{field|field4label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Value:&lt;br /&gt;
| {{{field|field4value|input type=text|size=30}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Project}}} {{{standard input|cancel}}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1239</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1239"/>
		<updated>2026-04-05T09:49:47Z</updated>

		<summary type="html">&lt;p&gt;Anthony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   MediaWiki:Common.css&lt;br /&gt;
   UnfinishedProjects Wiki&lt;br /&gt;
   &lt;br /&gt;
   TABLE OF CONTENTS&lt;br /&gt;
   0.  Nav Forum Link&lt;br /&gt;
   1.  Brand Variables&lt;br /&gt;
   2.  Callout Boxes&lt;br /&gt;
   3.  Badges&lt;br /&gt;
   4.  Table Utilities&lt;br /&gt;
   5.  Text Utilities&lt;br /&gt;
   6.  Category Pages&lt;br /&gt;
   7.  Tag-Based Hub&lt;br /&gt;
   8.  Hub Main Page Buttons&lt;br /&gt;
   9.  License Cloud&lt;br /&gt;
   10. Tag Tokenizer&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   0. Forum Link&lt;br /&gt;
   Forum header link — Gadget-sitenav.js&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link {&lt;br /&gt;
    background: var(--wiki-primary-subtle) !important;&lt;br /&gt;
    border: 1px solid var(--wiki-primary) !important;&lt;br /&gt;
    border-radius: 20px !important;&lt;br /&gt;
    color: var(--wiki-primary) !important;&lt;br /&gt;
    transition: background 0.15s, color 0.15s !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover {&lt;br /&gt;
    background: var(--wiki-primary) !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover .citizen-ui-icon {&lt;br /&gt;
    filter: brightness(0) invert(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   1. BRAND VARIABLES&lt;br /&gt;
   Edit only these lines to retheme the entire wiki.&lt;br /&gt;
   subtle  = primary at ~12% opacity (tag backgrounds, tints)&lt;br /&gt;
   overlay = primary at ~92% opacity (card hover overlays)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
    --wiki-primary:           #e46419;&lt;br /&gt;
    --wiki-primary-subtle:    rgba(228, 100, 25, 0.12);&lt;br /&gt;
    --wiki-primary-overlay:   rgba(228, 100, 25, 0.92);&lt;br /&gt;
    --wiki-secondary:         #3465a4;&lt;br /&gt;
    --wiki-secondary-subtle:  rgba(52, 101, 164, 0.12);&lt;br /&gt;
    --wiki-secondary-overlay: rgba(52, 101, 164, 0.92);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   2. CALLOUT BOXES&lt;br /&gt;
   Light mode uses tinted backgrounds.&lt;br /&gt;
   Dark mode desaturates them so they don&#039;t glow on dark surfaces.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.box-info,&lt;br /&gt;
.box-warning,&lt;br /&gt;
.box-danger,&lt;br /&gt;
.box-success {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box-info    { background: #e8f4fd; border-left: 4px solid #2196F3; }&lt;br /&gt;
.box-warning { background: #fff3cd; border-left: 4px solid #ffc107; }&lt;br /&gt;
.box-danger  { background: #f8d7da; border-left: 4px solid #dc3545; }&lt;br /&gt;
.box-success { background: #d4edda; border-left: 4px solid #28a745; }&lt;br /&gt;
&lt;br /&gt;
.box-neutral {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   3. BADGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.badge {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 2px 9px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 85%;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.badge-green  { background: #28a745; color: #fff; }&lt;br /&gt;
.badge-red    { background: #dc3545; color: #fff; }&lt;br /&gt;
.badge-yellow { background: #ffc107; color: #212529; }&lt;br /&gt;
.badge-blue   { background: #17a2b8; color: #fff; }&lt;br /&gt;
.badge-grey   { background: #6c757d; color: #fff; }&lt;br /&gt;
.badge-dark   { background: #3d3d3d; color: #fff; }&lt;br /&gt;
&lt;br /&gt;
/* Project badges */&lt;br /&gt;
.project-badge-status {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.03em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--active {&lt;br /&gt;
	background-color: rgba(40,167,69,0.15);&lt;br /&gt;
	color: #28a745;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--hiatus {&lt;br /&gt;
	background-color: rgba(255,193,7,0.20);&lt;br /&gt;
	color: #b8860b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--completed {&lt;br /&gt;
	background-color: rgba(52,101,164,0.15);&lt;br /&gt;
	color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--abandoned {&lt;br /&gt;
	background-color: rgba(108,117,125,0.15);&lt;br /&gt;
	color: #6c757d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-license {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	background: var(--color-surface-2);&lt;br /&gt;
	border: 1px solid var(--border-color-base);&lt;br /&gt;
	color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   4. TABLE UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.table-full { width: 100%; }&lt;br /&gt;
&lt;br /&gt;
.row-green  { background: #d4edda !important; }&lt;br /&gt;
.row-yellow { background: #fff3cd !important; }&lt;br /&gt;
.row-red    { background: #f8d7da !important; }&lt;br /&gt;
.row-blue   { background: #e8f4fd !important; }&lt;br /&gt;
.row-grey   { background: #e9ecef !important; }&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   5. TEXT UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.indent-1 { margin-left: 2em; }&lt;br /&gt;
.indent-2 { margin-left: 4em; }&lt;br /&gt;
&lt;br /&gt;
.text-muted { color: var(--color-base--subtle); font-size: 90%; }&lt;br /&gt;
.text-small { font-size: 85%; }&lt;br /&gt;
&lt;br /&gt;
.wiki-code {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    font-family: monospace;&lt;br /&gt;
    font-size: 90%;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   6. CATEGORY PAGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories h2,&lt;br /&gt;
#mw-pages h2,&lt;br /&gt;
#mw-category-media h2 {&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-bottom: 2px solid var(--wiki-primary);&lt;br /&gt;
    padding-bottom: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Subcategories — displayed as prominent nav blocks above pages */&lt;br /&gt;
#mw-subcategories .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Letter group heading */&lt;br /&gt;
.mw-category-group h3 {&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.1em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    border: none;&lt;br /&gt;
    margin: 20px 0 8px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pages — chip layout */&lt;br /&gt;
#mw-pages .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    min-width: 140px;&lt;br /&gt;
    max-width: 240px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-name {&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-overflow: ellipsis;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Loading shimmer on meta line until API responds */&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta:not(.loaded) {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    color: transparent;&lt;br /&gt;
    width: 80px;&lt;br /&gt;
    height: 0.75em;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    animation: cat-shimmer 1.4s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes cat-shimmer {&lt;br /&gt;
    0%   { opacity: 0.4; }&lt;br /&gt;
    50%  { opacity: 0.9; }&lt;br /&gt;
    100% { opacity: 0.4; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Red links */&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new {&lt;br /&gt;
    border-style: dashed;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new:hover {&lt;br /&gt;
    border-color: var(--border-color-base);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Search bar injected by JS */&lt;br /&gt;
.cat-search-wrap {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    max-width: 400px;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-count {&lt;br /&gt;
    margin-left: 10px;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page count note */&lt;br /&gt;
#mw-pages p,&lt;br /&gt;
#mw-subcategories p {&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   7. Tag-Based Hub — new styles added for unified Projects/Tutorials hubs&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
/* Hub wrapper */&lt;br /&gt;
.project-hub-wrapper,&lt;br /&gt;
.tutorial-hub-wrapper {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Filter bar (search, sort, count) */&lt;br /&gt;
.project-hub-filters,&lt;br /&gt;
.tutorial-hub-filters {&lt;br /&gt;
    background-color: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-search {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 200px;&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-search:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-select {&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-select:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-count,&lt;br /&gt;
.tutorial-hub-count {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Tag cloud */&lt;br /&gt;
.project-hub-tagcloud,&lt;br /&gt;
.tutorial-hub-tagcloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: nowrap;&lt;br /&gt;
    overflow-x: auto;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    scrollbar-width: thin;&lt;br /&gt;
    scrollbar-color: var(--border-color-base) transparent;&lt;br /&gt;
    -webkit-overflow-scrolling: touch;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar {&lt;br /&gt;
    height: 3px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar-thumb,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar-thumb {&lt;br /&gt;
    background: var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Clickable tag — used in cloud AND on cards */&lt;br /&gt;
.js-tag-filter,&lt;br /&gt;
.js-tutorial-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
.js-tag-filter:hover,&lt;br /&gt;
.js-tutorial-tag:hover,&lt;br /&gt;
.js-tag-filter.is-active,&lt;br /&gt;
.js-tutorial-tag.is-active {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Card grid */&lt;br /&gt;
.project-hub-grid,&lt;br /&gt;
.tutorial-hub-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    font-size: 0;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-grid .project-card-wrap,&lt;br /&gt;
.tutorial-hub-grid .tutorial-card-wrap {&lt;br /&gt;
    font-size: 1rem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Empty state */&lt;br /&gt;
.project-hub-empty {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 40px 20px;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Load more button */&lt;br /&gt;
.project-hub-loadmore,&lt;br /&gt;
.tutorial-hub-loadmore {&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    margin: 8px 0 16px;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-loadmore:hover,&lt;br /&gt;
.tutorial-hub-loadmore:hover {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   8.Hub Main Page Buttons&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.hub-buttons {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 240px;&lt;br /&gt;
    display: block;&lt;br /&gt;
    padding: 24px 20px;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    transition: opacity 0.15s, transform 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:hover {&lt;br /&gt;
    opacity: 0.92;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:first-child {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:last-child {&lt;br /&gt;
    background: rgba(228, 100, 25, 0.82);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons .hub-btn-sub {&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-size: 0.78em;&lt;br /&gt;
    font-weight: 400;&lt;br /&gt;
    opacity: 0.88;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for MediaWiki parser injecting &amp;lt;p&amp;gt; tags inside the container */&lt;br /&gt;
.hub-buttons,&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   9. License Cloud (Projects hub)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.project-hub-licensecloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 10px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-secondary-subtle);&lt;br /&gt;
    color: var(--wiki-secondary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter:hover,&lt;br /&gt;
.js-license-filter.is-active {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   10. Tag Tokenizer (Gadget-tagautocomplete.js)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box {&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 4px;&lt;br /&gt;
    min-height: 1.75em;&lt;br /&gt;
    padding: 2px 4px;&lt;br /&gt;
    background: var(--color-surface-0, Field);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
    cursor: text;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box:focus-within {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    outline: 1px solid var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token {&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 3px;&lt;br /&gt;
    padding: 1px 7px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove {&lt;br /&gt;
    background: none;&lt;br /&gt;
    border: none;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove:hover { opacity: 1; }&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-entry {&lt;br /&gt;
    border: none;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    padding: 1px 2px;&lt;br /&gt;
    min-width: 8em;&lt;br /&gt;
    flex: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: calc(100% + 2px);&lt;br /&gt;
    left: 0;&lt;br /&gt;
    min-width: 100%;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 4px 0;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    max-height: 220px;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li {&lt;br /&gt;
    padding: 6px 14px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li:hover {&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Tutorial&amp;diff=1238</id>
		<title>Form:Submit Tutorial</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Tutorial&amp;diff=1238"/>
		<updated>2026-04-05T09:47:20Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Remove nav from form&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{{info|page name=Tutorials/&amp;lt;TutorialMeta[name]&amp;gt;}}}&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{{for template|TutorialMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Tutorial Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Tutorial Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown on hover over the tutorial card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, beginner, recording}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Tutorial}}} {{{standard input|cancel}}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1237</id>
		<title>Form:Submit Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1237"/>
		<updated>2026-04-05T09:46:53Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Remove Nav from form&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{{info|page name=Projects/&amp;lt;ProjectMeta[name]&amp;gt;}}}&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{{for template|ProjectMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Project Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Project Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Status:&lt;br /&gt;
| {{{field|status|input type=dropdown|values=Active,Hiatus,Completed,Abandoned|default=Active}}}&lt;br /&gt;
|-&lt;br /&gt;
! License:&lt;br /&gt;
| {{{field|license|input type=dropdown|values=CC0 1.0,CC BY 4.0,CC BY-SA 4.0,MIT,Apache 2.0,GPL-3.0,AGPL-3.0,LGPL-3.0,BSD-3-Clause,MPL-2.0,EPL-2.0,EUPL-1.2}}}&lt;br /&gt;
|-&lt;br /&gt;
! Creator / Team:&lt;br /&gt;
| {{{field|creator|input type=text|size=40|placeholder=Your name or team name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown on hover over your project card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, ambient, synthesis}}}&lt;br /&gt;
|-&lt;br /&gt;
! Website:&lt;br /&gt;
| {{{field|website|input type=text|size=60|placeholder=example.com}}}&lt;br /&gt;
|-&lt;br /&gt;
! Repository:&lt;br /&gt;
| {{{field|repository|input type=text|size=60|placeholder=https://codeberg.org/...}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Label:&lt;br /&gt;
| {{{field|field1label|input type=text|size=30|placeholder=e.g. DAW}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Value:&lt;br /&gt;
| {{{field|field1value|input type=text|size=30|placeholder=e.g. Ableton}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Label:&lt;br /&gt;
| {{{field|field2label|input type=text|size=30|placeholder=e.g. Genre}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Value:&lt;br /&gt;
| {{{field|field2value|input type=text|size=30|placeholder=e.g. Ambient}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Label:&lt;br /&gt;
| {{{field|field3label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Value:&lt;br /&gt;
| {{{field|field3value|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Label:&lt;br /&gt;
| {{{field|field4label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Value:&lt;br /&gt;
| {{{field|field4value|input type=text|size=30}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Project}}} {{{standard input|cancel}}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Gadgets-definition&amp;diff=1236</id>
		<title>MediaWiki:Gadgets-definition</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Gadgets-definition&amp;diff=1236"/>
		<updated>2026-04-05T09:23:51Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Added mediawiki.util to tagautocomplete&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* tutorials[ResourceLoader|hidden|default|dependencies=mediawiki.api]|tutorials.js&lt;br /&gt;
* projects[ResourceLoader|hidden|default|dependencies=mediawiki.api]|projects.js&lt;br /&gt;
* categories[ResourceLoader|hidden|default|dependencies=mediawiki.api]|categories.js&lt;br /&gt;
* sitenav[ResourceLoader|hidden|default]|sitenav.js&lt;br /&gt;
* guide[ResourceLoader|hidden|default]|guide.js&lt;br /&gt;
* subpagenav[ResourceLoader|hidden|default]|subpagenav.js&lt;br /&gt;
* tagautocomplete[ResourceLoader|hidden|default|dependencies=mediawiki.api,mediawiki.util]|tagautocomplete.js&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-tagautocomplete.js&amp;diff=1235</id>
		<title>MediaWiki:Gadget-tagautocomplete.js</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-tagautocomplete.js&amp;diff=1235"/>
		<updated>2026-04-05T09:22:56Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Previous Version did not work - hopefully this one does.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   Gadget-tagautocomplete.js&lt;br /&gt;
   Tokenized tag input with autocomplete on Submit Project / Tutorial forms.&lt;br /&gt;
   Pulls existing tags from the Projects and Tutorials Cargo tables.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
( function () {&lt;br /&gt;
&lt;br /&gt;
    // Only run on Special:FormEdit/* pages&lt;br /&gt;
    if ( mw.config.get( &#039;wgCanonicalSpecialPageName&#039; ) !== &#039;FormEdit&#039; ) { return; }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
&lt;br /&gt;
        // ── Find the tags input by name attribute ────────────────────────────&lt;br /&gt;
        // Page Forms names inputs as TemplateName[fieldname] — target [tags]&lt;br /&gt;
        // specifically. We use .filter() because jQuery CSS attribute selectors&lt;br /&gt;
        // require the attribute to be explicitly present in the HTML; Page Forms&lt;br /&gt;
        // does not write type=&amp;quot;text&amp;quot; on its inputs, so [type=&amp;quot;text&amp;quot;] never matches.&lt;br /&gt;
        var $raw = $( &#039;input&#039; ).filter( function () {&lt;br /&gt;
            var name = $( this ).attr( &#039;name&#039; ) || &#039;&#039;;&lt;br /&gt;
            return name === &#039;ProjectMeta[tags]&#039; || name === &#039;TutorialMeta[tags]&#039;;&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        if ( !$raw.length ) { return; }&lt;br /&gt;
&lt;br /&gt;
        // ── Load all existing tags from Cargo ────────────────────────────────&lt;br /&gt;
        var allTags = [];&lt;br /&gt;
&lt;br /&gt;
        function fetchTags( table ) {&lt;br /&gt;
            return $.getJSON( mw.util.wikiScript( &#039;api&#039; ), {&lt;br /&gt;
                action  : &#039;cargoquery&#039;,&lt;br /&gt;
                tables  : table,&lt;br /&gt;
                fields  : &#039;tags&#039;,&lt;br /&gt;
                limit   : 500,&lt;br /&gt;
                format  : &#039;json&#039;&lt;br /&gt;
            } ).then( function ( data ) {&lt;br /&gt;
                ( data.cargoquery || [] ).forEach( function ( r ) {&lt;br /&gt;
                    ( r.title.tags || &#039;&#039; ).split( &#039;,&#039; ).forEach( function ( t ) {&lt;br /&gt;
                        t = t.trim().toLowerCase();&lt;br /&gt;
                        if ( t &amp;amp;&amp;amp; allTags.indexOf( t ) === -1 ) {&lt;br /&gt;
                            allTags.push( t );&lt;br /&gt;
                        }&lt;br /&gt;
                    } );&lt;br /&gt;
                } );&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $.when(&lt;br /&gt;
            fetchTags( &#039;Projects&#039; ),&lt;br /&gt;
            fetchTags( &#039;Tutorials&#039; )&lt;br /&gt;
        ).then( function () {&lt;br /&gt;
            allTags.sort();&lt;br /&gt;
            $raw.each( function () {&lt;br /&gt;
                initTokenizer( $( this ) );&lt;br /&gt;
            } );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // ── Tokenizer ────────────────────────────────────────────────────────&lt;br /&gt;
        function initTokenizer( $input ) {&lt;br /&gt;
            $input.hide();&lt;br /&gt;
&lt;br /&gt;
            var $wrap     = $( &#039;&amp;lt;div&amp;gt;&#039; ).addClass( &#039;tag-tokenizer&#039; ).insertAfter( $input );&lt;br /&gt;
            var $box      = $( &#039;&amp;lt;div&amp;gt;&#039; ).addClass( &#039;tag-tokenizer-box&#039; ).appendTo( $wrap );&lt;br /&gt;
            var $entry    = $( &#039;&amp;lt;input&amp;gt;&#039; ).attr( {&lt;br /&gt;
                type        : &#039;text&#039;,&lt;br /&gt;
                placeholder : &#039;Type a tag and press Enter or comma\u2026&#039;,&lt;br /&gt;
                autocomplete: &#039;off&#039;&lt;br /&gt;
            } ).addClass( &#039;tag-tokenizer-entry&#039; ).appendTo( $box );&lt;br /&gt;
            var $dropdown = $( &#039;&amp;lt;ul&amp;gt;&#039; ).addClass( &#039;tag-tokenizer-dropdown&#039; ).hide().appendTo( $wrap );&lt;br /&gt;
&lt;br /&gt;
            // Seed from existing hidden input value (edit mode)&lt;br /&gt;
            var existing = ( $input.val() || &#039;&#039; ).split( &#039;,&#039; )&lt;br /&gt;
                .map( function ( t ) { return t.trim(); } )&lt;br /&gt;
                .filter( Boolean );&lt;br /&gt;
            existing.forEach( addToken );&lt;br /&gt;
            syncHidden();&lt;br /&gt;
&lt;br /&gt;
            function addToken( tag ) {&lt;br /&gt;
                tag = tag.trim().toLowerCase().replace( /\s+/g, &#039;-&#039; );&lt;br /&gt;
                if ( !tag ) { return; }&lt;br /&gt;
                if ( $box.find( &#039;.tag-token&#039; ).filter( function () {&lt;br /&gt;
                    return $( this ).data( &#039;tag&#039; ) === tag;&lt;br /&gt;
                } ).length ) { return; }&lt;br /&gt;
&lt;br /&gt;
                var $token = $( &#039;&amp;lt;span&amp;gt;&#039; ).addClass( &#039;tag-token&#039; ).text( tag ).attr( &#039;data-tag&#039;, tag );&lt;br /&gt;
                var $x = $( &#039;&amp;lt;button&amp;gt;&#039; )&lt;br /&gt;
                    .attr( &#039;type&#039;, &#039;button&#039; )&lt;br /&gt;
                    .addClass( &#039;tag-token-remove&#039; )&lt;br /&gt;
                    .text( &#039;\u00d7&#039; )&lt;br /&gt;
                    .on( &#039;click&#039;, function () {&lt;br /&gt;
                        $token.remove();&lt;br /&gt;
                        syncHidden();&lt;br /&gt;
                    } );&lt;br /&gt;
                $token.append( $x ).insertBefore( $entry );&lt;br /&gt;
                syncHidden();&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function syncHidden() {&lt;br /&gt;
                var tags = [];&lt;br /&gt;
                $box.find( &#039;.tag-token&#039; ).each( function () {&lt;br /&gt;
                    tags.push( $( this ).data( &#039;tag&#039; ) );&lt;br /&gt;
                } );&lt;br /&gt;
                $input.val( tags.join( &#039;, &#039; ) );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function showDropdown( query ) {&lt;br /&gt;
                var active = [];&lt;br /&gt;
                $box.find( &#039;.tag-token&#039; ).each( function () {&lt;br /&gt;
                    active.push( $( this ).data( &#039;tag&#039; ) );&lt;br /&gt;
                } );&lt;br /&gt;
&lt;br /&gt;
                var matches = allTags.filter( function ( t ) {&lt;br /&gt;
                    return t.indexOf( query ) === 0 &amp;amp;&amp;amp; active.indexOf( t ) === -1;&lt;br /&gt;
                } ).slice( 0, 8 );&lt;br /&gt;
&lt;br /&gt;
                $dropdown.empty();&lt;br /&gt;
                if ( !matches.length ) { $dropdown.hide(); return; }&lt;br /&gt;
&lt;br /&gt;
                matches.forEach( function ( tag ) {&lt;br /&gt;
                    $( &#039;&amp;lt;li&amp;gt;&#039; ).text( tag ).on( &#039;mousedown&#039;, function ( e ) {&lt;br /&gt;
                        e.preventDefault();&lt;br /&gt;
                        addToken( tag );&lt;br /&gt;
                        $entry.val( &#039;&#039; );&lt;br /&gt;
                        $dropdown.hide();&lt;br /&gt;
                    } ).appendTo( $dropdown );&lt;br /&gt;
                } );&lt;br /&gt;
                $dropdown.show();&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $entry.on( &#039;input&#039;, function () {&lt;br /&gt;
                var val = $entry.val();&lt;br /&gt;
                if ( /,$/.test( val ) ) {&lt;br /&gt;
                    addToken( val.replace( /,$/, &#039;&#039; ) );&lt;br /&gt;
                    $entry.val( &#039;&#039; );&lt;br /&gt;
                    $dropdown.hide();&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                var q = val.trim().toLowerCase();&lt;br /&gt;
                if ( q.length &amp;gt;= 1 ) { showDropdown( q ); } else { $dropdown.hide(); }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            $entry.on( &#039;keydown&#039;, function ( e ) {&lt;br /&gt;
                if ( e.key === &#039;Enter&#039; ) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    var first = $dropdown.find( &#039;li:first&#039; ).text();&lt;br /&gt;
                    addToken( first || $entry.val() );&lt;br /&gt;
                    $entry.val( &#039;&#039; );&lt;br /&gt;
                    $dropdown.hide();&lt;br /&gt;
                }&lt;br /&gt;
                if ( e.key === &#039;Backspace&#039; &amp;amp;&amp;amp; $entry.val() === &#039;&#039; ) {&lt;br /&gt;
                    $box.find( &#039;.tag-token&#039; ).last().remove();&lt;br /&gt;
                    syncHidden();&lt;br /&gt;
                }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            $entry.on( &#039;blur&#039;, function () {&lt;br /&gt;
                setTimeout( function () { $dropdown.hide(); }, 150 );&lt;br /&gt;
                var val = $entry.val().trim();&lt;br /&gt;
                if ( val ) { addToken( val ); $entry.val( &#039;&#039; ); }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            $box.on( &#039;click&#039;, function () { $entry.trigger( &#039;focus&#039; ); } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
}() );&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-tagautocomplete.js&amp;diff=1234</id>
		<title>MediaWiki:Gadget-tagautocomplete.js</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-tagautocomplete.js&amp;diff=1234"/>
		<updated>2026-04-05T09:11:55Z</updated>

		<summary type="html">&lt;p&gt;Anthony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   Gadget-tagautocomplete.js&lt;br /&gt;
   Adds tokenized tag input with autocomplete on Submit Project / Submit Tutorial&lt;br /&gt;
   forms. Pulls existing tags from the Projects and Tutorials Cargo tables.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
( function () {&lt;br /&gt;
&lt;br /&gt;
    var pageName = mw.config.get( &#039;wgPageName&#039; ) || &#039;&#039;;&lt;br /&gt;
    if ( pageName.indexOf( &#039;Special:FormEdit&#039; ) === -1 &amp;amp;&amp;amp;&lt;br /&gt;
         pageName.indexOf( &#039;Special:RunQuery&#039; ) === -1 ) { return; }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
&lt;br /&gt;
        // ── Find the tags input ──────────────────────────────────────────────&lt;br /&gt;
        // Page Forms renders inputs near their label; match by placeholder text.&lt;br /&gt;
        var $raw = $( &#039;input[type=&amp;quot;text&amp;quot;]&#039; ).filter( function () {&lt;br /&gt;
            var ph = ( $( this ).attr( &#039;placeholder&#039; ) || &#039;&#039; ).toLowerCase();&lt;br /&gt;
            return ph.indexOf( &#039;tag&#039; ) !== -1;&lt;br /&gt;
        } );&lt;br /&gt;
        if ( !$raw.length ) { return; }&lt;br /&gt;
&lt;br /&gt;
        // ── Load all existing tags from Cargo ────────────────────────────────&lt;br /&gt;
        var allTags = [];&lt;br /&gt;
&lt;br /&gt;
        function fetchTags( table, field ) {&lt;br /&gt;
            return $.getJSON( mw.util.wikiScript( &#039;api&#039; ), {&lt;br /&gt;
                action   : &#039;cargoquery&#039;,&lt;br /&gt;
                tables   : table,&lt;br /&gt;
                fields   : field,&lt;br /&gt;
                limit    : 500,&lt;br /&gt;
                format   : &#039;json&#039;&lt;br /&gt;
            } ).then( function ( data ) {&lt;br /&gt;
                ( data.cargoquery || [] ).forEach( function ( r ) {&lt;br /&gt;
                    ( r.title[ field ] || &#039;&#039; ).split( &#039;,&#039; ).forEach( function ( t ) {&lt;br /&gt;
                        t = t.trim().toLowerCase();&lt;br /&gt;
                        if ( t &amp;amp;&amp;amp; allTags.indexOf( t ) === -1 ) {&lt;br /&gt;
                            allTags.push( t );&lt;br /&gt;
                        }&lt;br /&gt;
                    } );&lt;br /&gt;
                } );&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $.when(&lt;br /&gt;
            fetchTags( &#039;Projects&#039;,  &#039;tags&#039; ),&lt;br /&gt;
            fetchTags( &#039;Tutorials&#039;, &#039;tags&#039; )&lt;br /&gt;
        ).then( function () {&lt;br /&gt;
            allTags.sort();&lt;br /&gt;
            $raw.each( function () {&lt;br /&gt;
                initTokenizer( $( this ) );&lt;br /&gt;
            } );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // ── Tokenizer ────────────────────────────────────────────────────────&lt;br /&gt;
        function initTokenizer( $input ) {&lt;br /&gt;
            // Build wrapper to sit alongside the original (now hidden) input&lt;br /&gt;
            $input.hide();&lt;br /&gt;
&lt;br /&gt;
            var $wrap = $( &#039;&amp;lt;div&amp;gt;&#039; ).addClass( &#039;tag-tokenizer&#039; ).insertAfter( $input );&lt;br /&gt;
            var $box  = $( &#039;&amp;lt;div&amp;gt;&#039; ).addClass( &#039;tag-tokenizer-box&#039; ).appendTo( $wrap );&lt;br /&gt;
            var $entry = $( &#039;&amp;lt;input&amp;gt;&#039; ).attr( {&lt;br /&gt;
                type        : &#039;text&#039;,&lt;br /&gt;
                placeholder : &#039;Type a tag and press Enter or comma\u2026&#039;,&lt;br /&gt;
                autocomplete: &#039;off&#039;&lt;br /&gt;
            } ).addClass( &#039;tag-tokenizer-entry&#039; ).appendTo( $box );&lt;br /&gt;
            var $dropdown = $( &#039;&amp;lt;ul&amp;gt;&#039; ).addClass( &#039;tag-tokenizer-dropdown&#039; ).hide().appendTo( $wrap );&lt;br /&gt;
&lt;br /&gt;
            // Seed from any value already in the hidden input (edit mode)&lt;br /&gt;
            var existing = ( $input.val() || &#039;&#039; ).split( &#039;,&#039; ).map( function ( t ) { return t.trim(); } ).filter( Boolean );&lt;br /&gt;
            existing.forEach( function ( tag ) { addToken( tag ); } );&lt;br /&gt;
            syncHidden();&lt;br /&gt;
&lt;br /&gt;
            // ── Token rendering ──────────────────────────────────────────────&lt;br /&gt;
            function addToken( tag ) {&lt;br /&gt;
                tag = tag.trim().toLowerCase().replace( /\s+/g, &#039;-&#039; );&lt;br /&gt;
                if ( !tag ) { return; }&lt;br /&gt;
                // Prevent duplicates&lt;br /&gt;
                if ( $box.find( &#039;.tag-token&#039; ).filter( function () {&lt;br /&gt;
                    return $( this ).data( &#039;tag&#039; ) === tag;&lt;br /&gt;
                } ).length ) { return; }&lt;br /&gt;
&lt;br /&gt;
                var $token = $( &#039;&amp;lt;span&amp;gt;&#039; ).addClass( &#039;tag-token&#039; ).text( tag ).attr( &#039;data-tag&#039;, tag );&lt;br /&gt;
                var $x = $( &#039;&amp;lt;button&amp;gt;&#039; ).attr( &#039;type&#039;, &#039;button&#039; ).addClass( &#039;tag-token-remove&#039; ).text( &#039;\u00d7&#039; );&lt;br /&gt;
                $token.append( $x );&lt;br /&gt;
                $x.on( &#039;click&#039;, function () {&lt;br /&gt;
                    $token.remove();&lt;br /&gt;
                    syncHidden();&lt;br /&gt;
                } );&lt;br /&gt;
                $token.insertBefore( $entry );&lt;br /&gt;
                syncHidden();&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function syncHidden() {&lt;br /&gt;
                var tags = [];&lt;br /&gt;
                $box.find( &#039;.tag-token&#039; ).each( function () {&lt;br /&gt;
                    tags.push( $( this ).data( &#039;tag&#039; ) );&lt;br /&gt;
                } );&lt;br /&gt;
                $input.val( tags.join( &#039;, &#039; ) );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // ── Autocomplete dropdown ────────────────────────────────────────&lt;br /&gt;
            function showDropdown( query ) {&lt;br /&gt;
                var existing = [];&lt;br /&gt;
                $box.find( &#039;.tag-token&#039; ).each( function () {&lt;br /&gt;
                    existing.push( $( this ).data( &#039;tag&#039; ) );&lt;br /&gt;
                } );&lt;br /&gt;
&lt;br /&gt;
                var matches = allTags.filter( function ( t ) {&lt;br /&gt;
                    return t.indexOf( query ) === 0 &amp;amp;&amp;amp; existing.indexOf( t ) === -1;&lt;br /&gt;
                } ).slice( 0, 8 );&lt;br /&gt;
&lt;br /&gt;
                $dropdown.empty();&lt;br /&gt;
                if ( !matches.length ) { $dropdown.hide(); return; }&lt;br /&gt;
&lt;br /&gt;
                matches.forEach( function ( tag ) {&lt;br /&gt;
                    $( &#039;&amp;lt;li&amp;gt;&#039; ).text( tag ).on( &#039;mousedown&#039;, function ( e ) {&lt;br /&gt;
                        e.preventDefault(); // keep focus in $entry&lt;br /&gt;
                        addToken( tag );&lt;br /&gt;
                        $entry.val( &#039;&#039; );&lt;br /&gt;
                        $dropdown.hide();&lt;br /&gt;
                    } ).appendTo( $dropdown );&lt;br /&gt;
                } );&lt;br /&gt;
                $dropdown.show();&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // ── Events ───────────────────────────────────────────────────────&lt;br /&gt;
            $entry.on( &#039;input&#039;, function () {&lt;br /&gt;
                var val = $entry.val();&lt;br /&gt;
                // Comma or space after a word = commit tag&lt;br /&gt;
                if ( /[,]$/.test( val ) ) {&lt;br /&gt;
                    addToken( val.replace( /,$/, &#039;&#039; ) );&lt;br /&gt;
                    $entry.val( &#039;&#039; );&lt;br /&gt;
                    $dropdown.hide();&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                var q = val.trim().toLowerCase();&lt;br /&gt;
                if ( q.length &amp;gt;= 1 ) { showDropdown( q ); } else { $dropdown.hide(); }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            $entry.on( &#039;keydown&#039;, function ( e ) {&lt;br /&gt;
                // Enter = commit current text or first suggestion&lt;br /&gt;
                if ( e.key === &#039;Enter&#039; ) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    var first = $dropdown.find( &#039;li&#039; ).first().text();&lt;br /&gt;
                    addToken( first || $entry.val() );&lt;br /&gt;
                    $entry.val( &#039;&#039; );&lt;br /&gt;
                    $dropdown.hide();&lt;br /&gt;
                }&lt;br /&gt;
                // Backspace on empty entry = remove last token&lt;br /&gt;
                if ( e.key === &#039;Backspace&#039; &amp;amp;&amp;amp; $entry.val() === &#039;&#039; ) {&lt;br /&gt;
                    $box.find( &#039;.tag-token&#039; ).last().remove();&lt;br /&gt;
                    syncHidden();&lt;br /&gt;
                }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            $entry.on( &#039;blur&#039;, function () {&lt;br /&gt;
                setTimeout( function () { $dropdown.hide(); }, 150 );&lt;br /&gt;
                // Commit anything partially typed on blur&lt;br /&gt;
                var val = $entry.val().trim();&lt;br /&gt;
                if ( val ) { addToken( val ); $entry.val( &#039;&#039; ); }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            $box.on( &#039;click&#039;, function () { $entry.trigger( &#039;focus&#039; ); } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
}() );&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1233</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Common.css&amp;diff=1233"/>
		<updated>2026-04-05T08:53:04Z</updated>

		<summary type="html">&lt;p&gt;Anthony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   MediaWiki:Common.css&lt;br /&gt;
   UnfinishedProjects Wiki&lt;br /&gt;
   &lt;br /&gt;
   TABLE OF CONTENTS&lt;br /&gt;
   0.  Nav Forum Link&lt;br /&gt;
   1.  Brand Variables&lt;br /&gt;
   2.  Callout Boxes&lt;br /&gt;
   3.  Badges&lt;br /&gt;
   4.  Table Utilities&lt;br /&gt;
   5.  Text Utilities&lt;br /&gt;
   6.  Category Pages&lt;br /&gt;
   7.  Tag-Based Hub&lt;br /&gt;
   8.  Hub Main Page Buttons&lt;br /&gt;
   9.  License Cloud&lt;br /&gt;
   10. Tag Tokenizer&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   0. Forum Link&lt;br /&gt;
   Forum header link — Gadget-sitenav.js&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link {&lt;br /&gt;
    background: var(--wiki-primary-subtle) !important;&lt;br /&gt;
    border: 1px solid var(--wiki-primary) !important;&lt;br /&gt;
    border-radius: 20px !important;&lt;br /&gt;
    color: var(--wiki-primary) !important;&lt;br /&gt;
    transition: background 0.15s, color 0.15s !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover {&lt;br /&gt;
    background: var(--wiki-primary) !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.citizen-forum-link:hover .citizen-ui-icon {&lt;br /&gt;
    filter: brightness(0) invert(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   1. BRAND VARIABLES&lt;br /&gt;
   Edit only these lines to retheme the entire wiki.&lt;br /&gt;
   subtle  = primary at ~12% opacity (tag backgrounds, tints)&lt;br /&gt;
   overlay = primary at ~92% opacity (card hover overlays)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
    --wiki-primary:           #e46419;&lt;br /&gt;
    --wiki-primary-subtle:    rgba(228, 100, 25, 0.12);&lt;br /&gt;
    --wiki-primary-overlay:   rgba(228, 100, 25, 0.92);&lt;br /&gt;
    --wiki-secondary:         #3465a4;&lt;br /&gt;
    --wiki-secondary-subtle:  rgba(52, 101, 164, 0.12);&lt;br /&gt;
    --wiki-secondary-overlay: rgba(52, 101, 164, 0.92);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   2. CALLOUT BOXES&lt;br /&gt;
   Light mode uses tinted backgrounds.&lt;br /&gt;
   Dark mode desaturates them so they don&#039;t glow on dark surfaces.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.box-info,&lt;br /&gt;
.box-warning,&lt;br /&gt;
.box-danger,&lt;br /&gt;
.box-success {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box-info    { background: #e8f4fd; border-left: 4px solid #2196F3; }&lt;br /&gt;
.box-warning { background: #fff3cd; border-left: 4px solid #ffc107; }&lt;br /&gt;
.box-danger  { background: #f8d7da; border-left: 4px solid #dc3545; }&lt;br /&gt;
.box-success { background: #d4edda; border-left: 4px solid #28a745; }&lt;br /&gt;
&lt;br /&gt;
.box-neutral {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
.skin-theme-clientpref-night .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .box-info    { background: rgba(33,  150, 243, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-warning { background: rgba(255, 193,   7, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-danger  { background: rgba(220,  53,  69, 0.15); }&lt;br /&gt;
    .skin-theme-clientpref-os .box-success { background: rgba(40,  167,  69, 0.15); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   3. BADGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.badge {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 2px 9px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 85%;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.badge-green  { background: #28a745; color: #fff; }&lt;br /&gt;
.badge-red    { background: #dc3545; color: #fff; }&lt;br /&gt;
.badge-yellow { background: #ffc107; color: #212529; }&lt;br /&gt;
.badge-blue   { background: #17a2b8; color: #fff; }&lt;br /&gt;
.badge-grey   { background: #6c757d; color: #fff; }&lt;br /&gt;
.badge-dark   { background: #3d3d3d; color: #fff; }&lt;br /&gt;
&lt;br /&gt;
/* Project badges */&lt;br /&gt;
.project-badge-status {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.03em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--active {&lt;br /&gt;
	background-color: rgba(40,167,69,0.15);&lt;br /&gt;
	color: #28a745;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--hiatus {&lt;br /&gt;
	background-color: rgba(255,193,7,0.20);&lt;br /&gt;
	color: #b8860b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--completed {&lt;br /&gt;
	background-color: rgba(52,101,164,0.15);&lt;br /&gt;
	color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-status--abandoned {&lt;br /&gt;
	background-color: rgba(108,117,125,0.15);&lt;br /&gt;
	color: #6c757d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-badge-license {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	font-size: 0.72em;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	padding: 2px 8px;&lt;br /&gt;
	border-radius: 999px;&lt;br /&gt;
	background: var(--color-surface-2);&lt;br /&gt;
	border: 1px solid var(--border-color-base);&lt;br /&gt;
	color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   4. TABLE UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.table-full { width: 100%; }&lt;br /&gt;
&lt;br /&gt;
.row-green  { background: #d4edda !important; }&lt;br /&gt;
.row-yellow { background: #fff3cd !important; }&lt;br /&gt;
.row-red    { background: #f8d7da !important; }&lt;br /&gt;
.row-blue   { background: #e8f4fd !important; }&lt;br /&gt;
.row-grey   { background: #e9ecef !important; }&lt;br /&gt;
&lt;br /&gt;
.skin-theme-clientpref-night .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
.skin-theme-clientpref-night .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    .skin-theme-clientpref-os .row-green  { background: rgba(40,  167,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-yellow { background: rgba(255, 193,   7, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-red    { background: rgba(220,  53,  69, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-blue   { background: rgba(33,  150, 243, 0.2) !important; }&lt;br /&gt;
    .skin-theme-clientpref-os .row-grey   { background: rgba(108, 117, 125, 0.2) !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   5. TEXT UTILITIES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.indent-1 { margin-left: 2em; }&lt;br /&gt;
.indent-2 { margin-left: 4em; }&lt;br /&gt;
&lt;br /&gt;
.text-muted { color: var(--color-base--subtle); font-size: 90%; }&lt;br /&gt;
.text-small { font-size: 85%; }&lt;br /&gt;
&lt;br /&gt;
.wiki-code {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    font-family: monospace;&lt;br /&gt;
    font-size: 90%;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   6. CATEGORY PAGES&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories h2,&lt;br /&gt;
#mw-pages h2,&lt;br /&gt;
#mw-category-media h2 {&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-bottom: 2px solid var(--wiki-primary);&lt;br /&gt;
    padding-bottom: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Subcategories — displayed as prominent nav blocks above pages */&lt;br /&gt;
#mw-subcategories .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-subcategories .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Letter group heading */&lt;br /&gt;
.mw-category-group h3 {&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.1em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    border: none;&lt;br /&gt;
    margin: 20px 0 8px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pages — chip layout */&lt;br /&gt;
#mw-pages .mw-category-group ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0 0 4px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    min-width: 140px;&lt;br /&gt;
    max-width: 240px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a:hover {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-name {&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-overflow: ellipsis;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Loading shimmer on meta line until API responds */&lt;br /&gt;
#mw-pages .mw-category-group ul li a .cat-item-meta:not(.loaded) {&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    color: transparent;&lt;br /&gt;
    width: 80px;&lt;br /&gt;
    height: 0.75em;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    animation: cat-shimmer 1.4s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes cat-shimmer {&lt;br /&gt;
    0%   { opacity: 0.4; }&lt;br /&gt;
    50%  { opacity: 0.9; }&lt;br /&gt;
    100% { opacity: 0.4; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Red links */&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new {&lt;br /&gt;
    border-style: dashed;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-pages .mw-category-group ul li a.new:hover {&lt;br /&gt;
    border-color: var(--border-color-base);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Search bar injected by JS */&lt;br /&gt;
.cat-search-wrap {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    max-width: 400px;&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-input:focus {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cat-search-count {&lt;br /&gt;
    margin-left: 10px;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page count note */&lt;br /&gt;
#mw-pages p,&lt;br /&gt;
#mw-subcategories p {&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   7. Tag-Based Hub — new styles added for unified Projects/Tutorials hubs&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
/* Hub wrapper */&lt;br /&gt;
.project-hub-wrapper,&lt;br /&gt;
.tutorial-hub-wrapper {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Filter bar (search, sort, count) */&lt;br /&gt;
.project-hub-filters,&lt;br /&gt;
.tutorial-hub-filters {&lt;br /&gt;
    background-color: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-search {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 200px;&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-search:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-select {&lt;br /&gt;
    padding: 6px 10px;&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    background-color: var(--color-surface-1);&lt;br /&gt;
    outline: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-select:focus { border-color: var(--wiki-primary); }&lt;br /&gt;
&lt;br /&gt;
.project-hub-count,&lt;br /&gt;
.tutorial-hub-count {&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Tag cloud */&lt;br /&gt;
.project-hub-tagcloud,&lt;br /&gt;
.tutorial-hub-tagcloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: nowrap;&lt;br /&gt;
    overflow-x: auto;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    scrollbar-width: thin;&lt;br /&gt;
    scrollbar-color: var(--border-color-base) transparent;&lt;br /&gt;
    -webkit-overflow-scrolling: touch;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar {&lt;br /&gt;
    height: 3px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.project-hub-tagcloud::-webkit-scrollbar-thumb,&lt;br /&gt;
.tutorial-hub-tagcloud::-webkit-scrollbar-thumb {&lt;br /&gt;
    background: var(--border-color-base);&lt;br /&gt;
    border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Clickable tag — used in cloud AND on cards */&lt;br /&gt;
.js-tag-filter,&lt;br /&gt;
.js-tutorial-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
.js-tag-filter:hover,&lt;br /&gt;
.js-tutorial-tag:hover,&lt;br /&gt;
.js-tag-filter.is-active,&lt;br /&gt;
.js-tutorial-tag.is-active {&lt;br /&gt;
    background: var(--wiki-primary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Card grid */&lt;br /&gt;
.project-hub-grid,&lt;br /&gt;
.tutorial-hub-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    font-size: 0;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-grid .project-card-wrap,&lt;br /&gt;
.tutorial-hub-grid .tutorial-card-wrap {&lt;br /&gt;
    font-size: 1rem;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Empty state */&lt;br /&gt;
.project-hub-empty {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 40px 20px;&lt;br /&gt;
    color: var(--color-base--subtle);&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Load more button */&lt;br /&gt;
.project-hub-loadmore,&lt;br /&gt;
.tutorial-hub-loadmore {&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    margin: 8px 0 16px;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    background: var(--color-surface-2);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: background 0.15s, border-color 0.15s, color 0.15s;&lt;br /&gt;
}&lt;br /&gt;
.project-hub-loadmore:hover,&lt;br /&gt;
.tutorial-hub-loadmore:hover {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   8.Hub Main Page Buttons&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.hub-buttons {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 240px;&lt;br /&gt;
    display: block;&lt;br /&gt;
    padding: 24px 20px;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    transition: opacity 0.15s, transform 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:hover {&lt;br /&gt;
    opacity: 0.92;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:first-child {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons a:last-child {&lt;br /&gt;
    background: rgba(228, 100, 25, 0.82);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.hub-buttons .hub-btn-sub {&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-size: 0.78em;&lt;br /&gt;
    font-weight: 400;&lt;br /&gt;
    opacity: 0.88;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fix for MediaWiki parser injecting &amp;lt;p&amp;gt; tags inside the container */&lt;br /&gt;
.hub-buttons,&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
.hub-buttons p {&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   9. License Cloud (Projects hub)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.project-hub-licensecloud {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 6px;&lt;br /&gt;
    margin-bottom: 10px;&lt;br /&gt;
    padding: 10px 14px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    background: var(--wiki-secondary-subtle);&lt;br /&gt;
    color: var(--wiki-secondary);&lt;br /&gt;
    border: 1px solid transparent;&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.8em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.12s, color 0.12s, border-color 0.12s;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.js-license-filter:hover,&lt;br /&gt;
.js-license-filter.is-active {&lt;br /&gt;
    background: var(--wiki-secondary);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-color: var(--wiki-secondary);&lt;br /&gt;
}&lt;br /&gt;
/* =============================================================================&lt;br /&gt;
   10. Tag Tokenizer (Gadget-tagautocomplete.js)&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    min-height: 38px;&lt;br /&gt;
    padding: 5px 8px;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    cursor: text;&lt;br /&gt;
    transition: border-color 0.15s;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-box:focus-within {&lt;br /&gt;
    border-color: var(--wiki-primary);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token {&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 4px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    border: 1px solid var(--wiki-primary);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    border-radius: 20px;&lt;br /&gt;
    font-size: 0.82em;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove {&lt;br /&gt;
    background: none;&lt;br /&gt;
    border: none;&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
    font-size: 1.1em;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-token-remove:hover { opacity: 1; }&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-entry {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    min-width: 160px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    outline: none;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    padding: 2px 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: calc(100% + 3px);&lt;br /&gt;
    left: 0;&lt;br /&gt;
    right: 0;&lt;br /&gt;
    background: var(--color-surface-1);&lt;br /&gt;
    border: 1px solid var(--border-color-base);&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 4px 0;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    max-height: 220px;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li {&lt;br /&gt;
    padding: 7px 14px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    color: var(--color-base);&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.1s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tag-tokenizer-dropdown li:hover {&lt;br /&gt;
    background: var(--wiki-primary-subtle);&lt;br /&gt;
    color: var(--wiki-primary);&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-tagautocomplete.js&amp;diff=1232</id>
		<title>MediaWiki:Gadget-tagautocomplete.js</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-tagautocomplete.js&amp;diff=1232"/>
		<updated>2026-04-05T08:52:04Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Created page with &amp;quot;/* =============================================================================    Gadget-tagautocomplete.js    Adds tokenized tag input with autocomplete on Submit Project / Submit Tutorial    forms. Pulls existing tags from the Projects and Tutorials Cargo tables.    ============================================================================= */ ( function () {      var FORM_PAGES = [ &amp;#039;Form:Submit_Project&amp;#039;, &amp;#039;Form:Submit_Tutorial&amp;#039; ];     if ( FORM_PAGES.indexOf( mw.co...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   Gadget-tagautocomplete.js&lt;br /&gt;
   Adds tokenized tag input with autocomplete on Submit Project / Submit Tutorial&lt;br /&gt;
   forms. Pulls existing tags from the Projects and Tutorials Cargo tables.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
( function () {&lt;br /&gt;
&lt;br /&gt;
    var FORM_PAGES = [ &#039;Form:Submit_Project&#039;, &#039;Form:Submit_Tutorial&#039; ];&lt;br /&gt;
    if ( FORM_PAGES.indexOf( mw.config.get( &#039;wgPageName&#039; ) ) === -1 ) { return; }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
&lt;br /&gt;
        // ── Find the tags input ──────────────────────────────────────────────&lt;br /&gt;
        // Page Forms renders inputs near their label; match by placeholder text.&lt;br /&gt;
        var $raw = $( &#039;input[type=&amp;quot;text&amp;quot;]&#039; ).filter( function () {&lt;br /&gt;
            var ph = ( $( this ).attr( &#039;placeholder&#039; ) || &#039;&#039; ).toLowerCase();&lt;br /&gt;
            return ph.indexOf( &#039;tag&#039; ) !== -1;&lt;br /&gt;
        } );&lt;br /&gt;
        if ( !$raw.length ) { return; }&lt;br /&gt;
&lt;br /&gt;
        // ── Load all existing tags from Cargo ────────────────────────────────&lt;br /&gt;
        var allTags = [];&lt;br /&gt;
&lt;br /&gt;
        function fetchTags( table, field ) {&lt;br /&gt;
            return $.getJSON( mw.util.wikiScript( &#039;api&#039; ), {&lt;br /&gt;
                action   : &#039;cargoquery&#039;,&lt;br /&gt;
                tables   : table,&lt;br /&gt;
                fields   : field,&lt;br /&gt;
                limit    : 500,&lt;br /&gt;
                format   : &#039;json&#039;&lt;br /&gt;
            } ).then( function ( data ) {&lt;br /&gt;
                ( data.cargoquery || [] ).forEach( function ( r ) {&lt;br /&gt;
                    ( r.title[ field ] || &#039;&#039; ).split( &#039;,&#039; ).forEach( function ( t ) {&lt;br /&gt;
                        t = t.trim().toLowerCase();&lt;br /&gt;
                        if ( t &amp;amp;&amp;amp; allTags.indexOf( t ) === -1 ) {&lt;br /&gt;
                            allTags.push( t );&lt;br /&gt;
                        }&lt;br /&gt;
                    } );&lt;br /&gt;
                } );&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $.when(&lt;br /&gt;
            fetchTags( &#039;Projects&#039;,  &#039;tags&#039; ),&lt;br /&gt;
            fetchTags( &#039;Tutorials&#039;, &#039;tags&#039; )&lt;br /&gt;
        ).then( function () {&lt;br /&gt;
            allTags.sort();&lt;br /&gt;
            $raw.each( function () {&lt;br /&gt;
                initTokenizer( $( this ) );&lt;br /&gt;
            } );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // ── Tokenizer ────────────────────────────────────────────────────────&lt;br /&gt;
        function initTokenizer( $input ) {&lt;br /&gt;
            // Build wrapper to sit alongside the original (now hidden) input&lt;br /&gt;
            $input.hide();&lt;br /&gt;
&lt;br /&gt;
            var $wrap = $( &#039;&amp;lt;div&amp;gt;&#039; ).addClass( &#039;tag-tokenizer&#039; ).insertAfter( $input );&lt;br /&gt;
            var $box  = $( &#039;&amp;lt;div&amp;gt;&#039; ).addClass( &#039;tag-tokenizer-box&#039; ).appendTo( $wrap );&lt;br /&gt;
            var $entry = $( &#039;&amp;lt;input&amp;gt;&#039; ).attr( {&lt;br /&gt;
                type        : &#039;text&#039;,&lt;br /&gt;
                placeholder : &#039;Type a tag and press Enter or comma\u2026&#039;,&lt;br /&gt;
                autocomplete: &#039;off&#039;&lt;br /&gt;
            } ).addClass( &#039;tag-tokenizer-entry&#039; ).appendTo( $box );&lt;br /&gt;
            var $dropdown = $( &#039;&amp;lt;ul&amp;gt;&#039; ).addClass( &#039;tag-tokenizer-dropdown&#039; ).hide().appendTo( $wrap );&lt;br /&gt;
&lt;br /&gt;
            // Seed from any value already in the hidden input (edit mode)&lt;br /&gt;
            var existing = ( $input.val() || &#039;&#039; ).split( &#039;,&#039; ).map( function ( t ) { return t.trim(); } ).filter( Boolean );&lt;br /&gt;
            existing.forEach( function ( tag ) { addToken( tag ); } );&lt;br /&gt;
            syncHidden();&lt;br /&gt;
&lt;br /&gt;
            // ── Token rendering ──────────────────────────────────────────────&lt;br /&gt;
            function addToken( tag ) {&lt;br /&gt;
                tag = tag.trim().toLowerCase().replace( /\s+/g, &#039;-&#039; );&lt;br /&gt;
                if ( !tag ) { return; }&lt;br /&gt;
                // Prevent duplicates&lt;br /&gt;
                if ( $box.find( &#039;.tag-token&#039; ).filter( function () {&lt;br /&gt;
                    return $( this ).data( &#039;tag&#039; ) === tag;&lt;br /&gt;
                } ).length ) { return; }&lt;br /&gt;
&lt;br /&gt;
                var $token = $( &#039;&amp;lt;span&amp;gt;&#039; ).addClass( &#039;tag-token&#039; ).text( tag ).attr( &#039;data-tag&#039;, tag );&lt;br /&gt;
                var $x = $( &#039;&amp;lt;button&amp;gt;&#039; ).attr( &#039;type&#039;, &#039;button&#039; ).addClass( &#039;tag-token-remove&#039; ).text( &#039;\u00d7&#039; );&lt;br /&gt;
                $token.append( $x );&lt;br /&gt;
                $x.on( &#039;click&#039;, function () {&lt;br /&gt;
                    $token.remove();&lt;br /&gt;
                    syncHidden();&lt;br /&gt;
                } );&lt;br /&gt;
                $token.insertBefore( $entry );&lt;br /&gt;
                syncHidden();&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function syncHidden() {&lt;br /&gt;
                var tags = [];&lt;br /&gt;
                $box.find( &#039;.tag-token&#039; ).each( function () {&lt;br /&gt;
                    tags.push( $( this ).data( &#039;tag&#039; ) );&lt;br /&gt;
                } );&lt;br /&gt;
                $input.val( tags.join( &#039;, &#039; ) );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // ── Autocomplete dropdown ────────────────────────────────────────&lt;br /&gt;
            function showDropdown( query ) {&lt;br /&gt;
                var existing = [];&lt;br /&gt;
                $box.find( &#039;.tag-token&#039; ).each( function () {&lt;br /&gt;
                    existing.push( $( this ).data( &#039;tag&#039; ) );&lt;br /&gt;
                } );&lt;br /&gt;
&lt;br /&gt;
                var matches = allTags.filter( function ( t ) {&lt;br /&gt;
                    return t.indexOf( query ) === 0 &amp;amp;&amp;amp; existing.indexOf( t ) === -1;&lt;br /&gt;
                } ).slice( 0, 8 );&lt;br /&gt;
&lt;br /&gt;
                $dropdown.empty();&lt;br /&gt;
                if ( !matches.length ) { $dropdown.hide(); return; }&lt;br /&gt;
&lt;br /&gt;
                matches.forEach( function ( tag ) {&lt;br /&gt;
                    $( &#039;&amp;lt;li&amp;gt;&#039; ).text( tag ).on( &#039;mousedown&#039;, function ( e ) {&lt;br /&gt;
                        e.preventDefault(); // keep focus in $entry&lt;br /&gt;
                        addToken( tag );&lt;br /&gt;
                        $entry.val( &#039;&#039; );&lt;br /&gt;
                        $dropdown.hide();&lt;br /&gt;
                    } ).appendTo( $dropdown );&lt;br /&gt;
                } );&lt;br /&gt;
                $dropdown.show();&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // ── Events ───────────────────────────────────────────────────────&lt;br /&gt;
            $entry.on( &#039;input&#039;, function () {&lt;br /&gt;
                var val = $entry.val();&lt;br /&gt;
                // Comma or space after a word = commit tag&lt;br /&gt;
                if ( /[,]$/.test( val ) ) {&lt;br /&gt;
                    addToken( val.replace( /,$/, &#039;&#039; ) );&lt;br /&gt;
                    $entry.val( &#039;&#039; );&lt;br /&gt;
                    $dropdown.hide();&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                var q = val.trim().toLowerCase();&lt;br /&gt;
                if ( q.length &amp;gt;= 1 ) { showDropdown( q ); } else { $dropdown.hide(); }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            $entry.on( &#039;keydown&#039;, function ( e ) {&lt;br /&gt;
                // Enter = commit current text or first suggestion&lt;br /&gt;
                if ( e.key === &#039;Enter&#039; ) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    var first = $dropdown.find( &#039;li&#039; ).first().text();&lt;br /&gt;
                    addToken( first || $entry.val() );&lt;br /&gt;
                    $entry.val( &#039;&#039; );&lt;br /&gt;
                    $dropdown.hide();&lt;br /&gt;
                }&lt;br /&gt;
                // Backspace on empty entry = remove last token&lt;br /&gt;
                if ( e.key === &#039;Backspace&#039; &amp;amp;&amp;amp; $entry.val() === &#039;&#039; ) {&lt;br /&gt;
                    $box.find( &#039;.tag-token&#039; ).last().remove();&lt;br /&gt;
                    syncHidden();&lt;br /&gt;
                }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            $entry.on( &#039;blur&#039;, function () {&lt;br /&gt;
                setTimeout( function () { $dropdown.hide(); }, 150 );&lt;br /&gt;
                // Commit anything partially typed on blur&lt;br /&gt;
                var val = $entry.val().trim();&lt;br /&gt;
                if ( val ) { addToken( val ); $entry.val( &#039;&#039; ); }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            $box.on( &#039;click&#039;, function () { $entry.trigger( &#039;focus&#039; ); } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
}() );&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Gadgets-definition&amp;diff=1231</id>
		<title>MediaWiki:Gadgets-definition</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Gadgets-definition&amp;diff=1231"/>
		<updated>2026-04-05T08:51:36Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Adding tag autocomplete&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* tutorials[ResourceLoader|hidden|default|dependencies=mediawiki.api]|tutorials.js&lt;br /&gt;
* projects[ResourceLoader|hidden|default|dependencies=mediawiki.api]|projects.js&lt;br /&gt;
* categories[ResourceLoader|hidden|default|dependencies=mediawiki.api]|categories.js&lt;br /&gt;
* sitenav[ResourceLoader|hidden|default]|sitenav.js&lt;br /&gt;
* guide[ResourceLoader|hidden|default]|guide.js&lt;br /&gt;
* subpagenav[ResourceLoader|hidden|default]|subpagenav.js&lt;br /&gt;
* tagautocomplete[ResourceLoader|hidden|default|dependencies=mediawiki.api]|tagautocomplete.js&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Window_Manager_Central&amp;diff=1230</id>
		<title>Projects/Window Manager Central</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Window_Manager_Central&amp;diff=1230"/>
		<updated>2026-04-05T05:14:03Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Added an icon as your cover image so that it wouldn&amp;#039;t just show blank on the project hub. Obviously feel free to change or remove it if you like.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProjectMeta&lt;br /&gt;
| name = Window Manager Central&lt;br /&gt;
| status = Active&lt;br /&gt;
| description = Window Manager Cenral is small website where you can learn about window managers and hit the ground running with a fast new workflow. Discover guides, tips and resources for all levels of familiarity.&lt;br /&gt;
| website = wmc.codeberg.page&lt;br /&gt;
| repository = https://codeberg.org/wmc/pages-src&lt;br /&gt;
| image = Apps-preferences-system-windows.png&lt;br /&gt;
}}This is a small website project intending to serve as a dictionary of tips for window manager users. The idea is that anyone can upload tips, edit and improve the information available so that newcomers to window managers find it easier to start their journey.&lt;br /&gt;
&lt;br /&gt;
It is particularly difficult for newcomers to find guides, more so with good guides, when things go south the most usual response is to give up on window managers altogether. Having one place (ideally) that points to all the guides that one may need, as well as other sources of interest should facilitate the pain of using a search engine over and over.&lt;br /&gt;
&lt;br /&gt;
The point is not to babysit newcomers, but to point them in the right direction. While experienced users don&#039;t need regular help, they will definitely enjoy having a collection of resources instead of having the usual search engine route. They could find particular pleasure in sharing their own guides and mishaps that newbies will want to avoid.&lt;br /&gt;
&lt;br /&gt;
The website is build with [https://gohugo.io Hugo] and hosted on [https://codeberg.page Codeberg Pages], contributing for people familiar with Git is easy, it is just a pull request away. For other ways of contributing one can get in contact with the team.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1229</id>
		<title>Projects/Amalgam</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1229"/>
		<updated>2026-04-05T05:07:07Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Added &amp;quot;promotional banner&amp;quot; thumbnail&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav|icon=Amalgam_Logo}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【 Images 🔴 No 】 【 Code &amp;amp; Text 🟠 Yes, but see note¹  】&lt;br /&gt;
| details = note¹: Currently the project is largely being developed with AI because I don’t have the skills, patience, or motivation to do it without, quite frankly. Because of this, the code is pretty sloppy. Right now, development is focused on just getting the project up and running so I can try to get other people to play the game. The end goal is to eventually find more skilled individuals to help refactor the project and build it “correctly.” For now, since it’s just me working on it, the project is mainly trying to hold together well enough to become playable. In short: I am using AI, and I don’t mind if others use it for code or text. However, the goal is to move away from AI-generated code over time, or at least use it more carefully with input from experienced programmers.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
|name=Amalgam&lt;br /&gt;
|status=Active&lt;br /&gt;
|license=AGPL-3.0&lt;br /&gt;
|creator=Anthony&lt;br /&gt;
|description=A two player abstract strategy game that requires you to tactically utilize your pieces in conjunction with one another to either eliminate the opponents pieces or carefully get a valuable piece to the other side of the board&lt;br /&gt;
|image=Amalgam_Logo.png&lt;br /&gt;
|tags=boardgame, game, software&lt;br /&gt;
|website=https://greenants.github.io/Amalgam_Webgame&lt;br /&gt;
|repository=https://codeberg.org/AnthonyDavis/Amalgam&lt;br /&gt;
|field1label=Players&lt;br /&gt;
|field1value=2 (two)&lt;br /&gt;
|field2label=Genre&lt;br /&gt;
|field2value=Abstract Strategy&lt;br /&gt;
|field3label=Playability&lt;br /&gt;
|field3value=Demo (Rules work, but BOT player is weak)&lt;br /&gt;
}}&lt;br /&gt;
==Under Development==&lt;br /&gt;
This Project Page is currently under development and is acting as a placeholder until more information is added.&lt;br /&gt;
[[File:Amalgam Banner.webp|alt=Amalgam Board Game, A battle of gemstones. ~30min, 2 players, ages 13+|thumb|One possible variation of a &amp;quot;promotional Cover&amp;quot; or &amp;quot;banner&amp;quot; for Amalgam Board Game.]]&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=File:Amalgam_Banner.webp&amp;diff=1228</id>
		<title>File:Amalgam Banner.webp</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=File:Amalgam_Banner.webp&amp;diff=1228"/>
		<updated>2026-04-05T05:02:25Z</updated>

		<summary type="html">&lt;p&gt;Anthony: A banner for amalgam board game&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
A banner for amalgam board game&lt;br /&gt;
== Licensing ==&lt;br /&gt;
{{CC-BY-SA-4.0}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1227</id>
		<title>Projects/Amalgam</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1227"/>
		<updated>2026-04-05T04:58:18Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Update AIBanner text&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav|icon=Amalgam_Logo}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【 Images 🔴 No 】 【 Code &amp;amp; Text 🟠 Yes, but see note¹  】&lt;br /&gt;
| details = note¹: Currently the project is largely being developed with AI because I don’t have the skills, patience, or motivation to do it without, quite frankly. Because of this, the code is pretty sloppy. Right now, development is focused on just getting the project up and running so I can try to get other people to play the game. The end goal is to eventually find more skilled individuals to help refactor the project and build it “correctly.” For now, since it’s just me working on it, the project is mainly trying to hold together well enough to become playable. In short: I am using AI, and I don’t mind if others use it for code or text. However, the goal is to move away from AI-generated code over time, or at least use it more carefully with input from experienced programmers.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
|name=Amalgam&lt;br /&gt;
|status=Active&lt;br /&gt;
|license=AGPL-3.0&lt;br /&gt;
|creator=Anthony&lt;br /&gt;
|description=A two player abstract strategy game that requires you to tactically utilize your pieces in conjunction with one another to either eliminate the opponents pieces or carefully get a valuable piece to the other side of the board&lt;br /&gt;
|image=Amalgam_Logo.png&lt;br /&gt;
|tags=boardgame, game, software&lt;br /&gt;
|website=https://greenants.github.io/Amalgam_Webgame&lt;br /&gt;
|repository=https://codeberg.org/AnthonyDavis/Amalgam&lt;br /&gt;
|field1label=Players&lt;br /&gt;
|field1value=2 (two)&lt;br /&gt;
|field2label=Genre&lt;br /&gt;
|field2value=Abstract Strategy&lt;br /&gt;
|field3label=Playability&lt;br /&gt;
|field3value=Demo (Rules work, but BOT player is weak)&lt;br /&gt;
}}&lt;br /&gt;
==Under Development==&lt;br /&gt;
This Project Page is currently under development and is acting as a placeholder until more information is added.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Changelog&amp;diff=1226</id>
		<title>Projects/Amalgam/Changelog</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Changelog&amp;diff=1226"/>
		<updated>2026-04-05T04:55:43Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Initialize Placeholder&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Amalgam Change-log ==&lt;br /&gt;
As more people are able to play-test the game, we realize that the rules need to be adjusted. This page is acting as a placeholder to track changes that have been made or that have been flagged for change due unbalanced rules or otherwise.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Story&amp;diff=1225</id>
		<title>Projects/Amalgam/Story</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Story&amp;diff=1225"/>
		<updated>2026-04-05T04:52:46Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Initialize Placeholder&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== The Long Journey of Trying to Make Amalgam ==&lt;br /&gt;
This page is a placeholder to insert the &amp;quot;story&amp;quot; and background on trying to create this board game for more than a decade.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Contributors&amp;diff=1224</id>
		<title>Projects/Amalgam/Contributors</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Contributors&amp;diff=1224"/>
		<updated>2026-04-05T04:50:27Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Initialize Placeholder&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Contributors ==&lt;br /&gt;
This page is a placeholder for all contributors who worked on this project over time.&lt;br /&gt;
&lt;br /&gt;
As members contribute to the project, they should come and add their name to this page with their contributions.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Documentation&amp;diff=1223</id>
		<title>Projects/Amalgam/Documentation</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Documentation&amp;diff=1223"/>
		<updated>2026-04-05T04:48:14Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Initialize Placeholder&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Development Documentation ==&lt;br /&gt;
This page is a placeholder for docs on developing the digital version of the board game.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1222</id>
		<title>Projects/Example Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1222"/>
		<updated>2026-04-05T04:45:01Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Added navbar logo icon&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav|icon=Logo}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【Text 🟢 Yes 】 【 Images 🔴 No 】 【 Code 🟠 Depends* 】&lt;br /&gt;
| details = LLM Generated text and code must be thoroughly reviewed and proofread. . .it should be used as a tool to &#039;&#039;assist&#039;&#039; and enhance your contributions, not replace them. *Code is allowed only if a) it is manually proofread and checked for quality or b) it is used as a temporary proof of concept/demo and is clearly labeled as such.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
| name        = Example Project&lt;br /&gt;
| status      = Completed&lt;br /&gt;
| license     = CC BY-SA 4.0&lt;br /&gt;
| creator     = UnfinishedProjects&lt;br /&gt;
| description = This is an example project. It demonstrates how a project page should be set up.&lt;br /&gt;
| image       = Unfinished Projects Logo x512.png&lt;br /&gt;
| tags        = example, demo, template&lt;br /&gt;
| website     = forum.unfinishedprojects.net&lt;br /&gt;
| repository  = https://codeberg.org/UnfinishedProjects/UnfinishedProjects.net&lt;br /&gt;
| field1label = Current Project Lead&lt;br /&gt;
| field1value = [https://forum.unfinishedprojects.net/user/unfinishedprojects UnfinishedProjects]&lt;br /&gt;
| field2label = Contributors&lt;br /&gt;
| field2value = [https://forum.unfinishedprojects.net/user/anthony Anthony], [https://forum.unfinishedprojects.net/user/www-gem www-gem], [https://forum.unfinishedprojects.net/user/alectronic alectronic]&lt;br /&gt;
| field3label = Forked From&lt;br /&gt;
| field3value = [[Example Page| Another Project (Creator Name)]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Animi et et quis ut totam inventore. Eligendi est ut ullam voluptatibus dolorum ex. In quisquam est enim soluta distinctio explicabo quidem voluptatem. Maxime neque dolor id in sunt quisquam quos.&lt;br /&gt;
&lt;br /&gt;
Maiores in dolores laborum molestiae possimus. Ipsum ut et rerum. Neque et perspiciatis eaque autem unde molestias omnis voluptatem.&lt;br /&gt;
&lt;br /&gt;
Aspernatur ut non impedit ea natus eveniet distinctio. Perferendis non eveniet in nihil aut. Quo aut atque natus quisquam laboriosam.&lt;br /&gt;
&lt;br /&gt;
Dolor cumque sed quia quia quis debitis minus ipsa. Veniam recusandae voluptatem quia aut possimus veritatis. Omnis dolores unde quibusdam fugit officiis fugiat. Porro vel qui quia sequi enim nesciunt at. Omnis consequatur veniam quisquam numquam.&lt;br /&gt;
&lt;br /&gt;
Suscipit ipsum impedit reprehenderit magni asperiores tempore tenetur. Id consequatur aut earum voluptas autem qui. Cum laboriosam suscipit est autem non voluptatem aut. Quae error repellendus libero aliquam. Quod quia atque qui doloremque est cupiditate libero. Necessitatibus illum provident et.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1221</id>
		<title>Projects/Amalgam</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1221"/>
		<updated>2026-04-05T04:44:30Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Added Navbar Logo Icon&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav|icon=Amalgam_Logo}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【 Images 🔴 No 】 【 Code &amp;amp; Text 🟠 Yes, but see note¹  】&lt;br /&gt;
| details = note¹: The project is currently being developed largely with AI because I didn’t have the skills, patience, or motivation to do it without it. Because of this, the code is pretty sloppy. Right now, development is focused on just getting the project up and running so I can try to get other people to play the game. The end goal is to eventually find more skilled individuals to help refactor the project and build it “correctly.” For now, since it’s just me working on it, the project is mainly trying to hold together well enough to become playable. In short: I am using AI, and I don’t mind if others use it for code or text. However, the goal is to move away from AI-generated code over time, or at least use it more carefully with input from experienced programmers.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
|name=Amalgam&lt;br /&gt;
|status=Active&lt;br /&gt;
|license=AGPL-3.0&lt;br /&gt;
|creator=Anthony&lt;br /&gt;
|description=A two player abstract strategy game that requires you to tactically utilize your pieces in conjunction with one another to either eliminate the opponents pieces or carefully get a valuable piece to the other side of the board&lt;br /&gt;
|image=Amalgam_Logo.png&lt;br /&gt;
|tags=boardgame, game, software&lt;br /&gt;
|website=https://greenants.github.io/Amalgam_Webgame&lt;br /&gt;
|repository=https://codeberg.org/AnthonyDavis/Amalgam&lt;br /&gt;
|field1label=Players&lt;br /&gt;
|field1value=2 (two)&lt;br /&gt;
|field2label=Genre&lt;br /&gt;
|field2value=Abstract Strategy&lt;br /&gt;
|field3label=Playability&lt;br /&gt;
|field3value=Demo (Rules work, but BOT player is weak)&lt;br /&gt;
}}&lt;br /&gt;
==Under Development==&lt;br /&gt;
This Project Page is currently under development and is acting as a placeholder until more information is added.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Template:SubpageNav&amp;diff=1220</id>
		<title>Template:SubpageNav</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Template:SubpageNav&amp;diff=1220"/>
		<updated>2026-04-05T04:38:16Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Fixed nav showing all projects (hopefully)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;templatestyles src=&amp;quot;Template:SubpageNav/styles.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;subpage-nav-wrapper&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;subpage-nav&amp;quot; role=&amp;quot;navigation&amp;quot; aria-label=&amp;quot;{{#titleparts:{{PAGENAME}}|2}} navigation&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;subpage-nav-brand&amp;quot;&amp;gt;{{#if:{{{icon|}}}|[[File:{{{icon}}}.png|20px|link={{{root|{{#titleparts:{{PAGENAME}}|2}}}}}]]|}}&amp;lt;span class=&amp;quot;subpage-nav-title&amp;quot;&amp;gt;[[{{{root|{{#titleparts:{{PAGENAME}}|2}}}}}|{{{name|{{#if:{{#titleparts:{{PAGENAME}}|1|2}}|{{#titleparts:{{PAGENAME}}|1|2}}|{{PAGENAME}}}}}}}]]&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;subpage-nav-links&amp;quot;&amp;gt;{{#if:{{{1|}}}| {{{1}}}|&amp;lt;div class=&amp;quot;subpage-auto-list&amp;quot;&amp;gt;{{Special:PrefixIndex/{{{root|{{#titleparts:{{PAGENAME}}|2}}}}}/ |stripprefix=1}}&amp;lt;/div&amp;gt;}}&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
== SubpageNav ==&lt;br /&gt;
A compact, minimal horizontal navigation bar. Works on root pages and any depth of subpage. Auto-populates all subpages with full dropdown support for nested paths.&lt;br /&gt;
&lt;br /&gt;
=== Basic Usage ===&lt;br /&gt;
Drop this at the top of any project or tutorial page:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{SubpageNav}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Works on the root page and any subpage depth. On &amp;lt;code&amp;gt;Example Project/About/More Details&amp;lt;/code&amp;gt; the nav correctly shows &amp;lt;code&amp;gt;Example Project&amp;lt;/code&amp;gt; as the brand and lists all of its subpages.&lt;br /&gt;
&lt;br /&gt;
=== With an Icon ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{SubpageNav|icon=emotes-face-smile-big}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Manual List ===&lt;br /&gt;
Pass a bulleted wikitext list as the first parameter. Nesting with &amp;lt;code&amp;gt;**&amp;lt;/code&amp;gt; creates dropdown menus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{SubpageNav|&lt;br /&gt;
* [[My Project/Overview|Overview]]&lt;br /&gt;
** [[My Project/Overview/Details|Details]]&lt;br /&gt;
* [[My Project/Gallery|Gallery]]&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
; &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; : Optional manual wikitext list. If omitted, auto-populates via Special:PrefixIndex.&lt;br /&gt;
; &amp;lt;code&amp;gt;icon&amp;lt;/code&amp;gt; : Icon filename without &amp;lt;code&amp;gt;File:&amp;lt;/code&amp;gt; prefix or &amp;lt;code&amp;gt;.png&amp;lt;/code&amp;gt; extension.&lt;br /&gt;
; &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; : Override the root page (defaults to &amp;lt;code&amp;gt;{{ROOTPAGENAME}}&amp;lt;/code&amp;gt;).&lt;br /&gt;
; &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; : Override the brand label in the nav bar.&lt;br /&gt;
&lt;br /&gt;
=== Technical Notes ===&lt;br /&gt;
* Styles: [[Template:SubpageNav/styles.css]]&lt;br /&gt;
* Dropdown &amp;amp; nesting: [[MediaWiki:Gadget-subpagenav.js]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;templatedata&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Adds a compact horizontal subpage navigation bar. Auto-detects all subpages and builds dropdown menus for nested paths. Works correctly from any depth of subpage.&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
        &amp;quot;1&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Manual link list&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Optional. A bulleted wikitext list of links. Nesting with ** creates dropdown menus. If omitted, subpages are auto-detected.&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;icon&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Icon&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Icon filename without File: prefix or .png extension (e.g. emotes-face-smile-big).&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;root&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Root page&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Override the root page used for the brand link and subpage lookup. Defaults to {{ROOTPAGENAME}}.&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;wiki-page-name&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;name&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Display name&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Override the brand label shown in the nav bar. Defaults to the root page name.&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;format&amp;quot;: &amp;quot;inline&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/templatedata&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Rulebook&amp;diff=1219</id>
		<title>Projects/Amalgam/Rulebook</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam/Rulebook&amp;diff=1219"/>
		<updated>2026-04-05T04:32:21Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Initialize Placeholder&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Amalgam Rules ==&lt;br /&gt;
This page is a placeholder for the game-play rules.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1218</id>
		<title>Projects/Amalgam</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1218"/>
		<updated>2026-04-05T04:29:47Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Added AIBanner and &amp;quot;Under Development&amp;quot;. Current Edit will act as a placeholder until I get more time to flesh out the project page(s)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【 Images 🔴 No 】 【 Code &amp;amp; Text 🟠 Yes, but see note¹  】&lt;br /&gt;
| details = note¹: The project is currently being developed largely with AI because I didn’t have the skills, patience, or motivation to do it without it. Because of this, the code is pretty sloppy. Right now, development is focused on just getting the project up and running so I can try to get other people to play the game. The end goal is to eventually find more skilled individuals to help refactor the project and build it “correctly.” For now, since it’s just me working on it, the project is mainly trying to hold together well enough to become playable. In short: I am using AI, and I don’t mind if others use it for code or text. However, the goal is to move away from AI-generated code over time, or at least use it more carefully with input from experienced programmers.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
|name=Amalgam&lt;br /&gt;
|status=Active&lt;br /&gt;
|license=AGPL-3.0&lt;br /&gt;
|creator=Anthony&lt;br /&gt;
|description=A two player abstract strategy game that requires you to tactically utilize your pieces in conjunction with one another to either eliminate the opponents pieces or carefully get a valuable piece to the other side of the board&lt;br /&gt;
|image=Amalgam_Logo.png&lt;br /&gt;
|tags=boardgame, game, software&lt;br /&gt;
|website=https://greenants.github.io/Amalgam_Webgame&lt;br /&gt;
|repository=https://codeberg.org/AnthonyDavis/Amalgam&lt;br /&gt;
|field1label=Players&lt;br /&gt;
|field1value=2 (two)&lt;br /&gt;
|field2label=Genre&lt;br /&gt;
|field2value=Abstract Strategy&lt;br /&gt;
|field3label=Playability&lt;br /&gt;
|field3value=Demo (Rules work, but BOT player is weak)&lt;br /&gt;
}}&lt;br /&gt;
==Under Development==&lt;br /&gt;
This Project Page is currently under development and is acting as a placeholder until more information is added.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1217</id>
		<title>Projects/Amalgam</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Amalgam&amp;diff=1217"/>
		<updated>2026-04-05T04:16:16Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Created page with &amp;quot;{{ProjectMeta |name=Amalgam |status=Active |license=AGPL-3.0 |creator=Anthony |description=A two player abstract strategy game that requires you to tactically utilize your pieces in conjunction with one another to either eliminate the opponents pieces or carefully get a valuable piece to the other side of the board |image=amalgam_logo.png |tags=boardgame, game, software |website=https://greenants.github.io/Amalgam_Webgame |repository=https://codeberg.org/AnthonyDavis/Ama...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProjectMeta&lt;br /&gt;
|name=Amalgam&lt;br /&gt;
|status=Active&lt;br /&gt;
|license=AGPL-3.0&lt;br /&gt;
|creator=Anthony&lt;br /&gt;
|description=A two player abstract strategy game that requires you to tactically utilize your pieces in conjunction with one another to either eliminate the opponents pieces or carefully get a valuable piece to the other side of the board&lt;br /&gt;
|image=amalgam_logo.png&lt;br /&gt;
|tags=boardgame, game, software&lt;br /&gt;
|website=https://greenants.github.io/Amalgam_Webgame&lt;br /&gt;
|repository=https://codeberg.org/AnthonyDavis/Amalgam&lt;br /&gt;
|field1label=Players&lt;br /&gt;
|field1value=2 (two)&lt;br /&gt;
|field2label=Genre&lt;br /&gt;
|field2value=Abstract Strategy&lt;br /&gt;
|field3label=Playability&lt;br /&gt;
|field3value=Demo (Rules work, but BOT player is weak)&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1216</id>
		<title>Projects/Example Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1216"/>
		<updated>2026-04-05T02:31:28Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Missing a space after the comma&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【Text 🟢 Yes 】 【 Images 🔴 No 】 【 Code 🟠 Depends* 】&lt;br /&gt;
| details = LLM Generated text and code must be thoroughly reviewed and proofread. . .it should be used as a tool to &#039;&#039;assist&#039;&#039; and enhance your contributions, not replace them. *Code is allowed only if a) it is manually proofread and checked for quality or b) it is used as a temporary proof of concept/demo and is clearly labeled as such.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
| name        = Example Project&lt;br /&gt;
| status      = Completed&lt;br /&gt;
| license     = CC BY-SA 4.0&lt;br /&gt;
| creator     = UnfinishedProjects&lt;br /&gt;
| description = This is an example project. It demonstrates how a project page should be set up.&lt;br /&gt;
| image       = Unfinished Projects Logo x512.png&lt;br /&gt;
| tags        = example, demo, template&lt;br /&gt;
| website     = forum.unfinishedprojects.net&lt;br /&gt;
| repository  = https://codeberg.org/UnfinishedProjects/UnfinishedProjects.net&lt;br /&gt;
| field1label = Current Project Lead&lt;br /&gt;
| field1value = [https://forum.unfinishedprojects.net/user/unfinishedprojects UnfinishedProjects]&lt;br /&gt;
| field2label = Contributors&lt;br /&gt;
| field2value = [https://forum.unfinishedprojects.net/user/anthony Anthony], [https://forum.unfinishedprojects.net/user/www-gem www-gem], [https://forum.unfinishedprojects.net/user/alectronic alectronic]&lt;br /&gt;
| field3label = Forked From&lt;br /&gt;
| field3value = [[Example Page| Another Project (Creator Name)]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Animi et et quis ut totam inventore. Eligendi est ut ullam voluptatibus dolorum ex. In quisquam est enim soluta distinctio explicabo quidem voluptatem. Maxime neque dolor id in sunt quisquam quos.&lt;br /&gt;
&lt;br /&gt;
Maiores in dolores laborum molestiae possimus. Ipsum ut et rerum. Neque et perspiciatis eaque autem unde molestias omnis voluptatem.&lt;br /&gt;
&lt;br /&gt;
Aspernatur ut non impedit ea natus eveniet distinctio. Perferendis non eveniet in nihil aut. Quo aut atque natus quisquam laboriosam.&lt;br /&gt;
&lt;br /&gt;
Dolor cumque sed quia quia quis debitis minus ipsa. Veniam recusandae voluptatem quia aut possimus veritatis. Omnis dolores unde quibusdam fugit officiis fugiat. Porro vel qui quia sequi enim nesciunt at. Omnis consequatur veniam quisquam numquam.&lt;br /&gt;
&lt;br /&gt;
Suscipit ipsum impedit reprehenderit magni asperiores tempore tenetur. Id consequatur aut earum voluptas autem qui. Cum laboriosam suscipit est autem non voluptatem aut. Quae error repellendus libero aliquam. Quod quia atque qui doloremque est cupiditate libero. Necessitatibus illum provident et.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1215</id>
		<title>Projects/Example Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1215"/>
		<updated>2026-04-05T02:30:57Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Fixed contrinbutor spacing in ProjectMeta&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【Text 🟢 Yes 】 【 Images 🔴 No 】 【 Code 🟠 Depends* 】&lt;br /&gt;
| details = LLM Generated text and code must be thoroughly reviewed and proofread. . .it should be used as a tool to &#039;&#039;assist&#039;&#039; and enhance your contributions, not replace them. *Code is allowed only if a) it is manually proofread and checked for quality or b) it is used as a temporary proof of concept/demo and is clearly labeled as such.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
| name        = Example Project&lt;br /&gt;
| status      = Completed&lt;br /&gt;
| license     = CC BY-SA 4.0&lt;br /&gt;
| creator     = UnfinishedProjects&lt;br /&gt;
| description = This is an example project. It demonstrates how a project page should be set up.&lt;br /&gt;
| image       = Unfinished Projects Logo x512.png&lt;br /&gt;
| tags        = example, demo, template&lt;br /&gt;
| website     = forum.unfinishedprojects.net&lt;br /&gt;
| repository  = https://codeberg.org/UnfinishedProjects/UnfinishedProjects.net&lt;br /&gt;
| field1label = Current Project Lead&lt;br /&gt;
| field1value = [https://forum.unfinishedprojects.net/user/unfinishedprojects UnfinishedProjects]&lt;br /&gt;
| field2label = Contributors&lt;br /&gt;
| field2value = [https://forum.unfinishedprojects.net/user/anthony Anthony], [https://forum.unfinishedprojects.net/user/www-gem www-gem],[https://forum.unfinishedprojects.net/user/alectronic alectronic]&lt;br /&gt;
| field3label = Forked From&lt;br /&gt;
| field3value = [[Example Page| Another Project (Creator Name)]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Animi et et quis ut totam inventore. Eligendi est ut ullam voluptatibus dolorum ex. In quisquam est enim soluta distinctio explicabo quidem voluptatem. Maxime neque dolor id in sunt quisquam quos.&lt;br /&gt;
&lt;br /&gt;
Maiores in dolores laborum molestiae possimus. Ipsum ut et rerum. Neque et perspiciatis eaque autem unde molestias omnis voluptatem.&lt;br /&gt;
&lt;br /&gt;
Aspernatur ut non impedit ea natus eveniet distinctio. Perferendis non eveniet in nihil aut. Quo aut atque natus quisquam laboriosam.&lt;br /&gt;
&lt;br /&gt;
Dolor cumque sed quia quia quis debitis minus ipsa. Veniam recusandae voluptatem quia aut possimus veritatis. Omnis dolores unde quibusdam fugit officiis fugiat. Porro vel qui quia sequi enim nesciunt at. Omnis consequatur veniam quisquam numquam.&lt;br /&gt;
&lt;br /&gt;
Suscipit ipsum impedit reprehenderit magni asperiores tempore tenetur. Id consequatur aut earum voluptas autem qui. Cum laboriosam suscipit est autem non voluptatem aut. Quae error repellendus libero aliquam. Quod quia atque qui doloremque est cupiditate libero. Necessitatibus illum provident et.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Anonnotice&amp;diff=1214</id>
		<title>MediaWiki:Anonnotice</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Anonnotice&amp;diff=1214"/>
		<updated>2026-04-05T01:26:14Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Update padding width&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;text-align: center; padding: 12px 20px; border: 1px solid var(--wiki-primary); border-radius: 8px; background: var(--color-surface-1); margin: 15px auto; max-width: 1100px; width: calc(100% - 40px); line-height: 1.5; box-sizing: border-box;&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;div style=&amp;quot;margin-bottom: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;strong style=&amp;quot;color:var(--wiki-primary);&amp;quot;&amp;gt;🚧 True to our name, we’re still a work in progress. 🚧&amp;lt;/strong&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;span style=&amp;quot;font-size: 0.95em;&amp;quot;&amp;gt;&lt;br /&gt;
        You’re welcome to explore, but &amp;lt;strong&amp;gt;account registration is currently invite-only&amp;lt;/strong&amp;gt; as we finalize the setup. &lt;br /&gt;
        Join our &amp;lt;strong&amp;gt;[https://forum.unfinishedprojects.net forum]&amp;lt;/strong&amp;gt; or follow &amp;lt;strong&amp;gt;[https://mastodon.social/@UnfinishedProjects Mastodon]&amp;lt;/strong&amp;gt; for updates. &lt;br /&gt;
        &amp;lt;i style=&amp;quot;opacity: 0.8; margin-left: 5px;&amp;quot;&amp;gt;Full Wiki launch coming soon!&amp;lt;/i&amp;gt;&lt;br /&gt;
    &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Anonnotice&amp;diff=1213</id>
		<title>MediaWiki:Anonnotice</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Anonnotice&amp;diff=1213"/>
		<updated>2026-04-05T01:24:00Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Updated to match forum registration opening&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;text-align: center; padding: 12px 20px; border: 1px solid var(--wiki-primary); border-radius: 8px; background: var(--color-surface-1); margin: 10px 0; line-height: 1.5;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;margin-bottom: 4px;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;strong style=&amp;quot;color:var(--wiki-primary);&amp;quot;&amp;gt;🚧 True to our name, we’re still a work in progress. 🚧&amp;lt;/strong&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;span style=&amp;quot;font-size: 0.95em;&amp;quot;&amp;gt;&lt;br /&gt;
        You’re welcome to explore, but &amp;lt;strong&amp;gt;account registration is currently limited&amp;lt;/strong&amp;gt; as we finalize the setup. &lt;br /&gt;
        Join our &amp;lt;strong&amp;gt;[https://forum.unfinishedprojects.net forum]&amp;lt;/strong&amp;gt; or follow &amp;lt;strong&amp;gt;[https://mastodon.social/@UnfinishedProjects Mastodon]&amp;lt;/strong&amp;gt; for updates. &lt;br /&gt;
        &amp;lt;i style=&amp;quot;opacity: 0.8; margin-left: 5px;&amp;quot;&amp;gt;Full Wiki launch coming soon!&amp;lt;/i&amp;gt;&lt;br /&gt;
    &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Tutorial&amp;diff=1211</id>
		<title>Form:Submit Tutorial</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Tutorial&amp;diff=1211"/>
		<updated>2026-04-05T01:06:53Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Fixing Page redirect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{{info|page name=Tutorials/&amp;lt;TutorialMeta[name]&amp;gt;}}}&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{SubpageNav| icon=emotes-face-smile-big}}&lt;br /&gt;
&lt;br /&gt;
{{{for template|TutorialMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Tutorial Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Tutorial Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown on hover over the tutorial card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, beginner, recording}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Tutorial}}} {{{standard input|cancel}}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Template:HubHeader&amp;diff=1209</id>
		<title>Template:HubHeader</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Template:HubHeader&amp;diff=1209"/>
		<updated>2026-04-05T01:03:59Z</updated>

		<summary type="html">&lt;p&gt;Anthony: FormStart to FormEdit to fix Pages posting to root&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;hub-container&amp;quot; style=&amp;quot;margin-bottom: 24px;&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;hub-header-minimal&amp;quot; style=&amp;quot;background: var(--color-surface-1); border: 1px solid var(--border-color-base); border-radius: 4px 4px 0 0; padding: 24px; text-align: left; border-bottom: none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;flex: 1; min-width: 300px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;font-size: 1.8em; font-weight: 800; color: var(--color-base); margin-bottom: 4px; letter-spacing: -0.01em;&amp;quot;&amp;gt;{{{title|Title Text}}}&amp;lt;/div&amp;gt;&amp;lt;div style=&amp;quot;font-size: 0.9em; color: var(--wiki-primary); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 12px;&amp;quot;&amp;gt;{{{subtitle|Subtitle Text}}}&amp;lt;/div&amp;gt;&amp;lt;div style=&amp;quot;font-size: 1em; color: var(--color-base); line-height: 1.6; max-width: 850px; opacity: 0.9;&amp;quot;&amp;gt;{{{description|}}}&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;{{#if:{{{category|}}}|&amp;lt;div style=&amp;quot;background: var(--color-surface-2); border: 1px solid var(--border-color-base); padding: 16px 24px; border-radius: 4px; text-align: center; min-width: 140px; box-shadow: inset 0 1px 2px rgba(0,0,0,0.03); flex-shrink: 0;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;font-size: 0.7em; text-transform: uppercase; font-weight: 800; color: var(--color-base--subtle); letter-spacing: 0.08em; margin-bottom: 4px;&amp;quot;&amp;gt;{{{count_label|Projects}}}&amp;lt;/div&amp;gt;&amp;lt;div style=&amp;quot;font-size: 2em; font-weight: 900; color: var(--color-base); line-height: 1;&amp;quot;&amp;gt;{{PAGESINCATEGORY:{{{category}}}|pages}}&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;|}}&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;hub-banner&amp;quot; style=&amp;quot;background: var(--color-surface-1); border: 1px solid var(--border-color-base); border-radius: 0 0 4px 4px; padding: 0; overflow: hidden;&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;hub-toolbar&amp;quot; style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); width: 100%; border-top: 1px solid var(--border-color-base); box-sizing: border-box;&amp;quot;&amp;gt;{{#if:{{{submit_form|}}}|[[Special:FormEdit/{{{submit_form|}}}|&amp;lt;span style=&amp;quot;display: flex; align-items: center; justify-content: center; height: 100%; background: var(--wiki-primary); color: #fff; padding: 12px 6px; font-size: 0.75em; font-weight: 700; text-align: center; text-transform: uppercase; border-right: 1px solid var(--border-color-base); letter-spacing: 0.05em; box-sizing: border-box;&amp;quot;&amp;gt;+ Submit&amp;lt;/span&amp;gt;]]|}} [[:Category:{{{category|{{PAGENAME}}}}}|&amp;lt;span style=&amp;quot;display: flex; align-items: center; justify-content: center; height: 100%; background: var(--color-surface-2); color: var(--color-base); padding: 12px 6px; font-size: 0.75em; font-weight: 700; text-align: center; text-transform: uppercase; border-right: 1px solid var(--border-color-base); letter-spacing: 0.05em; box-sizing: border-box;&amp;quot;&amp;gt;Full Index&amp;lt;/span&amp;gt;]] [[Guidebook/Quick Start/Projects|&amp;lt;span style=&amp;quot;display: flex; align-items: center; justify-content: center; height: 100%; background: var(--color-surface-2); color: var(--color-base); padding: 12px 6px; font-size: 0.75em; font-weight: 700; text-align: center; text-transform: uppercase; border-right: 1px solid var(--border-color-base); letter-spacing: 0.05em; box-sizing: border-box;&amp;quot;&amp;gt;Submission Rules&amp;lt;/span&amp;gt;]] [[MediaWiki:Licenses|&amp;lt;span style=&amp;quot;display: flex; align-items: center; justify-content: center; height: 100%; background: var(--color-surface-2); color: var(--color-base); padding: 12px 6px; font-size: 0.75em; font-weight: 700; text-align: center; text-transform: uppercase; border-right: 1px solid var(--border-color-base); letter-spacing: 0.05em; box-sizing: border-box;&amp;quot;&amp;gt;License Options&amp;lt;/span&amp;gt;]] [[{{TALKPAGENAME}}|&amp;lt;span style=&amp;quot;display: flex; align-items: center; justify-content: center; height: 100%; background: var(--color-surface-2); color: var(--color-base); padding: 12px 6px; font-size: 0.75em; font-weight: 700; text-align: center; text-transform: uppercase; border-right: 1px solid var(--border-color-base); letter-spacing: 0.05em; box-sizing: border-box;&amp;quot;&amp;gt;Moderators&amp;lt;/span&amp;gt;]] [[Special:PrefixIndex/Template:{{{hub_type|Project}}}|&amp;lt;span style=&amp;quot;display: flex; align-items: center; justify-content: center; height: 100%; background: var(--color-surface-2); color: var(--color-base); padding: 12px 6px; font-size: 0.75em; font-weight: 700; text-align: center; text-transform: uppercase; border-right: 1px solid var(--border-color-base); letter-spacing: 0.05em; box-sizing: border-box;&amp;quot;&amp;gt;Templates&amp;lt;/span&amp;gt;]] [[About|&amp;lt;span style=&amp;quot;display: flex; align-items: center; justify-content: center; height: 100%; background: var(--color-surface-2); color: var(--color-base); padding: 12px 6px; font-size: 0.75em; font-weight: 700; text-align: center; text-transform: uppercase; border: none; letter-spacing: 0.05em; box-sizing: border-box;&amp;quot;&amp;gt;About&amp;lt;/span&amp;gt;]]&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;hub-metadata&amp;quot; style=&amp;quot;display: flex; flex-wrap: wrap; gap: 24px; font-size: 0.82em; align-items: center; border-top: 1px solid var(--border-color-base); padding: 14px 24px; background: var(--color-surface-1);&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;color: var(--color-base);&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;font-weight: 800; text-transform: uppercase; margin-right: 8px; letter-spacing: 0.05em; opacity: 0.7;&amp;quot;&amp;gt;Last Submission&amp;lt;/span&amp;gt;&amp;lt;span id=&amp;quot;hub-meta-last-submission&amp;quot; style=&amp;quot;color: #007bff; font-weight: 700;&amp;quot;&amp;gt;Loading...&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style=&amp;quot;color: var(--color-base);&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;font-weight: 800; text-transform: uppercase; margin-right: 8px; letter-spacing: 0.05em; opacity: 0.7;&amp;quot;&amp;gt;Activity&amp;lt;/span&amp;gt;&amp;lt;span id=&amp;quot;hub-meta-last-edit&amp;quot; style=&amp;quot;color: var(--wiki-primary); font-weight: 700;&amp;quot;&amp;gt;Loading...&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
== HubHeader ==&lt;br /&gt;
Displays the full header block for project and tutorial hub pages. Includes a title/subtitle/description area, optional live count badge, toolbar row with a Submit button and navigation links, and a metadata bar showing default license and live activity (populated by [[MediaWiki:Gadget-projects.js]] or [[MediaWiki:Gadget-tutorials.js]]).&lt;br /&gt;
&lt;br /&gt;
=== Usage — Projects hub ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{HubHeader&lt;br /&gt;
| title       = Audio Projects&lt;br /&gt;
| subtitle    = Music, sound design, and anything audio&lt;br /&gt;
| description = Any openly licensed audio project — sound FX, music, field recordings, podcasts, etc.&lt;br /&gt;
| category    = Projects/Audio&lt;br /&gt;
| count_label = Audio Projects&lt;br /&gt;
| submit_form = Submit_Project&lt;br /&gt;
| hub_path    = Projects/Audio&lt;br /&gt;
| hub_type    = ProjectCard&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Usage — Tutorials hub ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{HubHeader&lt;br /&gt;
| title       = Community Tutorials&lt;br /&gt;
| subtitle    = Step-by-step guides written by the community&lt;br /&gt;
| description = Browse tutorials by topic below.&lt;br /&gt;
| category    = Tutorials&lt;br /&gt;
| count_label = Tutorials&lt;br /&gt;
| submit_form = Submit_Tutorial&lt;br /&gt;
| hub_path    = Tutorials&lt;br /&gt;
| hub_type    = TutorialCard&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
; &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; : Main heading. Defaults to &amp;quot;Title Text&amp;quot;.&lt;br /&gt;
; &amp;lt;code&amp;gt;subtitle&amp;lt;/code&amp;gt; : Orange uppercase subtitle. Defaults to &amp;quot;Subtitle Text&amp;quot;.&lt;br /&gt;
; &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; : Optional body paragraph below the subtitle.&lt;br /&gt;
; &amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt; : If provided, shows a live count badge using &amp;lt;code&amp;gt;PAGESINCATEGORY&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;Projects/Audio&amp;lt;/code&amp;gt;).&lt;br /&gt;
; &amp;lt;code&amp;gt;count_label&amp;lt;/code&amp;gt; : Label above the count badge. Defaults to &amp;quot;Projects&amp;quot;.&lt;br /&gt;
; &amp;lt;code&amp;gt;submit_form&amp;lt;/code&amp;gt; : If provided, adds an orange &amp;quot;+ Submit&amp;quot; button linking to &amp;lt;code&amp;gt;Special:FormStart/FormName&amp;lt;/code&amp;gt;.&lt;br /&gt;
; &amp;lt;code&amp;gt;hub_path&amp;lt;/code&amp;gt; : Path for the &amp;quot;Full Index&amp;quot; button. Defaults to current page name.&lt;br /&gt;
; &amp;lt;code&amp;gt;hub_type&amp;lt;/code&amp;gt; : Template name for the &amp;quot;Templates&amp;quot; toolbar button. Defaults to &amp;quot;Project&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
* &amp;quot;Last Submission&amp;quot; and &amp;quot;Activity&amp;quot; in the metadata bar are populated by JavaScript gadgets.&lt;br /&gt;
* The toolbar links to [[Project:Submission Guidelines]], [[Project:Licenses]], the page&#039;s talk page, and [[Project:Community]] — create these pages to avoid red links.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;templatedata&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Displays the full header block for a project or tutorial hub page, including title, count badge, toolbar, and a live metadata bar.&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
        &amp;quot;title&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Title&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Main heading for the hub page.&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
            &amp;quot;default&amp;quot;: &amp;quot;Title Text&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;subtitle&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Subtitle&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Orange uppercase subtitle shown below the title.&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
            &amp;quot;default&amp;quot;: &amp;quot;Subtitle Text&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;description&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Description&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Optional body paragraph below the subtitle. Supports wikitext.&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;category&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Category&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Category name for the live count badge (e.g. Projects/Audio).&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;count_label&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Count label&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Label shown above the count badge.&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
            &amp;quot;default&amp;quot;: &amp;quot;Projects&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;submit_form&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Submit form&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;PageForms form name for the orange Submit button (e.g. Submit_Project or Submit_Tutorial).&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
            &amp;quot;suggestedvalues&amp;quot;: [&amp;quot;Submit_Project&amp;quot;, &amp;quot;Submit_Tutorial&amp;quot;],&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;hub_path&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Hub path&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Path used for the Full Index toolbar button. Defaults to the current page name.&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;wiki-page-name&amp;quot;,&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;hub_type&amp;quot;: {&lt;br /&gt;
            &amp;quot;label&amp;quot;: &amp;quot;Hub type&amp;quot;,&lt;br /&gt;
            &amp;quot;description&amp;quot;: &amp;quot;Template name linked in the Templates toolbar button.&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
            &amp;quot;default&amp;quot;: &amp;quot;Project&amp;quot;,&lt;br /&gt;
            &amp;quot;suggestedvalues&amp;quot;: [&amp;quot;ProjectCard&amp;quot;, &amp;quot;TutorialCard&amp;quot;],&lt;br /&gt;
            &amp;quot;required&amp;quot;: false&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;format&amp;quot;: &amp;quot;block&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/templatedata&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Layout Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Window_Manager_Central&amp;diff=1208</id>
		<title>Window Manager Central</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Window_Manager_Central&amp;diff=1208"/>
		<updated>2026-04-05T01:01:07Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Anthony moved page Window Manager Central to Projects/Window Manager Central: Moved page due to broken form submission that posts the project to the root. It should be nested under /wiki/Projects/&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Projects/Window Manager Central]]&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Window_Manager_Central&amp;diff=1207</id>
		<title>Projects/Window Manager Central</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Window_Manager_Central&amp;diff=1207"/>
		<updated>2026-04-05T01:01:07Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Anthony moved page Window Manager Central to Projects/Window Manager Central: Moved page due to broken form submission that posts the project to the root. It should be nested under /wiki/Projects/&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProjectMeta&lt;br /&gt;
|name=Window Manager Central&lt;br /&gt;
|status=Active&lt;br /&gt;
|description=Window Manager Cenral is small website where you can learn about window managers and hit the ground running with a fast new workflow. Discover guides, tips and resources for all levels of familiarity.&lt;br /&gt;
|website=wmc.codeberg.page&lt;br /&gt;
|repository=https://codeberg.org/wmc/pages-src&lt;br /&gt;
}}This is a small website project intending to serve as a dictionary of tips for window manager users. The idea is that anyone can upload tips, edit and improve the information available so that newcomers to window managers find it easier to start their journey.&lt;br /&gt;
&lt;br /&gt;
It is particularly difficult for newcomers to find guides, more so with good guides, when things go south the most usual response is to give up on window managers altogether. Having one place (ideally) that points to all the guides that one may need, as well as other sources of interest should facilitate the pain of using a search engine over and over.&lt;br /&gt;
&lt;br /&gt;
The point is not to babysit newcomers, but to point them in the right direction. While experienced users don&#039;t need regular help, they will definitely enjoy having a collection of resources instead of having the usual search engine route. They could find particular pleasure in sharing their own guides and mishaps that newbies will want to avoid.&lt;br /&gt;
&lt;br /&gt;
The website is build with [https://gohugo.io Hugo] and hosted on [https://codeberg.page Codeberg Pages], contributing for people familiar with Git is easy, it is just a pull request away. For other ways of contributing one can get in contact with the team.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-projects.js&amp;diff=1205</id>
		<title>MediaWiki:Gadget-projects.js</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-projects.js&amp;diff=1205"/>
		<updated>2026-04-05T00:56:20Z</updated>

		<summary type="html">&lt;p&gt;Anthony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   Gadget-projects.js  v2.1&lt;br /&gt;
   Unified project hub — API-powered search, tag/licence filtering, pagination.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
( function () {&lt;br /&gt;
&lt;br /&gt;
    if ( mw.config.get( &#039;wgPageName&#039; ) !== &#039;Projects&#039; ) { return; }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
&lt;br /&gt;
        var PAGE_SIZE  = 24;&lt;br /&gt;
        var generation = 0; // Incremented on every new search to discard stale responses&lt;br /&gt;
&lt;br /&gt;
        var state = {&lt;br /&gt;
            search  : &#039;&#039;,&lt;br /&gt;
            tag     : &#039;&#039;,&lt;br /&gt;
            license : &#039;&#039;,&lt;br /&gt;
            sort    : &#039;newest&#039;,&lt;br /&gt;
            offset  : 0,&lt;br /&gt;
            done    : false,&lt;br /&gt;
            busy    : false&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var $wrapper = $( &#039;.project-hub-wrapper&#039; );&lt;br /&gt;
        if ( !$wrapper.length ) { return; }&lt;br /&gt;
&lt;br /&gt;
        var $filters      = $wrapper.find( &#039;.project-hub-filters&#039; );&lt;br /&gt;
        var $tagCloud     = $wrapper.find( &#039;.project-hub-tagcloud&#039; );&lt;br /&gt;
        var $licenseCloud = $wrapper.find( &#039;.project-hub-licensecloud&#039; );&lt;br /&gt;
        var $grid         = $wrapper.find( &#039;.project-hub-grid&#039; );&lt;br /&gt;
        var $count        = $( &#039;&amp;lt;span&amp;gt;&#039; ).addClass( &#039;project-hub-count&#039; );&lt;br /&gt;
&lt;br /&gt;
        // Create the Load More button entirely in JS.&lt;br /&gt;
        // &amp;lt;button&amp;gt; tags are stripped by the MediaWiki HTML sanitiser if placed in wikitext.&lt;br /&gt;
        var $more = $( &#039;&amp;lt;button&amp;gt;&#039; )&lt;br /&gt;
            .addClass( &#039;project-hub-loadmore&#039; )&lt;br /&gt;
            .text( &#039;Load more projects&#039; )&lt;br /&gt;
            .hide()&lt;br /&gt;
            .appendTo( $wrapper );&lt;br /&gt;
&lt;br /&gt;
        // ── Filter bar ────────────────────────────────────────────────────────&lt;br /&gt;
        var $search = $( &#039;&amp;lt;input&amp;gt;&#039; ).attr( {&lt;br /&gt;
            type        : &#039;text&#039;,&lt;br /&gt;
            placeholder : &#039;Search name, creator, license, tags, description\u2026&#039;,&lt;br /&gt;
            &#039;class&#039;     : &#039;project-hub-search&#039;&lt;br /&gt;
        } );&lt;br /&gt;
        var $sort = $( &#039;&amp;lt;select&amp;gt;&#039; ).addClass( &#039;project-hub-select&#039; ).append(&lt;br /&gt;
            $( &#039;&amp;lt;option&amp;gt;&#039; ).val( &#039;newest&#039; ).text( &#039;Newest first&#039; ),&lt;br /&gt;
            $( &#039;&amp;lt;option&amp;gt;&#039; ).val( &#039;alpha&#039;  ).text( &#039;A \u2013 Z&#039; )&lt;br /&gt;
        );&lt;br /&gt;
        $filters.append( $search, $sort, $count );&lt;br /&gt;
&lt;br /&gt;
        // ── Events ────────────────────────────────────────────────────────────&lt;br /&gt;
        var searchDebounce;&lt;br /&gt;
        $search.on( &#039;input&#039;, function () {&lt;br /&gt;
            clearTimeout( searchDebounce );&lt;br /&gt;
            searchDebounce = setTimeout( function () {&lt;br /&gt;
                state.search = $search.val().trim();&lt;br /&gt;
                resetAndLoad();&lt;br /&gt;
            }, 350 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $sort.on( &#039;change&#039;, function () {&lt;br /&gt;
            state.sort = $sort.val();&lt;br /&gt;
            resetAndLoad();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $more.on( &#039;click&#039;, function () {&lt;br /&gt;
            if ( !state.busy ) { fetchPage(); }&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Tag pill — delegated so it works for both cloud pills and card tag spans&lt;br /&gt;
        $( document ).on( &#039;click&#039;, &#039;.js-tag-filter&#039;, function ( e ) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var tag = $( this ).data( &#039;tag&#039; );&lt;br /&gt;
            if ( state.tag === tag ) {&lt;br /&gt;
                state.tag = &#039;&#039;;&lt;br /&gt;
                $( &#039;.js-tag-filter&#039; ).removeClass( &#039;is-active&#039; );&lt;br /&gt;
            } else {&lt;br /&gt;
                state.tag = tag;&lt;br /&gt;
                $( &#039;.js-tag-filter&#039; ).removeClass( &#039;is-active&#039; );&lt;br /&gt;
                $( &#039;.js-tag-filter&#039; ).filter( function () {&lt;br /&gt;
                    return $( this ).data( &#039;tag&#039; ) === tag;&lt;br /&gt;
                } ).addClass( &#039;is-active&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            resetAndLoad();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // License pill — delegated&lt;br /&gt;
        $( document ).on( &#039;click&#039;, &#039;.js-license-filter&#039;, function ( e ) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var lic = $( this ).data( &#039;license&#039; );&lt;br /&gt;
            if ( state.license === lic ) {&lt;br /&gt;
                state.license = &#039;&#039;;&lt;br /&gt;
                $( &#039;.js-license-filter&#039; ).removeClass( &#039;is-active&#039; );&lt;br /&gt;
            } else {&lt;br /&gt;
                state.license = lic;&lt;br /&gt;
                $( &#039;.js-license-filter&#039; ).removeClass( &#039;is-active&#039; );&lt;br /&gt;
                $( &#039;.js-license-filter&#039; ).filter( function () {&lt;br /&gt;
                    return $( this ).data( &#039;license&#039; ) === lic;&lt;br /&gt;
                } ).addClass( &#039;is-active&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            resetAndLoad();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // ── Boot ─────────────────────────────────────────────────────────────&lt;br /&gt;
        loadTagCloud();&lt;br /&gt;
        loadLicenseCloud();&lt;br /&gt;
        loadHubMeta();&lt;br /&gt;
        fetchPage();&lt;br /&gt;
&lt;br /&gt;
        // ── Helpers ───────────────────────────────────────────────────────────&lt;br /&gt;
        function resetAndLoad() {&lt;br /&gt;
            generation++;          // Any in-flight request with a lower generation is discarded&lt;br /&gt;
            state.offset = 0;&lt;br /&gt;
            state.done   = false;&lt;br /&gt;
            state.busy   = false;  // Unblock immediately so the new fetch can start&lt;br /&gt;
            $grid.empty();&lt;br /&gt;
            $more.hide();&lt;br /&gt;
            fetchPage();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function buildWhere() {&lt;br /&gt;
            var parts = [];&lt;br /&gt;
            if ( state.search ) {&lt;br /&gt;
                var q = state.search.replace( /&#039;/g, &amp;quot;&#039;&#039;&amp;quot; );&lt;br /&gt;
                parts.push(&lt;br /&gt;
                    &amp;quot;( name LIKE &#039;%&amp;quot; + q + &amp;quot;%&#039;&amp;quot; +&lt;br /&gt;
                    &amp;quot; OR creator LIKE &#039;%&amp;quot; + q + &amp;quot;%&#039;&amp;quot; +&lt;br /&gt;
                    &amp;quot; OR license LIKE &#039;%&amp;quot; + q + &amp;quot;%&#039;&amp;quot; +&lt;br /&gt;
                    &amp;quot; OR description LIKE &#039;%&amp;quot; + q + &amp;quot;%&#039; )&amp;quot;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
            if ( state.tag ) {&lt;br /&gt;
                parts.push( &amp;quot;tags HOLDS &#039;&amp;quot; + state.tag.replace( /&#039;/g, &amp;quot;&#039;&#039;&amp;quot; ) + &amp;quot;&#039;&amp;quot; );&lt;br /&gt;
            }&lt;br /&gt;
            if ( state.license ) {&lt;br /&gt;
                parts.push( &amp;quot;license = &#039;&amp;quot; + state.license.replace( /&#039;/g, &amp;quot;&#039;&#039;&amp;quot; ) + &amp;quot;&#039;&amp;quot; );&lt;br /&gt;
            }&lt;br /&gt;
            return parts.join( &#039; AND &#039; );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function orderBy() {&lt;br /&gt;
            return state.sort === &#039;alpha&#039; ? &#039;name ASC&#039; : &#039;_pageID DESC&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // ── Data ──────────────────────────────────────────────────────────────&lt;br /&gt;
        function fetchPage() {&lt;br /&gt;
            if ( state.busy || state.done ) { return; }&lt;br /&gt;
            state.busy = true;&lt;br /&gt;
            var gen = ++generation;&lt;br /&gt;
            $more.text( &#039;Loading\u2026&#039; ).show();&lt;br /&gt;
&lt;br /&gt;
            var params = {&lt;br /&gt;
                action   : &#039;cargoquery&#039;,&lt;br /&gt;
                tables   : &#039;Projects&#039;,&lt;br /&gt;
                fields   : &#039;_pageName=pagename,name,status,license,creator,&#039; +&lt;br /&gt;
                           &#039;description,image,tags,&#039; +&lt;br /&gt;
                           &#039;field1label,field1value,field2label,field2value,&#039; +&lt;br /&gt;
                           &#039;field3label,field3value,field4label,field4value&#039;,&lt;br /&gt;
                order_by : orderBy(),&lt;br /&gt;
                limit    : PAGE_SIZE,&lt;br /&gt;
                offset   : state.offset,&lt;br /&gt;
                format   : &#039;json&#039;&lt;br /&gt;
            };&lt;br /&gt;
            var w = buildWhere();&lt;br /&gt;
            if ( w ) { params.where = w; }&lt;br /&gt;
            if ( state.offset === 0 ) { fetchTotal( w ); }&lt;br /&gt;
&lt;br /&gt;
            $.getJSON( mw.util.wikiScript( &#039;api&#039; ), params )&lt;br /&gt;
                .done( function ( data ) {&lt;br /&gt;
                    if ( gen !== generation ) { return; } // Stale — discard silently&lt;br /&gt;
&lt;br /&gt;
                    var rows    = ( data.cargoquery || [] ).map( function ( r ) { return r.title; } );&lt;br /&gt;
                    var prevOff = state.offset;&lt;br /&gt;
                    var batch   = [];&lt;br /&gt;
&lt;br /&gt;
                    rows.forEach( function ( row ) {&lt;br /&gt;
                        var $c = buildCard( row );&lt;br /&gt;
                        $grid.append( $c );&lt;br /&gt;
                        batch.push( { $el: $c, page: row.pagename } );&lt;br /&gt;
                    } );&lt;br /&gt;
&lt;br /&gt;
                    enrichCards( batch );&lt;br /&gt;
&lt;br /&gt;
                    state.offset += rows.length;&lt;br /&gt;
                    state.done    = rows.length &amp;lt; PAGE_SIZE;&lt;br /&gt;
                    state.busy    = false;&lt;br /&gt;
&lt;br /&gt;
                    $more.text( &#039;Load more projects&#039; ).toggle( !state.done );&lt;br /&gt;
&lt;br /&gt;
                    if ( rows.length === 0 &amp;amp;&amp;amp; prevOff === 0 ) {&lt;br /&gt;
                        $grid.html( &#039;&amp;lt;div class=&amp;quot;project-hub-empty&amp;quot;&amp;gt;No projects found matching your search.&amp;lt;/div&amp;gt;&#039; );&lt;br /&gt;
                        $more.hide();&lt;br /&gt;
                    }&lt;br /&gt;
                } )&lt;br /&gt;
                .fail( function () {&lt;br /&gt;
                    if ( gen !== generation ) { return; }&lt;br /&gt;
                    state.busy = false;&lt;br /&gt;
                    $more.text( &#039;Load more projects&#039; ).toggle( !state.done );&lt;br /&gt;
                } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function fetchTotal( where ) {&lt;br /&gt;
            var p = { action: &#039;cargoquery&#039;, tables: &#039;Projects&#039;, fields: &#039;COUNT(*)=n&#039;, limit: 1, format: &#039;json&#039; };&lt;br /&gt;
            if ( where ) { p.where = where; }&lt;br /&gt;
            $.getJSON( mw.util.wikiScript( &#039;api&#039; ), p ).done( function ( data ) {&lt;br /&gt;
                var row = ( data.cargoquery || [] )[ 0 ];&lt;br /&gt;
                var n   = row ? ( parseInt( row.title.n, 10 ) || 0 ) : 0;&lt;br /&gt;
                $count.text( n + &#039; project&#039; + ( n === 1 ? &#039;&#039; : &#039;s&#039; ) );&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function loadTagCloud() {&lt;br /&gt;
            $.getJSON( mw.util.wikiScript( &#039;api&#039; ), {&lt;br /&gt;
                action: &#039;cargoquery&#039;, tables: &#039;Projects&#039;, fields: &#039;tags&#039;, limit: 500, format: &#039;json&#039;&lt;br /&gt;
            } ).done( function ( data ) {&lt;br /&gt;
                var freq = {};&lt;br /&gt;
                ( data.cargoquery || [] ).forEach( function ( r ) {&lt;br /&gt;
                    ( r.title.tags || &#039;&#039; ).split( &#039;,&#039; ).forEach( function ( t ) {&lt;br /&gt;
                        t = t.trim();&lt;br /&gt;
                        if ( t ) { freq[ t ] = ( freq[ t ] || 0 ) + 1; }&lt;br /&gt;
                    } );&lt;br /&gt;
                } );&lt;br /&gt;
                var top = Object.keys( freq )&lt;br /&gt;
                    .sort( function ( a, b ) { return freq[ b ] - freq[ a ]; } )&lt;br /&gt;
                    .slice( 0, 25 );&lt;br /&gt;
                if ( !top.length ) { return; }&lt;br /&gt;
                top.forEach( function ( tag ) {&lt;br /&gt;
                    $tagCloud.append(&lt;br /&gt;
                        $( &#039;&amp;lt;span&amp;gt;&#039; ).addClass( &#039;js-tag-filter&#039; ).attr( &#039;data-tag&#039;, tag ).text( tag )&lt;br /&gt;
                    );&lt;br /&gt;
                } );&lt;br /&gt;
                $tagCloud.show();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function loadLicenseCloud() {&lt;br /&gt;
            $.getJSON( mw.util.wikiScript( &#039;api&#039; ), {&lt;br /&gt;
                action   : &#039;cargoquery&#039;,&lt;br /&gt;
                tables   : &#039;Projects&#039;,&lt;br /&gt;
                fields   : &#039;license&#039;,&lt;br /&gt;
                group_by : &#039;license&#039;,&lt;br /&gt;
                where    : &amp;quot;license IS NOT NULL AND license != &#039;&#039;&amp;quot;,&lt;br /&gt;
                order_by : &#039;license ASC&#039;,&lt;br /&gt;
                limit    : 20,&lt;br /&gt;
                format   : &#039;json&#039;&lt;br /&gt;
            } ).done( function ( data ) {&lt;br /&gt;
                var licenses = ( data.cargoquery || [] )&lt;br /&gt;
                    .map( function ( r ) { return ( r.title.license || &#039;&#039; ).trim(); } )&lt;br /&gt;
                    .filter( Boolean );&lt;br /&gt;
                if ( !licenses.length ) { return; }&lt;br /&gt;
                licenses.forEach( function ( lic ) {&lt;br /&gt;
                    $licenseCloud.append(&lt;br /&gt;
                        $( &#039;&amp;lt;span&amp;gt;&#039; ).addClass( &#039;js-license-filter&#039; )&lt;br /&gt;
                            .attr( &#039;data-license&#039;, lic ).text( lic )&lt;br /&gt;
                    );&lt;br /&gt;
                } );&lt;br /&gt;
                $licenseCloud.show();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function loadHubMeta() {&lt;br /&gt;
            mw.loader.using( &#039;mediawiki.api&#039; ).then( function () {&lt;br /&gt;
                new mw.Api().get( {&lt;br /&gt;
                    action: &#039;query&#039;, list: &#039;categorymembers&#039;, cmtitle: &#039;Category:Projects&#039;,&lt;br /&gt;
                    cmsort: &#039;timestamp&#039;, cmdir: &#039;desc&#039;, cmlimit: 1,&lt;br /&gt;
                    cmtype: &#039;page&#039;, cmprop: &#039;ids|title|timestamp&#039;, format: &#039;json&#039;&lt;br /&gt;
                } ).done( function ( data ) {&lt;br /&gt;
                    var m = data.query &amp;amp;&amp;amp; data.query.categorymembers;&lt;br /&gt;
                    if ( !m || !m.length ) { return; }&lt;br /&gt;
                    var str = m[ 0 ].title.replace( /^.*\//, &#039;&#039; ) + &#039; \u2014 &#039; +&lt;br /&gt;
                        ( m[ 0 ].timestamp&lt;br /&gt;
                            ? new Date( m[ 0 ].timestamp ).toLocaleDateString(&lt;br /&gt;
                                &#039;en-GB&#039;, { day: &#039;numeric&#039;, month: &#039;short&#039;, year: &#039;numeric&#039; } )&lt;br /&gt;
                            : &#039;\u2014&#039; );&lt;br /&gt;
                    $( &#039;#hub-meta-last-submission, #hub-meta-last-edit&#039; ).text( str );&lt;br /&gt;
                } );&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // ── Card rendering ────────────────────────────────────────────────────&lt;br /&gt;
        function parseWikitext( text ) {&lt;br /&gt;
            if ( !text ) { return &#039;&#039;; }&lt;br /&gt;
            text = String( text );&lt;br /&gt;
            // External links: [https://url Display Text]&lt;br /&gt;
            text = text.replace( /\[(\S+?)\s+([^\]]+?)\]/g, function ( m, url, display ) {&lt;br /&gt;
                if ( !/^https?:\/\//i.test( url ) ) { return mw.html.escape( m ); }&lt;br /&gt;
                return &#039;&amp;lt;a href=&amp;quot;&#039; + url.replace( /&amp;quot;/g, &#039;%22&#039; ) + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    mw.html.escape( display ) + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
            } );&lt;br /&gt;
            // Internal links: [[Page Name|Display]] or [[Page Name]]&lt;br /&gt;
            text = text.replace( /\[\[([^\]|]+?)(?:\|([^\]]+?))?\]\]/g, function ( m, page, display ) {&lt;br /&gt;
                return &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl( page.trim() ) + &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    mw.html.escape( ( display || page ).trim() ) + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
            } );&lt;br /&gt;
            // Newlines to line breaks&lt;br /&gt;
            text = text.replace( /\n/g, &#039;&amp;lt;br&amp;gt;&#039; );&lt;br /&gt;
            return text;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function esc( s ) { return mw.html.escape( s || &#039;&#039; ); }&lt;br /&gt;
&lt;br /&gt;
        function fileUrl( f ) {&lt;br /&gt;
            return f ? mw.config.get( &#039;wgServer&#039; ) + &#039;/wiki/Special:FilePath/&#039; + encodeURIComponent( f ) : &#039;&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function buildCard( row ) {&lt;br /&gt;
            var page = row.pagename || &#039;&#039;;&lt;br /&gt;
            var name = row.name || page.replace( /^.*\//, &#039;&#039; );&lt;br /&gt;
            var url  = mw.util.getUrl( page );&lt;br /&gt;
&lt;br /&gt;
            var img = row.image&lt;br /&gt;
                ? &#039;&amp;lt;img src=&amp;quot;&#039; + esc( fileUrl( row.image ) ) + &#039;&amp;quot; alt=&amp;quot;&#039; + esc( name ) + &#039;&amp;quot; loading=&amp;quot;lazy&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                : &#039;&amp;lt;div class=&amp;quot;project-card-image-fallback&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            var badges = &#039;&#039;;&lt;br /&gt;
            if ( row.status ) {&lt;br /&gt;
                badges += &#039;&amp;lt;span class=&amp;quot;project-badge-status project-badge-status--&#039; +&lt;br /&gt;
                    esc( row.status.toLowerCase() ) + &#039;&amp;quot;&amp;gt;&#039; + esc( row.status ) + &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
            }&lt;br /&gt;
            if ( row.license ) {&lt;br /&gt;
                badges += &#039;&amp;lt;span class=&amp;quot;project-badge-license&amp;quot;&amp;gt;&#039; + esc( row.license ) + &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var tags = &#039;&#039;;&lt;br /&gt;
            ( row.tags || &#039;&#039; ).split( &#039;,&#039; ).forEach( function ( t ) {&lt;br /&gt;
                t = t.trim();&lt;br /&gt;
                if ( t ) {&lt;br /&gt;
                    tags += &#039;&amp;lt;span class=&amp;quot;project-card-tag js-tag-filter&amp;quot; data-tag=&amp;quot;&#039; +&lt;br /&gt;
                        esc( t ) + &#039;&amp;quot;&amp;gt;&#039; + esc( t ) + &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
                }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            var extras = &#039;&#039;;&lt;br /&gt;
            for ( var i = 1; i &amp;lt;= 4; i++ ) {&lt;br /&gt;
                if ( row[ &#039;field&#039; + i + &#039;label&#039; ] ) {&lt;br /&gt;
                    extras += &#039;&amp;lt;div class=&amp;quot;project-card-extra&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                        esc( row[ &#039;field&#039; + i + &#039;label&#039; ] ) +&lt;br /&gt;
                        &#039;: &amp;lt;strong&amp;gt;&#039; + parseWikitext( row[ &#039;field&#039; + i + &#039;value&#039; ] ) + &#039;&amp;lt;/strong&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return $( [&lt;br /&gt;
                &#039;&amp;lt;div class=&amp;quot;project-card-wrap&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                  &#039;&amp;lt;div class=&amp;quot;project-card&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;project-card-inner&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                      &#039;&amp;lt;div class=&amp;quot;project-card-front&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;project-card-image&amp;quot;&amp;gt;&#039;, img, &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;project-card-body&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                          &#039;&amp;lt;div class=&amp;quot;project-card-title&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;&#039;, url, &#039;&amp;quot;&amp;gt;&#039;, esc( name ), &#039;&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                          &#039;&amp;lt;div class=&amp;quot;project-card-badges&amp;quot;&amp;gt;&#039;, badges, &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                          row.creator ? &#039;&amp;lt;div class=&amp;quot;project-card-creator&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;project-card-label&amp;quot;&amp;gt;By&amp;lt;/span&amp;gt; &#039; + esc( row.creator ) + &#039;&amp;lt;/div&amp;gt;&#039; : &#039;&#039;,&lt;br /&gt;
                          extras,&lt;br /&gt;
                          tags ? &#039;&amp;lt;div class=&amp;quot;project-card-tags&amp;quot;&amp;gt;&#039; + tags + &#039;&amp;lt;/div&amp;gt;&#039; : &#039;&#039;,&lt;br /&gt;
                          &#039;&amp;lt;div class=&amp;quot;project-card-footer&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;span class=&amp;quot;project-card-meta-item project-card-contributors&amp;quot;&amp;gt;—&amp;lt;/span&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;span class=&amp;quot;project-card-meta-item project-card-updated&amp;quot;&amp;gt;—&amp;lt;/span&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;js-flip-btn project-card-flip-btn&amp;quot;&amp;gt;Read more&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
                          &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                      &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                      &#039;&amp;lt;div class=&amp;quot;project-card-back&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                         &#039;&amp;lt;div class=&amp;quot;project-card-back-header&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;span class=&amp;quot;project-card-back-title&amp;quot;&amp;gt;About&amp;lt;/span&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;js-flip-btn project-card-flip-btn&amp;quot;&amp;gt;Close&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
                         &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                         &#039;&amp;lt;div class=&amp;quot;project-card-back-content&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                            row.description ? esc( row.description ) : &#039;No description provided.&#039;,&lt;br /&gt;
                         &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                      &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                    &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                  &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
            ].join( &#039;&#039; ) );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // ── Enrichment (contributor count + last-edited date) ─────────────────&lt;br /&gt;
        function enrichCards( batch ) {&lt;br /&gt;
            if ( !batch.length ) { return; }&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            for ( var i = 0; i &amp;lt; batch.length; i += 20 ) {&lt;br /&gt;
                ( function ( chunk ) {&lt;br /&gt;
                    api.get( {&lt;br /&gt;
                        action: &#039;query&#039;,&lt;br /&gt;
                        titles: chunk.map( function ( c ) { return c.page; } ).join( &#039;|&#039; ),&lt;br /&gt;
                        prop: &#039;revisions|contributors&#039;,&lt;br /&gt;
                        rvprop: &#039;timestamp&#039;,&lt;br /&gt;
                        format: &#039;json&#039;&lt;br /&gt;
                    } ).done( function ( data ) {&lt;br /&gt;
                        if ( !data.query ) { return; }&lt;br /&gt;
                        $.each( data.query.pages || {}, function ( _, page ) {&lt;br /&gt;
                            if ( page.missing !== undefined ) { return; }&lt;br /&gt;
                            var normalise = function ( s ) { return ( s || &#039;&#039; ).replace( /_/g, &#039; &#039; ); };&lt;br /&gt;
                            var match = chunk.filter( function ( c ) { return normalise( c.page ) === normalise( page.title ); } );&lt;br /&gt;
                            if ( !match.length ) { return; }&lt;br /&gt;
                            var $el = match[ 0 ].$el;&lt;br /&gt;
                            var ts  = ( page.revisions &amp;amp;&amp;amp; page.revisions[ 0 ] &amp;amp;&amp;amp; page.revisions[ 0 ].timestamp ) || &#039;&#039;;&lt;br /&gt;
                            var n   = ( page.contributors ? page.contributors.length : 0 ) + ( page.anoncontributors || 0 );&lt;br /&gt;
                            var d   = ts ? new Date( ts ).toLocaleDateString( &#039;en-GB&#039;, { year: &#039;numeric&#039;, month: &#039;short&#039; } ) : &#039;\u2014&#039;;&lt;br /&gt;
                            $el.find( &#039;.project-card-contributors&#039; )&lt;br /&gt;
                               .text( n + ( n === 1 ? &#039; contributor&#039; : &#039; contributors&#039; ) ).addClass( &#039;loaded&#039; );&lt;br /&gt;
                            $el.find( &#039;.project-card-updated&#039; )&lt;br /&gt;
                               .text( &#039;Edited &#039; + d ).addClass( &#039;loaded&#039; );&lt;br /&gt;
                        } );&lt;br /&gt;
                    } );&lt;br /&gt;
                } )( batch.slice( i, i + 20 ) );&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} () );&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1204</id>
		<title>Form:Submit Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1204"/>
		<updated>2026-04-05T00:54:02Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Trying again to fix the same bug of posting to root&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{{info|page name=Projects/&amp;lt;ProjectMeta[name]&amp;gt;}}}&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{SubpageNav| icon=emotes-face-smile-big}}&lt;br /&gt;
&lt;br /&gt;
{{{for template|ProjectMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Project Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Project Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Status:&lt;br /&gt;
| {{{field|status|input type=dropdown|values=Active,Hiatus,Completed,Abandoned|default=Active}}}&lt;br /&gt;
|-&lt;br /&gt;
! License:&lt;br /&gt;
| {{{field|license|input type=dropdown|values=CC0 1.0,CC BY 4.0,CC BY-SA 4.0,MIT,Apache 2.0,GPL-3.0,AGPL-3.0,LGPL-3.0,BSD-3-Clause,MPL-2.0,EPL-2.0,EUPL-1.2}}}&lt;br /&gt;
|-&lt;br /&gt;
! Creator / Team:&lt;br /&gt;
| {{{field|creator|input type=text|size=40|placeholder=Your name or team name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown on hover over your project card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, ambient, synthesis}}}&lt;br /&gt;
|-&lt;br /&gt;
! Website:&lt;br /&gt;
| {{{field|website|input type=text|size=60|placeholder=example.com}}}&lt;br /&gt;
|-&lt;br /&gt;
! Repository:&lt;br /&gt;
| {{{field|repository|input type=text|size=60|placeholder=https://codeberg.org/...}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Label:&lt;br /&gt;
| {{{field|field1label|input type=text|size=30|placeholder=e.g. DAW}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Value:&lt;br /&gt;
| {{{field|field1value|input type=text|size=30|placeholder=e.g. Ableton}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Label:&lt;br /&gt;
| {{{field|field2label|input type=text|size=30|placeholder=e.g. Genre}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Value:&lt;br /&gt;
| {{{field|field2value|input type=text|size=30|placeholder=e.g. Ambient}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Label:&lt;br /&gt;
| {{{field|field3label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Value:&lt;br /&gt;
| {{{field|field3value|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Label:&lt;br /&gt;
| {{{field|field4label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Value:&lt;br /&gt;
| {{{field|field4value|input type=text|size=30}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Project}}} {{{standard input|cancel}}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-subpagenav.js&amp;diff=1202</id>
		<title>MediaWiki:Gadget-subpagenav.js</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-subpagenav.js&amp;diff=1202"/>
		<updated>2026-04-05T00:37:20Z</updated>

		<summary type="html">&lt;p&gt;Anthony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   MediaWiki:Gadget-subpagenav.js&lt;br /&gt;
   UnfinishedProjects Wiki&lt;br /&gt;
&lt;br /&gt;
   Auto-builds nested dropdown menus from Special:PrefixIndex output and&lt;br /&gt;
   wires up accessible toggle behaviour for Template:SubpageNav.&lt;br /&gt;
&lt;br /&gt;
   TABLE OF CONTENTS&lt;br /&gt;
   Part 1 — Auto-Builder  (converts flat PrefixIndex list → nested tree)&lt;br /&gt;
   Part 2 — Manual Lists  (adds carets to hand-authored &amp;lt;ul&amp;gt; trees)&lt;br /&gt;
   Part 3 — Click Handlers&lt;br /&gt;
   Part 4 — Current-Page Highlight&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
( function () {&lt;br /&gt;
    $( function () {&lt;br /&gt;
&lt;br /&gt;
        var $navLinks = $( &#039;.subpage-nav-links&#039; );&lt;br /&gt;
        if ( !$navLinks.length ) return;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* =====================================================================&lt;br /&gt;
           PART 1: AUTO-BUILDER&lt;br /&gt;
           Converts the flat &amp;lt;a&amp;gt; list from Special:PrefixIndex into a proper&lt;br /&gt;
           nested tree.&lt;br /&gt;
&lt;br /&gt;
           WHY TWO PASSES?&lt;br /&gt;
           PrefixIndex lists pages alphabetically. If &amp;quot;About&amp;quot; appears before&lt;br /&gt;
           &amp;quot;About/More Details&amp;quot;, a single-pass builder would create &amp;quot;About&amp;quot; as a&lt;br /&gt;
           leaf &amp;lt;li&amp;gt; (no child &amp;lt;ul&amp;gt;). When &amp;quot;About/More Details&amp;quot; is processed next&lt;br /&gt;
           it tries to descend into a non-existent &amp;lt;ul&amp;gt; and silently drops the&lt;br /&gt;
           item. Building a plain-JS tree first, then rendering, avoids this&lt;br /&gt;
           entirely — a node can be both a real page AND a parent folder.&lt;br /&gt;
           ===================================================================== */&lt;br /&gt;
        $navLinks.find( &#039;.subpage-auto-list&#039; ).each( function () {&lt;br /&gt;
            var $autoContainer = $( this );&lt;br /&gt;
&lt;br /&gt;
            // --- Pass A: Build a plain-JS tree --------------------------------&lt;br /&gt;
            // Each node shape: { href: null|string, children: {} }&lt;br /&gt;
            var tree = {};&lt;br /&gt;
&lt;br /&gt;
            $autoContainer.find( &#039;a&#039; ).each( function () {&lt;br /&gt;
                var href = $( this ).attr( &#039;href&#039; );&lt;br /&gt;
                var fullPath = $( this ).text().trim(); // e.g. &amp;quot;About/More Details&amp;quot;&lt;br /&gt;
                var parts = fullPath.split( &#039;/&#039; );&lt;br /&gt;
&lt;br /&gt;
                var node = tree;&lt;br /&gt;
                for ( var i = 0; i &amp;lt; parts.length; i++ ) {&lt;br /&gt;
                    var part = parts[ i ].trim();&lt;br /&gt;
                    if ( !part ) { continue; }&lt;br /&gt;
&lt;br /&gt;
                    if ( !node[ part ] ) {&lt;br /&gt;
                        node[ part ] = { href: null, children: {} };&lt;br /&gt;
                    }&lt;br /&gt;
                    // If this is the last segment it&#039;s a real, linkable page&lt;br /&gt;
                    if ( i === parts.length - 1 ) {&lt;br /&gt;
                        node[ part ].href = href;&lt;br /&gt;
                    }&lt;br /&gt;
                    // Descend regardless — the same segment can be both a page&lt;br /&gt;
                    // and a parent folder (dual-node case)&lt;br /&gt;
                    node = node[ part ].children;&lt;br /&gt;
                }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            // --- Pass B: Render tree to DOM (recursive) -----------------------&lt;br /&gt;
            function renderTree( treeNode ) {&lt;br /&gt;
                var $ul = $( &#039;&amp;lt;ul&amp;gt;&#039; );&lt;br /&gt;
&lt;br /&gt;
                $.each( treeNode, function ( key, item ) {&lt;br /&gt;
                    var $li = $( &#039;&amp;lt;li&amp;gt;&#039; );&lt;br /&gt;
                    var hasChildren = Object.keys( item.children ).length &amp;gt; 0;&lt;br /&gt;
&lt;br /&gt;
                    if ( item.href ) {&lt;br /&gt;
                        // Real page — render as a navigable link&lt;br /&gt;
                        $li.append( $( &#039;&amp;lt;a&amp;gt;&#039; ).attr( &#039;href&#039;, item.href ).text( key ) );&lt;br /&gt;
                    } else {&lt;br /&gt;
                        // Virtual folder — no page exists, render as a label&lt;br /&gt;
                        $li.append( $( &#039;&amp;lt;span&amp;gt;&#039; ).text( key ) );&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    if ( hasChildren ) {&lt;br /&gt;
                        // Add a SIBLING caret &amp;lt;button&amp;gt; — not inside the &amp;lt;a&amp;gt;.&lt;br /&gt;
                        // This keeps the link fully navigable; only the button toggles.&lt;br /&gt;
                        $li.addClass( &#039;has-dropdown&#039; );&lt;br /&gt;
                        $li.append(&lt;br /&gt;
                            $( &#039;&amp;lt;button&amp;gt;&#039; )&lt;br /&gt;
                                .addClass( &#039;subpage-nav-caret&#039; )&lt;br /&gt;
                                .attr( &#039;type&#039;, &#039;button&#039; )&lt;br /&gt;
                                .attr( &#039;aria-label&#039;, &#039;Toggle submenu&#039; )&lt;br /&gt;
                                .text( &#039;▾&#039; )&lt;br /&gt;
                        );&lt;br /&gt;
                        $li.append( renderTree( item.children ) );&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                    $ul.append( $li );&lt;br /&gt;
                } );&lt;br /&gt;
&lt;br /&gt;
                return $ul;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Swap the raw PrefixIndex block with our clean nested list&lt;br /&gt;
            $autoContainer.replaceWith( renderTree( tree ) );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* =====================================================================&lt;br /&gt;
           PART 2: MANUAL LISTS&lt;br /&gt;
           When the template is called with a hand-authored wikitext list&lt;br /&gt;
           (parameter 1), MediaWiki already renders correct &amp;lt;ul&amp;gt;/&amp;lt;li&amp;gt; nesting.&lt;br /&gt;
           We just need to find &amp;lt;li&amp;gt; elements that contain a child &amp;lt;ul&amp;gt; and&lt;br /&gt;
           wire them up the same way the auto-builder does.&lt;br /&gt;
&lt;br /&gt;
           KEY DIFFERENCE from old approach:&lt;br /&gt;
           Old code appended the caret INSIDE the &amp;lt;a&amp;gt; tag, then called&lt;br /&gt;
           e.preventDefault() on the &amp;lt;a&amp;gt; click — this prevented navigation.&lt;br /&gt;
           New code adds a separate sibling &amp;lt;button&amp;gt; for the caret, so the&lt;br /&gt;
           link remains fully clickable for navigation.&lt;br /&gt;
           ===================================================================== */&lt;br /&gt;
        $navLinks.find( &#039;li&#039; ).has( &#039;ul&#039; ).each( function () {&lt;br /&gt;
            var $li = $( this );&lt;br /&gt;
&lt;br /&gt;
            // Skip anything already wired up by Part 1&lt;br /&gt;
            if ( $li.hasClass( &#039;has-dropdown&#039; ) ) { return; }&lt;br /&gt;
            $li.addClass( &#039;has-dropdown&#039; );&lt;br /&gt;
&lt;br /&gt;
            var $trigger = $li.children( &#039;a, span&#039; ).first();&lt;br /&gt;
            var $caret = $( &#039;&amp;lt;button&amp;gt;&#039; )&lt;br /&gt;
                .addClass( &#039;subpage-nav-caret&#039; )&lt;br /&gt;
                .attr( &#039;type&#039;, &#039;button&#039; )&lt;br /&gt;
                .attr( &#039;aria-label&#039;, &#039;Toggle submenu&#039; )&lt;br /&gt;
                .text( &#039;▾&#039; );&lt;br /&gt;
&lt;br /&gt;
            if ( $trigger.is( &#039;a&#039; ) ) {&lt;br /&gt;
                // Link stays navigable — insert caret as a sibling AFTER the link&lt;br /&gt;
                $trigger.after( $caret );&lt;br /&gt;
            } else {&lt;br /&gt;
                // No real link — caret goes inside the &amp;lt;span&amp;gt; as a child&lt;br /&gt;
                $trigger.append( $caret );&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* =====================================================================&lt;br /&gt;
           PART 3: CLICK HANDLERS&lt;br /&gt;
&lt;br /&gt;
           Caret button  → toggle is-open on parent &amp;lt;li&amp;gt;, close siblings&lt;br /&gt;
           Folder &amp;lt;span&amp;gt; → same (clicking the label of a folder-only item)&lt;br /&gt;
           Outside click → close all open dropdowns&lt;br /&gt;
           ===================================================================== */&lt;br /&gt;
&lt;br /&gt;
        // Caret button click&lt;br /&gt;
        $navLinks.on( &#039;click&#039;, &#039;.has-dropdown &amp;gt; .subpage-nav-caret&#039;, function ( e ) {&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var $parentLi = $( this ).parent();&lt;br /&gt;
            // Close siblings at the same nesting level&lt;br /&gt;
            $parentLi.siblings( &#039;.is-open&#039; ).removeClass( &#039;is-open&#039; );&lt;br /&gt;
            $parentLi.toggleClass( &#039;is-open&#039; );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Folder label &amp;lt;span&amp;gt; click (virtual folder — no navigation possible)&lt;br /&gt;
        $navLinks.on( &#039;click&#039;, &#039;.has-dropdown &amp;gt; span&#039;, function ( e ) {&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
            var $parentLi = $( this ).parent();&lt;br /&gt;
            $parentLi.siblings( &#039;.is-open&#039; ).removeClass( &#039;is-open&#039; );&lt;br /&gt;
            $parentLi.toggleClass( &#039;is-open&#039; );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Click anywhere outside the nav closes all open dropdowns&lt;br /&gt;
        $( document ).on( &#039;click&#039;, function ( e ) {&lt;br /&gt;
            if ( !$( e.target ).closest( &#039;.subpage-nav-links&#039; ).length ) {&lt;br /&gt;
                $navLinks.find( &#039;.is-open&#039; ).removeClass( &#039;is-open&#039; );&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* =====================================================================&lt;br /&gt;
           PART 4: CURRENT-PAGE HIGHLIGHT&lt;br /&gt;
           Reads the current page name from MediaWiki, finds the matching link&lt;br /&gt;
           in the nav, marks it with .is-current, and auto-opens any ancestor&lt;br /&gt;
           dropdown &amp;lt;li&amp;gt; elements so the user can immediately see where they are.&lt;br /&gt;
&lt;br /&gt;
           Normalises underscores ↔ spaces since MediaWiki uses both.&lt;br /&gt;
           ===================================================================== */&lt;br /&gt;
        var currentPage = ( mw.config.get( &#039;wgPageName&#039; ) || &#039;&#039; ).replace( /_/g, &#039; &#039; );&lt;br /&gt;
        if ( !currentPage ) { return; }&lt;br /&gt;
&lt;br /&gt;
        $navLinks.find( &#039;a&#039; ).each( function () {&lt;br /&gt;
            var $a = $( this );&lt;br /&gt;
            var href = decodeURIComponent( $a.attr( &#039;href&#039; ) || &#039;&#039; );&lt;br /&gt;
&lt;br /&gt;
            // MediaWiki internal links look like /wiki/Page_Name&lt;br /&gt;
            // Strip the /wiki/ prefix and normalise underscores&lt;br /&gt;
            var linkPage = href.replace( /^.*\/wiki\//, &#039;&#039; ).replace( /_/g, &#039; &#039; );&lt;br /&gt;
&lt;br /&gt;
            if ( linkPage === currentPage ) {&lt;br /&gt;
                $a.addClass( &#039;is-current&#039; );&lt;br /&gt;
&lt;br /&gt;
                // Walk up the DOM and open ancestor dropdowns.&lt;br /&gt;
                // Start from $a.parent() so we do NOT auto-open the dropdown&lt;br /&gt;
                // that the current page itself belongs to — only true ancestors.&lt;br /&gt;
                $a.parent().parents( &#039;.subpage-nav-links li.has-dropdown&#039; ).each( function () {&lt;br /&gt;
                    $( this ).addClass( &#039;is-open&#039; );&lt;br /&gt;
                } );&lt;br /&gt;
&lt;br /&gt;
                return false; // Stop iterating once found&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
    } );&lt;br /&gt;
}() );&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-projects.js&amp;diff=1201</id>
		<title>MediaWiki:Gadget-projects.js</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Gadget-projects.js&amp;diff=1201"/>
		<updated>2026-04-05T00:36:33Z</updated>

		<summary type="html">&lt;p&gt;Anthony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* =============================================================================&lt;br /&gt;
   Gadget-projects.js  v2.1&lt;br /&gt;
   Unified project hub — API-powered search, tag/licence filtering, pagination.&lt;br /&gt;
   ============================================================================= */&lt;br /&gt;
( function () {&lt;br /&gt;
&lt;br /&gt;
    if ( mw.config.get( &#039;wgPageName&#039; ) !== &#039;Projects&#039; ) { return; }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
&lt;br /&gt;
        var PAGE_SIZE  = 24;&lt;br /&gt;
        var generation = 0; // Incremented on every new search to discard stale responses&lt;br /&gt;
&lt;br /&gt;
        var state = {&lt;br /&gt;
            search  : &#039;&#039;,&lt;br /&gt;
            tag     : &#039;&#039;,&lt;br /&gt;
            license : &#039;&#039;,&lt;br /&gt;
            sort    : &#039;newest&#039;,&lt;br /&gt;
            offset  : 0,&lt;br /&gt;
            done    : false,&lt;br /&gt;
            busy    : false&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var $wrapper = $( &#039;.project-hub-wrapper&#039; );&lt;br /&gt;
        if ( !$wrapper.length ) { return; }&lt;br /&gt;
&lt;br /&gt;
        var $filters      = $wrapper.find( &#039;.project-hub-filters&#039; );&lt;br /&gt;
        var $tagCloud     = $wrapper.find( &#039;.project-hub-tagcloud&#039; );&lt;br /&gt;
        var $licenseCloud = $wrapper.find( &#039;.project-hub-licensecloud&#039; );&lt;br /&gt;
        var $grid         = $wrapper.find( &#039;.project-hub-grid&#039; );&lt;br /&gt;
        var $count        = $( &#039;&amp;lt;span&amp;gt;&#039; ).addClass( &#039;project-hub-count&#039; );&lt;br /&gt;
&lt;br /&gt;
        // Create the Load More button entirely in JS.&lt;br /&gt;
        // &amp;lt;button&amp;gt; tags are stripped by the MediaWiki HTML sanitiser if placed in wikitext.&lt;br /&gt;
        var $more = $( &#039;&amp;lt;button&amp;gt;&#039; )&lt;br /&gt;
            .addClass( &#039;project-hub-loadmore&#039; )&lt;br /&gt;
            .text( &#039;Load more projects&#039; )&lt;br /&gt;
            .hide()&lt;br /&gt;
            .appendTo( $wrapper );&lt;br /&gt;
&lt;br /&gt;
        // ── Filter bar ────────────────────────────────────────────────────────&lt;br /&gt;
        var $search = $( &#039;&amp;lt;input&amp;gt;&#039; ).attr( {&lt;br /&gt;
            type        : &#039;text&#039;,&lt;br /&gt;
            placeholder : &#039;Search name, creator, license, tags, description\u2026&#039;,&lt;br /&gt;
            &#039;class&#039;     : &#039;project-hub-search&#039;&lt;br /&gt;
        } );&lt;br /&gt;
        var $sort = $( &#039;&amp;lt;select&amp;gt;&#039; ).addClass( &#039;project-hub-select&#039; ).append(&lt;br /&gt;
            $( &#039;&amp;lt;option&amp;gt;&#039; ).val( &#039;newest&#039; ).text( &#039;Newest first&#039; ),&lt;br /&gt;
            $( &#039;&amp;lt;option&amp;gt;&#039; ).val( &#039;alpha&#039;  ).text( &#039;A \u2013 Z&#039; )&lt;br /&gt;
        );&lt;br /&gt;
        $filters.append( $search, $sort, $count );&lt;br /&gt;
&lt;br /&gt;
        // ── Events ────────────────────────────────────────────────────────────&lt;br /&gt;
        var searchDebounce;&lt;br /&gt;
        $search.on( &#039;input&#039;, function () {&lt;br /&gt;
            clearTimeout( searchDebounce );&lt;br /&gt;
            searchDebounce = setTimeout( function () {&lt;br /&gt;
                state.search = $search.val().trim();&lt;br /&gt;
                resetAndLoad();&lt;br /&gt;
            }, 350 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $sort.on( &#039;change&#039;, function () {&lt;br /&gt;
            state.sort = $sort.val();&lt;br /&gt;
            resetAndLoad();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $more.on( &#039;click&#039;, function () {&lt;br /&gt;
            if ( !state.busy ) { fetchPage(); }&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Tag pill — delegated so it works for both cloud pills and card tag spans&lt;br /&gt;
        $( document ).on( &#039;click&#039;, &#039;.js-tag-filter&#039;, function ( e ) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var tag = $( this ).data( &#039;tag&#039; );&lt;br /&gt;
            if ( state.tag === tag ) {&lt;br /&gt;
                state.tag = &#039;&#039;;&lt;br /&gt;
                $( &#039;.js-tag-filter&#039; ).removeClass( &#039;is-active&#039; );&lt;br /&gt;
            } else {&lt;br /&gt;
                state.tag = tag;&lt;br /&gt;
                $( &#039;.js-tag-filter&#039; ).removeClass( &#039;is-active&#039; );&lt;br /&gt;
                $( &#039;.js-tag-filter&#039; ).filter( function () {&lt;br /&gt;
                    return $( this ).data( &#039;tag&#039; ) === tag;&lt;br /&gt;
                } ).addClass( &#039;is-active&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            resetAndLoad();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // License pill — delegated&lt;br /&gt;
        $( document ).on( &#039;click&#039;, &#039;.js-license-filter&#039;, function ( e ) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var lic = $( this ).data( &#039;license&#039; );&lt;br /&gt;
            if ( state.license === lic ) {&lt;br /&gt;
                state.license = &#039;&#039;;&lt;br /&gt;
                $( &#039;.js-license-filter&#039; ).removeClass( &#039;is-active&#039; );&lt;br /&gt;
            } else {&lt;br /&gt;
                state.license = lic;&lt;br /&gt;
                $( &#039;.js-license-filter&#039; ).removeClass( &#039;is-active&#039; );&lt;br /&gt;
                $( &#039;.js-license-filter&#039; ).filter( function () {&lt;br /&gt;
                    return $( this ).data( &#039;license&#039; ) === lic;&lt;br /&gt;
                } ).addClass( &#039;is-active&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            resetAndLoad();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // ── Boot ─────────────────────────────────────────────────────────────&lt;br /&gt;
        loadTagCloud();&lt;br /&gt;
        loadLicenseCloud();&lt;br /&gt;
        loadHubMeta();&lt;br /&gt;
        fetchPage();&lt;br /&gt;
&lt;br /&gt;
        // ── Helpers ───────────────────────────────────────────────────────────&lt;br /&gt;
        function resetAndLoad() {&lt;br /&gt;
            generation++;          // Any in-flight request with a lower generation is discarded&lt;br /&gt;
            state.offset = 0;&lt;br /&gt;
            state.done   = false;&lt;br /&gt;
            state.busy   = false;  // Unblock immediately so the new fetch can start&lt;br /&gt;
            $grid.empty();&lt;br /&gt;
            $more.hide();&lt;br /&gt;
            fetchPage();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function buildWhere() {&lt;br /&gt;
            var parts = [];&lt;br /&gt;
            if ( state.search ) {&lt;br /&gt;
                var q = state.search.replace( /&#039;/g, &amp;quot;&#039;&#039;&amp;quot; );&lt;br /&gt;
                parts.push(&lt;br /&gt;
                    &amp;quot;( name LIKE &#039;%&amp;quot; + q + &amp;quot;%&#039;&amp;quot; +&lt;br /&gt;
                    &amp;quot; OR creator LIKE &#039;%&amp;quot; + q + &amp;quot;%&#039;&amp;quot; +&lt;br /&gt;
                    &amp;quot; OR license LIKE &#039;%&amp;quot; + q + &amp;quot;%&#039;&amp;quot; +&lt;br /&gt;
                    &amp;quot; OR description LIKE &#039;%&amp;quot; + q + &amp;quot;%&#039; )&amp;quot;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
            if ( state.tag ) {&lt;br /&gt;
                parts.push( &amp;quot;tags HOLDS &#039;&amp;quot; + state.tag.replace( /&#039;/g, &amp;quot;&#039;&#039;&amp;quot; ) + &amp;quot;&#039;&amp;quot; );&lt;br /&gt;
            }&lt;br /&gt;
            if ( state.license ) {&lt;br /&gt;
                parts.push( &amp;quot;license = &#039;&amp;quot; + state.license.replace( /&#039;/g, &amp;quot;&#039;&#039;&amp;quot; ) + &amp;quot;&#039;&amp;quot; );&lt;br /&gt;
            }&lt;br /&gt;
            return parts.join( &#039; AND &#039; );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function orderBy() {&lt;br /&gt;
            return state.sort === &#039;alpha&#039; ? &#039;name ASC&#039; : &#039;_pageID DESC&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // ── Data ──────────────────────────────────────────────────────────────&lt;br /&gt;
        function fetchPage() {&lt;br /&gt;
            if ( state.busy || state.done ) { return; }&lt;br /&gt;
            state.busy = true;&lt;br /&gt;
            var gen = ++generation;&lt;br /&gt;
            $more.text( &#039;Loading\u2026&#039; ).show();&lt;br /&gt;
&lt;br /&gt;
            var params = {&lt;br /&gt;
                action   : &#039;cargoquery&#039;,&lt;br /&gt;
                tables   : &#039;Projects&#039;,&lt;br /&gt;
                fields   : &#039;_pageName=pagename,name,status,license,creator,&#039; +&lt;br /&gt;
                           &#039;description,image,tags,&#039; +&lt;br /&gt;
                           &#039;field1label,field1value,field2label,field2value,&#039; +&lt;br /&gt;
                           &#039;field3label,field3value,field4label,field4value&#039;,&lt;br /&gt;
                order_by : orderBy(),&lt;br /&gt;
                limit    : PAGE_SIZE,&lt;br /&gt;
                offset   : state.offset,&lt;br /&gt;
                format   : &#039;json&#039;&lt;br /&gt;
            };&lt;br /&gt;
            var w = buildWhere();&lt;br /&gt;
            if ( w ) { params.where = w; }&lt;br /&gt;
            if ( state.offset === 0 ) { fetchTotal( w ); }&lt;br /&gt;
&lt;br /&gt;
            $.getJSON( mw.util.wikiScript( &#039;api&#039; ), params )&lt;br /&gt;
                .done( function ( data ) {&lt;br /&gt;
                    if ( gen !== generation ) { return; } // Stale — discard silently&lt;br /&gt;
&lt;br /&gt;
                    var rows    = ( data.cargoquery || [] ).map( function ( r ) { return r.title; } );&lt;br /&gt;
                    var prevOff = state.offset;&lt;br /&gt;
                    var batch   = [];&lt;br /&gt;
&lt;br /&gt;
                    rows.forEach( function ( row ) {&lt;br /&gt;
                        var $c = buildCard( row );&lt;br /&gt;
                        $grid.append( $c );&lt;br /&gt;
                        batch.push( { $el: $c, page: row.pagename } );&lt;br /&gt;
                    } );&lt;br /&gt;
&lt;br /&gt;
                    enrichCards( batch );&lt;br /&gt;
&lt;br /&gt;
                    state.offset += rows.length;&lt;br /&gt;
                    state.done    = rows.length &amp;lt; PAGE_SIZE;&lt;br /&gt;
                    state.busy    = false;&lt;br /&gt;
&lt;br /&gt;
                    $more.text( &#039;Load more projects&#039; ).toggle( !state.done );&lt;br /&gt;
&lt;br /&gt;
                    if ( rows.length === 0 &amp;amp;&amp;amp; prevOff === 0 ) {&lt;br /&gt;
                        $grid.html( &#039;&amp;lt;div class=&amp;quot;project-hub-empty&amp;quot;&amp;gt;No projects found matching your search.&amp;lt;/div&amp;gt;&#039; );&lt;br /&gt;
                        $more.hide();&lt;br /&gt;
                    }&lt;br /&gt;
                } )&lt;br /&gt;
                .fail( function () {&lt;br /&gt;
                    if ( gen !== generation ) { return; }&lt;br /&gt;
                    state.busy = false;&lt;br /&gt;
                    $more.text( &#039;Load more projects&#039; ).toggle( !state.done );&lt;br /&gt;
                } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function fetchTotal( where ) {&lt;br /&gt;
            var p = { action: &#039;cargoquery&#039;, tables: &#039;Projects&#039;, fields: &#039;COUNT(*)=n&#039;, limit: 1, format: &#039;json&#039; };&lt;br /&gt;
            if ( where ) { p.where = where; }&lt;br /&gt;
            $.getJSON( mw.util.wikiScript( &#039;api&#039; ), p ).done( function ( data ) {&lt;br /&gt;
                var row = ( data.cargoquery || [] )[ 0 ];&lt;br /&gt;
                var n   = row ? ( parseInt( row.title.n, 10 ) || 0 ) : 0;&lt;br /&gt;
                $count.text( n + &#039; project&#039; + ( n === 1 ? &#039;&#039; : &#039;s&#039; ) );&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function loadTagCloud() {&lt;br /&gt;
            $.getJSON( mw.util.wikiScript( &#039;api&#039; ), {&lt;br /&gt;
                action: &#039;cargoquery&#039;, tables: &#039;Projects&#039;, fields: &#039;tags&#039;, limit: 500, format: &#039;json&#039;&lt;br /&gt;
            } ).done( function ( data ) {&lt;br /&gt;
                var freq = {};&lt;br /&gt;
                ( data.cargoquery || [] ).forEach( function ( r ) {&lt;br /&gt;
                    ( r.title.tags || &#039;&#039; ).split( &#039;,&#039; ).forEach( function ( t ) {&lt;br /&gt;
                        t = t.trim();&lt;br /&gt;
                        if ( t ) { freq[ t ] = ( freq[ t ] || 0 ) + 1; }&lt;br /&gt;
                    } );&lt;br /&gt;
                } );&lt;br /&gt;
                var top = Object.keys( freq )&lt;br /&gt;
                    .sort( function ( a, b ) { return freq[ b ] - freq[ a ]; } )&lt;br /&gt;
                    .slice( 0, 25 );&lt;br /&gt;
                if ( !top.length ) { return; }&lt;br /&gt;
                top.forEach( function ( tag ) {&lt;br /&gt;
                    $tagCloud.append(&lt;br /&gt;
                        $( &#039;&amp;lt;span&amp;gt;&#039; ).addClass( &#039;js-tag-filter&#039; ).attr( &#039;data-tag&#039;, tag ).text( tag )&lt;br /&gt;
                    );&lt;br /&gt;
                } );&lt;br /&gt;
                $tagCloud.show();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function loadLicenseCloud() {&lt;br /&gt;
            $.getJSON( mw.util.wikiScript( &#039;api&#039; ), {&lt;br /&gt;
                action   : &#039;cargoquery&#039;,&lt;br /&gt;
                tables   : &#039;Projects&#039;,&lt;br /&gt;
                fields   : &#039;license&#039;,&lt;br /&gt;
                group_by : &#039;license&#039;,&lt;br /&gt;
                where    : &amp;quot;license IS NOT NULL AND license != &#039;&#039;&amp;quot;,&lt;br /&gt;
                order_by : &#039;license ASC&#039;,&lt;br /&gt;
                limit    : 20,&lt;br /&gt;
                format   : &#039;json&#039;&lt;br /&gt;
            } ).done( function ( data ) {&lt;br /&gt;
                var licenses = ( data.cargoquery || [] )&lt;br /&gt;
                    .map( function ( r ) { return ( r.title.license || &#039;&#039; ).trim(); } )&lt;br /&gt;
                    .filter( Boolean );&lt;br /&gt;
                if ( !licenses.length ) { return; }&lt;br /&gt;
                licenses.forEach( function ( lic ) {&lt;br /&gt;
                    $licenseCloud.append(&lt;br /&gt;
                        $( &#039;&amp;lt;span&amp;gt;&#039; ).addClass( &#039;js-license-filter&#039; )&lt;br /&gt;
                            .attr( &#039;data-license&#039;, lic ).text( lic )&lt;br /&gt;
                    );&lt;br /&gt;
                } );&lt;br /&gt;
                $licenseCloud.show();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function loadHubMeta() {&lt;br /&gt;
            mw.loader.using( &#039;mediawiki.api&#039; ).then( function () {&lt;br /&gt;
                new mw.Api().get( {&lt;br /&gt;
                    action: &#039;query&#039;, list: &#039;categorymembers&#039;, cmtitle: &#039;Category:Projects&#039;,&lt;br /&gt;
                    cmsort: &#039;timestamp&#039;, cmdir: &#039;desc&#039;, cmlimit: 1,&lt;br /&gt;
                    cmtype: &#039;page&#039;, cmprop: &#039;ids|title|timestamp&#039;, format: &#039;json&#039;&lt;br /&gt;
                } ).done( function ( data ) {&lt;br /&gt;
                    var m = data.query &amp;amp;&amp;amp; data.query.categorymembers;&lt;br /&gt;
                    if ( !m || !m.length ) { return; }&lt;br /&gt;
                    var str = m[ 0 ].title.replace( /^.*\//, &#039;&#039; ) + &#039; \u2014 &#039; +&lt;br /&gt;
                        ( m[ 0 ].timestamp&lt;br /&gt;
                            ? new Date( m[ 0 ].timestamp ).toLocaleDateString(&lt;br /&gt;
                                &#039;en-GB&#039;, { day: &#039;numeric&#039;, month: &#039;short&#039;, year: &#039;numeric&#039; } )&lt;br /&gt;
                            : &#039;\u2014&#039; );&lt;br /&gt;
                    $( &#039;#hub-meta-last-submission, #hub-meta-last-edit&#039; ).text( str );&lt;br /&gt;
                } );&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // ── Card rendering ────────────────────────────────────────────────────&lt;br /&gt;
        function parseWikitext( text ) {&lt;br /&gt;
            if ( !text ) { return &#039;&#039;; }&lt;br /&gt;
            text = String( text );&lt;br /&gt;
            // External links: [https://url Display Text]&lt;br /&gt;
            text = text.replace( /\[(\S+?)\s+([^\]]+?)\]/g, function ( m, url, display ) {&lt;br /&gt;
                if ( !/^https?:\/\//i.test( url ) ) { return mw.html.escape( m ); }&lt;br /&gt;
                return &#039;&amp;lt;a href=&amp;quot;&#039; + url.replace( /&amp;quot;/g, &#039;%22&#039; ) + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    mw.html.escape( display ) + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
            } );&lt;br /&gt;
            // Internal links: [[Page Name|Display]] or [[Page Name]]&lt;br /&gt;
            text = text.replace( /\[\[([^\]|]+?)(?:\|([^\]]+?))?\]\]/g, function ( m, page, display ) {&lt;br /&gt;
                return &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl( page.trim() ) + &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    mw.html.escape( ( display || page ).trim() ) + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
            } );&lt;br /&gt;
            // Newlines to line breaks&lt;br /&gt;
            text = text.replace( /\n/g, &#039;&amp;lt;br&amp;gt;&#039; );&lt;br /&gt;
            return text;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function esc( s ) { return mw.html.escape( s || &#039;&#039; ); }&lt;br /&gt;
&lt;br /&gt;
        function fileUrl( f ) {&lt;br /&gt;
            return f ? mw.config.get( &#039;wgServer&#039; ) + &#039;/wiki/Special:FilePath/&#039; + encodeURIComponent( f ) : &#039;&#039;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function buildCard( row ) {&lt;br /&gt;
            var page = row.pagename || &#039;&#039;;&lt;br /&gt;
            var name = row.name || page.replace( /^.*\//, &#039;&#039; );&lt;br /&gt;
            var url  = mw.util.getUrl( page );&lt;br /&gt;
&lt;br /&gt;
            var img = row.image&lt;br /&gt;
                ? &#039;&amp;lt;img src=&amp;quot;&#039; + esc( fileUrl( row.image ) ) + &#039;&amp;quot; alt=&amp;quot;&#039; + esc( name ) + &#039;&amp;quot; loading=&amp;quot;lazy&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                : &#039;&amp;lt;div class=&amp;quot;project-card-image-fallback&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            var badges = &#039;&#039;;&lt;br /&gt;
            if ( row.status ) {&lt;br /&gt;
                badges += &#039;&amp;lt;span class=&amp;quot;project-badge-status project-badge-status--&#039; +&lt;br /&gt;
                    esc( row.status.toLowerCase() ) + &#039;&amp;quot;&amp;gt;&#039; + esc( row.status ) + &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
            }&lt;br /&gt;
            if ( row.license ) {&lt;br /&gt;
                badges += &#039;&amp;lt;span class=&amp;quot;project-badge-license&amp;quot;&amp;gt;&#039; + esc( row.license ) + &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var tags = &#039;&#039;;&lt;br /&gt;
            ( row.tags || &#039;&#039; ).split( &#039;,&#039; ).forEach( function ( t ) {&lt;br /&gt;
                t = t.trim();&lt;br /&gt;
                if ( t ) {&lt;br /&gt;
                    tags += &#039;&amp;lt;span class=&amp;quot;project-card-tag js-tag-filter&amp;quot; data-tag=&amp;quot;&#039; +&lt;br /&gt;
                        esc( t ) + &#039;&amp;quot;&amp;gt;&#039; + esc( t ) + &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
                }&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
            var extras = &#039;&#039;;&lt;br /&gt;
            for ( var i = 1; i &amp;lt;= 4; i++ ) {&lt;br /&gt;
                if ( row[ &#039;field&#039; + i + &#039;label&#039; ] ) {&lt;br /&gt;
                    extras += &#039;&amp;lt;div class=&amp;quot;project-card-extra&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                        esc( row[ &#039;field&#039; + i + &#039;label&#039; ] ) +&lt;br /&gt;
                        &#039;: &amp;lt;strong&amp;gt;&#039; + parseWikitext( row[ &#039;field&#039; + i + &#039;value&#039; ] ) + &#039;&amp;lt;/strong&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return $( [&lt;br /&gt;
                &#039;&amp;lt;div class=&amp;quot;project-card-wrap&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                  &#039;&amp;lt;div class=&amp;quot;project-card&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;project-card-inner&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                      &#039;&amp;lt;div class=&amp;quot;project-card-front&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;project-card-image&amp;quot;&amp;gt;&#039;, img, &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;project-card-body&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                          &#039;&amp;lt;div class=&amp;quot;project-card-title&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;&#039;, url, &#039;&amp;quot;&amp;gt;&#039;, esc( name ), &#039;&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                          &#039;&amp;lt;div class=&amp;quot;project-card-badges&amp;quot;&amp;gt;&#039;, badges, &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                          row.creator ? &#039;&amp;lt;div class=&amp;quot;project-card-creator&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;project-card-label&amp;quot;&amp;gt;By&amp;lt;/span&amp;gt; &#039; + esc( row.creator ) + &#039;&amp;lt;/div&amp;gt;&#039; : &#039;&#039;,&lt;br /&gt;
                          extras,&lt;br /&gt;
                          tags ? &#039;&amp;lt;div class=&amp;quot;project-card-tags&amp;quot;&amp;gt;&#039; + tags + &#039;&amp;lt;/div&amp;gt;&#039; : &#039;&#039;,&lt;br /&gt;
                          &#039;&amp;lt;div class=&amp;quot;project-card-footer&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;span class=&amp;quot;project-card-meta-item project-card-contributors&amp;quot;&amp;gt;—&amp;lt;/span&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;span class=&amp;quot;project-card-meta-item project-card-updated&amp;quot;&amp;gt;—&amp;lt;/span&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;js-flip-btn project-card-flip-btn&amp;quot;&amp;gt;Read more&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
                          &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                      &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                      &#039;&amp;lt;div class=&amp;quot;project-card-back&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                         &#039;&amp;lt;div class=&amp;quot;project-card-back-header&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;span class=&amp;quot;project-card-back-title&amp;quot;&amp;gt;About&amp;lt;/span&amp;gt;&#039;,&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;js-flip-btn project-card-flip-btn&amp;quot;&amp;gt;Close&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
                         &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                         &#039;&amp;lt;div class=&amp;quot;project-card-back-content&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                            row.description ? esc( row.description ) : &#039;No description provided.&#039;,&lt;br /&gt;
                         &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                      &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                    &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                  &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
            ].join( &#039;&#039; ) );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // ── Enrichment (contributor count + last-edited date) ─────────────────&lt;br /&gt;
        function enrichCards( batch ) {&lt;br /&gt;
            if ( !batch.length ) { return; }&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            for ( var i = 0; i &amp;lt; batch.length; i += 20 ) {&lt;br /&gt;
                ( function ( chunk ) {&lt;br /&gt;
                    api.get( {&lt;br /&gt;
                        action: &#039;query&#039;,&lt;br /&gt;
                        titles: chunk.map( function ( c ) { return c.page; } ).join( &#039;|&#039; ),&lt;br /&gt;
                        prop: &#039;revisions|contributors&#039;,&lt;br /&gt;
                        rvprop: &#039;timestamp&#039;, rvlimit: 1, pclimit: 20,&lt;br /&gt;
                        format: &#039;json&#039;&lt;br /&gt;
                    } ).done( function ( data ) {&lt;br /&gt;
                        if ( !data.query ) { return; }&lt;br /&gt;
                        $.each( data.query.pages || {}, function ( _, page ) {&lt;br /&gt;
                            if ( page.missing !== undefined ) { return; }&lt;br /&gt;
                            var normalise = function ( s ) { return ( s || &#039;&#039; ).replace( /_/g, &#039; &#039; ); };&lt;br /&gt;
                            var match = chunk.filter( function ( c ) { return normalise( c.page ) === normalise( page.title ); } );&lt;br /&gt;
                            if ( !match.length ) { return; }&lt;br /&gt;
                            var $el = match[ 0 ].$el;&lt;br /&gt;
                            var ts  = ( page.revisions &amp;amp;&amp;amp; page.revisions[ 0 ] &amp;amp;&amp;amp; page.revisions[ 0 ].timestamp ) || &#039;&#039;;&lt;br /&gt;
                            var n   = ( page.contributors ? page.contributors.length : 0 ) + ( page.anoncontributors || 0 );&lt;br /&gt;
                            var d   = ts ? new Date( ts ).toLocaleDateString( &#039;en-GB&#039;, { year: &#039;numeric&#039;, month: &#039;short&#039; } ) : &#039;\u2014&#039;;&lt;br /&gt;
                            $el.find( &#039;.project-card-contributors&#039; )&lt;br /&gt;
                               .text( n + ( n === 1 ? &#039; contributor&#039; : &#039; contributors&#039; ) ).addClass( &#039;loaded&#039; );&lt;br /&gt;
                            $el.find( &#039;.project-card-updated&#039; )&lt;br /&gt;
                               .text( &#039;Edited &#039; + d ).addClass( &#039;loaded&#039; );&lt;br /&gt;
                        } );&lt;br /&gt;
                    } );&lt;br /&gt;
                } )( batch.slice( i, i + 20 ) );&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} () );&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Tutorial&amp;diff=1200</id>
		<title>Form:Submit Tutorial</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Tutorial&amp;diff=1200"/>
		<updated>2026-04-05T00:33:35Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Trying to fix bug with New tutorials going to root wiki directory&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{{info|page name=Tutorials/&amp;lt;TutorialMeta[name]&amp;gt;}}}&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{SubpageNav| icon=emotes-face-smile-big}}&lt;br /&gt;
&lt;br /&gt;
{{{for template|TutorialMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Tutorial Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Tutorial Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown on hover over the tutorial card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, beginner, recording}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Tutorial}}} {{{standard input|cancel}}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1199</id>
		<title>Form:Submit Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1199"/>
		<updated>2026-04-05T00:30:36Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Fixed Bug with &amp;lt;name&amp;gt; causing parsing error&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{{info|page name=Projects/&amp;lt;ProjectMeta[name]&amp;gt;}}}&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{SubpageNav| icon=emotes-face-smile-big}}&lt;br /&gt;
&lt;br /&gt;
{{{for template|ProjectMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Project Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Project Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Status:&lt;br /&gt;
| {{{field|status|input type=dropdown|values=Active,Hiatus,Completed,Abandoned|default=Active}}}&lt;br /&gt;
|-&lt;br /&gt;
! License:&lt;br /&gt;
| {{{field|license|input type=dropdown|values=CC0 1.0,CC BY 4.0,CC BY-SA 4.0,MIT,Apache 2.0,GPL-3.0,AGPL-3.0,LGPL-3.0,BSD-3-Clause,MPL-2.0,EPL-2.0,EUPL-1.2}}}&lt;br /&gt;
|-&lt;br /&gt;
! Creator / Team:&lt;br /&gt;
| {{{field|creator|input type=text|size=40|placeholder=Your name or team name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown on hover over your project card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, ambient, synthesis}}}&lt;br /&gt;
|-&lt;br /&gt;
! Website:&lt;br /&gt;
| {{{field|website|input type=text|size=60|placeholder=example.com}}}&lt;br /&gt;
|-&lt;br /&gt;
! Repository:&lt;br /&gt;
| {{{field|repository|input type=text|size=60|placeholder=https://codeberg.org/...}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Label:&lt;br /&gt;
| {{{field|field1label|input type=text|size=30|placeholder=e.g. DAW}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Value:&lt;br /&gt;
| {{{field|field1value|input type=text|size=30|placeholder=e.g. Ableton}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Label:&lt;br /&gt;
| {{{field|field2label|input type=text|size=30|placeholder=e.g. Genre}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Value:&lt;br /&gt;
| {{{field|field2value|input type=text|size=30|placeholder=e.g. Ambient}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Label:&lt;br /&gt;
| {{{field|field3label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Value:&lt;br /&gt;
| {{{field|field3value|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Label:&lt;br /&gt;
| {{{field|field4label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Value:&lt;br /&gt;
| {{{field|field4value|input type=text|size=30}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Project}}} {{{standard input|cancel}}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Window_Manager_Central&amp;diff=1198</id>
		<title>Projects/Window Manager Central</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Window_Manager_Central&amp;diff=1198"/>
		<updated>2026-04-05T00:19:50Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Fixed broken website link in ProjectMeta (Removed https://)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProjectMeta&lt;br /&gt;
|name=Window Manager Central&lt;br /&gt;
|status=Active&lt;br /&gt;
|description=Window Manager Cenral is small website where you can learn about window managers and hit the ground running with a fast new workflow. Discover guides, tips and resources for all levels of familiarity.&lt;br /&gt;
|website=wmc.codeberg.page&lt;br /&gt;
|repository=https://codeberg.org/wmc/pages-src&lt;br /&gt;
}}This is a small website project intending to serve as a dictionary of tips for window manager users. The idea is that anyone can upload tips, edit and improve the information available so that newcomers to window managers find it easier to start their journey.&lt;br /&gt;
&lt;br /&gt;
It is particularly difficult for newcomers to find guides, more so with good guides, when things go south the most usual response is to give up on window managers altogether. Having one place (ideally) that points to all the guides that one may need, as well as other sources of interest should facilitate the pain of using a search engine over and over.&lt;br /&gt;
&lt;br /&gt;
The point is not to babysit newcomers, but to point them in the right direction. While experienced users don&#039;t need regular help, they will definitely enjoy having a collection of resources instead of having the usual search engine route. They could find particular pleasure in sharing their own guides and mishaps that newbies will want to avoid.&lt;br /&gt;
&lt;br /&gt;
The website is build with [https://gohugo.io Hugo] and hosted on [https://codeberg.page Codeberg Pages], contributing for people familiar with Git is easy, it is just a pull request away. For other ways of contributing one can get in contact with the team.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1197</id>
		<title>Projects/Example Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1197"/>
		<updated>2026-04-05T00:14:19Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Undo revision 1196 by Anthony (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【Text 🟢 Yes 】 【 Images 🔴 No 】 【 Code 🟠 Depends* 】&lt;br /&gt;
| details = LLM Generated text and code must be thoroughly reviewed and proofread. . .it should be used as a tool to &#039;&#039;assist&#039;&#039; and enhance your contributions, not replace them. *Code is allowed only if a) it is manually proofread and checked for quality or b) it is used as a temporary proof of concept/demo and is clearly labeled as such.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
| name        = Example Project&lt;br /&gt;
| status      = Completed&lt;br /&gt;
| license     = CC BY-SA 4.0&lt;br /&gt;
| creator     = UnfinishedProjects&lt;br /&gt;
| description = This is an example project. It demonstrates how a project page should be set up.&lt;br /&gt;
| image       = Unfinished Projects Logo x512.png&lt;br /&gt;
| tags        = example, demo, template&lt;br /&gt;
| website     = forum.unfinishedprojects.net&lt;br /&gt;
| repository  = https://codeberg.org/UnfinishedProjects/UnfinishedProjects.net&lt;br /&gt;
| field1label = Current Project Lead&lt;br /&gt;
| field1value = [https://forum.unfinishedprojects.net/user/unfinishedprojects UnfinishedProjects]&lt;br /&gt;
| field2label = Contributors&lt;br /&gt;
| field2value = [https://forum.unfinishedprojects.net/user/anthony Anthony]&lt;br /&gt;
&lt;br /&gt;
[https://forum.unfinishedprojects.net/user/www-gem www-gem]&lt;br /&gt;
&lt;br /&gt;
[https://forum.unfinishedprojects.net/user/alectronic alectronic]&lt;br /&gt;
| field3label = Forked From&lt;br /&gt;
| field3value = [[Example Page| Another Project (Creator Name)]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Animi et et quis ut totam inventore. Eligendi est ut ullam voluptatibus dolorum ex. In quisquam est enim soluta distinctio explicabo quidem voluptatem. Maxime neque dolor id in sunt quisquam quos.&lt;br /&gt;
&lt;br /&gt;
Maiores in dolores laborum molestiae possimus. Ipsum ut et rerum. Neque et perspiciatis eaque autem unde molestias omnis voluptatem.&lt;br /&gt;
&lt;br /&gt;
Aspernatur ut non impedit ea natus eveniet distinctio. Perferendis non eveniet in nihil aut. Quo aut atque natus quisquam laboriosam.&lt;br /&gt;
&lt;br /&gt;
Dolor cumque sed quia quia quis debitis minus ipsa. Veniam recusandae voluptatem quia aut possimus veritatis. Omnis dolores unde quibusdam fugit officiis fugiat. Porro vel qui quia sequi enim nesciunt at. Omnis consequatur veniam quisquam numquam.&lt;br /&gt;
&lt;br /&gt;
Suscipit ipsum impedit reprehenderit magni asperiores tempore tenetur. Id consequatur aut earum voluptas autem qui. Cum laboriosam suscipit est autem non voluptatem aut. Quae error repellendus libero aliquam. Quod quia atque qui doloremque est cupiditate libero. Necessitatibus illum provident et.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1196</id>
		<title>Projects/Example Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1196"/>
		<updated>2026-04-05T00:13:29Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Reverting to old version to see if it fixes some javascript errors on the hub.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【Text 🟢 Yes 】 【 Images 🔴 No 】 【 Code 🟠 Depends* 】&lt;br /&gt;
| details = LLM Generated text and code must be thoroughly reviewed and proofread. . .it should be used as a tool to &#039;&#039;assist&#039;&#039; and enhance your contributions, not replace them. *Code is allowed only if a) it is manually proofread and checked for quality or b) it is used as a temporary proof of concept/demo and is clearly labeled as such.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
| name        = Example Project&lt;br /&gt;
| status      = Completed&lt;br /&gt;
| license     = CC-BY-SA 4.0&lt;br /&gt;
| creator     = UnfinishedProjects&lt;br /&gt;
| description = This is an example project. It demonstrates how a project page should be set up.&lt;br /&gt;
| image       = Unfinished Projects Logo x512.png&lt;br /&gt;
| tags        = example, demo, template&lt;br /&gt;
| website     = forum.unfinishedprojects.net&lt;br /&gt;
| repository  = https://codeberg.org/UnfinishedProjects/UnfinishedProjects.net&lt;br /&gt;
| field1label = Extra Label&lt;br /&gt;
| field1value = Value&lt;br /&gt;
| field2label = Another Label&lt;br /&gt;
| field2value = Another Value&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Animi et et quis ut totam inventore. Eligendi est ut ullam voluptatibus dolorum ex. In quisquam est enim soluta distinctio explicabo quidem voluptatem. Maxime neque dolor id in sunt quisquam quos.&lt;br /&gt;
&lt;br /&gt;
Maiores in dolores laborum molestiae possimus. Ipsum ut et rerum. Neque et perspiciatis eaque autem unde molestias omnis voluptatem.&lt;br /&gt;
&lt;br /&gt;
Aspernatur ut non impedit ea natus eveniet distinctio. Perferendis non eveniet in nihil aut. Quo aut atque natus quisquam laboriosam.&lt;br /&gt;
&lt;br /&gt;
Dolor cumque sed quia quia quis debitis minus ipsa. Veniam recusandae voluptatem quia aut possimus veritatis. Omnis dolores unde quibusdam fugit officiis fugiat. Porro vel qui quia sequi enim nesciunt at. Omnis consequatur veniam quisquam numquam.&lt;br /&gt;
&lt;br /&gt;
Suscipit ipsum impedit reprehenderit magni asperiores tempore tenetur. Id consequatur aut earum voluptas autem qui. Cum laboriosam suscipit est autem non voluptatem aut. Quae error repellendus libero aliquam. Quod quia atque qui doloremque est cupiditate libero. Necessitatibus illum provident et.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1191</id>
		<title>Form:Submit Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1191"/>
		<updated>2026-04-04T14:34:09Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Undo revision 1189 by Anthony (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{{info|page name=Projects/&amp;lt;name&amp;gt;}}}&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{SubpageNav| icon=emotes-face-smile-big}}&lt;br /&gt;
&lt;br /&gt;
{{{for template|ProjectMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Project Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Project Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Status:&lt;br /&gt;
| {{{field|status|input type=dropdown|values=Active,Hiatus,Completed,Abandoned|default=Active}}}&lt;br /&gt;
|-&lt;br /&gt;
! License:&lt;br /&gt;
| {{{field|license|input type=dropdown|values=CC0 1.0,CC BY 4.0,CC BY-SA 4.0,MIT,Apache 2.0,GPL-3.0,AGPL-3.0,LGPL-3.0,BSD-3-Clause,MPL-2.0,EPL-2.0,EUPL-1.2,Other}}}&lt;br /&gt;
| {{{field|license|input type=dropdown|values=}}}&lt;br /&gt;
|-&lt;br /&gt;
! Creator / Team:&lt;br /&gt;
| {{{field|creator|input type=text|size=40|placeholder=Your name or team name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown on hover over your project card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, ambient, synthesis}}}&lt;br /&gt;
|-&lt;br /&gt;
! Website:&lt;br /&gt;
| {{{field|website|input type=text|size=60|placeholder=example.com}}}&lt;br /&gt;
|-&lt;br /&gt;
! Repository:&lt;br /&gt;
| {{{field|repository|input type=text|size=60|placeholder=https://codeberg.org/...}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Label:&lt;br /&gt;
| {{{field|field1label|input type=text|size=30|placeholder=e.g. DAW}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Value:&lt;br /&gt;
| {{{field|field1value|input type=text|size=30|placeholder=e.g. Ableton}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Label:&lt;br /&gt;
| {{{field|field2label|input type=text|size=30|placeholder=e.g. Genre}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Value:&lt;br /&gt;
| {{{field|field2value|input type=text|size=30|placeholder=e.g. Ambient}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Label:&lt;br /&gt;
| {{{field|field3label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Value:&lt;br /&gt;
| {{{field|field3value|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Label:&lt;br /&gt;
| {{{field|field4label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Value:&lt;br /&gt;
| {{{field|field4value|input type=text|size=30}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Project}}} {{{standard input|cancel}}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1189</id>
		<title>Form:Submit Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1189"/>
		<updated>2026-04-04T14:29:35Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Fixed bugs for form pathing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
This is the &amp;quot;Project&amp;quot; form.&lt;br /&gt;
To create a page with this form, enter the project name below:&lt;br /&gt;
{{#forminput:form=Project|button text=Create Project Page}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&lt;br /&gt;
{{{info|page name=Projects/&amp;lt;ProjectMeta[name]&amp;gt;}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{SubpageNav| icon=emotes-face-smile-big}}&lt;br /&gt;
&lt;br /&gt;
{{{for template|ProjectMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Project Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Project Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Status:&lt;br /&gt;
| {{{field|status|input type=dropdown|values=Active,Hiatus,Completed,Abandoned|default=Active}}}&lt;br /&gt;
|-&lt;br /&gt;
! License:&lt;br /&gt;
| {{{field|license|input type=dropdown|values=CC0 1.0,CC BY 4.0,CC BY-SA 4.0,MIT,Apache 2.0,GPL-3.0,AGPL-3.0,LGPL-3.0,BSD-3-Clause,MPL-2.0,EPL-2.0,EUPL-1.2,Other}}}&lt;br /&gt;
|-&lt;br /&gt;
! Creator / Team:&lt;br /&gt;
| {{{field|creator|input type=text|size=40|placeholder=Your name or team name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown on hover over your project card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, ambient, synthesis}}}&lt;br /&gt;
|-&lt;br /&gt;
! Website:&lt;br /&gt;
| {{{field|website|input type=text|size=60|placeholder=example.com}}}&lt;br /&gt;
|-&lt;br /&gt;
! Repository:&lt;br /&gt;
| {{{field|repository|input type=text|size=60|placeholder=https://codeberg.org/...}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Label:&lt;br /&gt;
| {{{field|field1label|input type=text|size=30|placeholder=e.g. DAW}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Value:&lt;br /&gt;
| {{{field|field1value|input type=text|size=30|placeholder=e.g. Ableton}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Label:&lt;br /&gt;
| {{{field|field2label|input type=text|size=30|placeholder=e.g. Genre}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Value:&lt;br /&gt;
| {{{field|field2value|input type=text|size=30|placeholder=e.g. Ambient}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Label:&lt;br /&gt;
| {{{field|field3label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Value:&lt;br /&gt;
| {{{field|field3value|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Label:&lt;br /&gt;
| {{{field|field4label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Value:&lt;br /&gt;
| {{{field|field4value|input type=text|size=30}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Project}}} {{{standard input|cancel}}}&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=File:Amalgam_Logo.png&amp;diff=1187</id>
		<title>File:Amalgam Logo.png</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=File:Amalgam_Logo.png&amp;diff=1187"/>
		<updated>2026-04-04T14:19:50Z</updated>

		<summary type="html">&lt;p&gt;Anthony: A Simple Logo for Amalgam Board Game. Will likely get replaced in the future.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
A Simple Logo for Amalgam Board Game. Will likely get replaced in the future.&lt;br /&gt;
== Licensing ==&lt;br /&gt;
{{CC-BY-SA-4.0}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=MediaWiki:Licenses&amp;diff=1186</id>
		<title>MediaWiki:Licenses</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=MediaWiki:Licenses&amp;diff=1186"/>
		<updated>2026-04-04T14:15:18Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Removed vague licenses&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Free &amp;amp; Open Licenses (Recommended)&lt;br /&gt;
** CC-BY-SA-4.0|Creative Commons Attribution-ShareAlike 4.0 (Default - Assets)&lt;br /&gt;
** CC-BY-4.0|Creative Commons Attribution 4.0&lt;br /&gt;
** PD|Public Domain / CC0 1.0&lt;br /&gt;
** AGPL-3.0|GNU Affero General Public License v3.0 (Default - Code)&lt;br /&gt;
** GPL-3.0|GNU General Public License v3.0&lt;br /&gt;
** MIT|MIT License&lt;br /&gt;
** BSD-3-Clause|3-Clause BSD License&lt;br /&gt;
** Apache-2.0|Apache License 2.0&lt;br /&gt;
&lt;br /&gt;
* More Open Source Licenses&lt;br /&gt;
** LGPL-3.0|GNU Lesser General Public License v3.0&lt;br /&gt;
** MPL-2.0|Mozilla Public License 2.0&lt;br /&gt;
** EPL-2.0|Eclipse Public License 2.0&lt;br /&gt;
** EUPL-1.2|European Union Public License 1.2&lt;br /&gt;
** Other|Other Open License (Specify in summary)&lt;br /&gt;
&lt;br /&gt;
* Wiki Specific&lt;br /&gt;
** UP-screenshot|UnfinishedProjects Screenshot (CC-BY-SA 4.0 + Captured Content Licensing)&lt;br /&gt;
&lt;br /&gt;
* Non-Free / Protected (Exceptions)&lt;br /&gt;
** Logo|Fair Use: Official Logo (Trademarked, low-res, for brand identification only)&lt;br /&gt;
&lt;br /&gt;
* Non-Compliant&lt;br /&gt;
** None|Unknown / No license (Warning: File will be removed - DO NOT UPLOAD)&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1185</id>
		<title>Form:Submit Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Form:Submit_Project&amp;diff=1185"/>
		<updated>2026-04-04T14:12:47Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Removed Vague licenses&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{{info|page name=Projects/&amp;lt;name&amp;gt;}}}&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #aaa;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{SubpageNav| icon=emotes-face-smile-big}}&lt;br /&gt;
&lt;br /&gt;
{{{for template|ProjectMeta}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Project Name:&lt;br /&gt;
| {{{field|name|input type=text|mandatory|size=60|placeholder=My Project Name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Status:&lt;br /&gt;
| {{{field|status|input type=dropdown|values=Active,Hiatus,Completed,Abandoned|default=Active}}}&lt;br /&gt;
|-&lt;br /&gt;
! License:&lt;br /&gt;
| {{{field|license|input type=dropdown|values=CC0 1.0,CC BY 4.0,CC BY-SA 4.0,MIT,Apache 2.0,GPL-3.0,AGPL-3.0,LGPL-3.0,BSD-3-Clause,MPL-2.0,EPL-2.0,EUPL-1.2,Other}}}&lt;br /&gt;
| {{{field|license|input type=dropdown|values=}}}&lt;br /&gt;
|-&lt;br /&gt;
! Creator / Team:&lt;br /&gt;
| {{{field|creator|input type=text|size=40|placeholder=Your name or team name}}}&lt;br /&gt;
|-&lt;br /&gt;
! Short Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=3|cols=60|placeholder=A short description shown on hover over your project card.}}}&lt;br /&gt;
|-&lt;br /&gt;
! Cover Image:&lt;br /&gt;
| {{{field|image|input type=text|size=40|placeholder=MyImage.png (upload the file first)}}}&lt;br /&gt;
|-&lt;br /&gt;
! Tags:&lt;br /&gt;
| {{{field|tags|input type=text|size=60|placeholder=Comma-separated tags, e.g.: audio, ambient, synthesis}}}&lt;br /&gt;
|-&lt;br /&gt;
! Website:&lt;br /&gt;
| {{{field|website|input type=text|size=60|placeholder=example.com}}}&lt;br /&gt;
|-&lt;br /&gt;
! Repository:&lt;br /&gt;
| {{{field|repository|input type=text|size=60|placeholder=https://codeberg.org/...}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Label:&lt;br /&gt;
| {{{field|field1label|input type=text|size=30|placeholder=e.g. DAW}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 1 Value:&lt;br /&gt;
| {{{field|field1value|input type=text|size=30|placeholder=e.g. Ableton}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Label:&lt;br /&gt;
| {{{field|field2label|input type=text|size=30|placeholder=e.g. Genre}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 2 Value:&lt;br /&gt;
| {{{field|field2value|input type=text|size=30|placeholder=e.g. Ambient}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Label:&lt;br /&gt;
| {{{field|field3label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 3 Value:&lt;br /&gt;
| {{{field|field3value|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Label:&lt;br /&gt;
| {{{field|field4label|input type=text|size=30}}}&lt;br /&gt;
|-&lt;br /&gt;
! Extra Field 4 Value:&lt;br /&gt;
| {{{field|field4value|input type=text|size=30}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save|label=Submit Project}}} {{{standard input|cancel}}}&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
	<entry>
		<id>https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1184</id>
		<title>Projects/Example Project</title>
		<link rel="alternate" type="text/html" href="https://unfinishedprojects.net/index.php?title=Projects/Example_Project&amp;diff=1184"/>
		<updated>2026-04-04T14:07:59Z</updated>

		<summary type="html">&lt;p&gt;Anthony: Fixed license after updating form&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SubpageNav}}&lt;br /&gt;
{{AIBanner&lt;br /&gt;
| acceptability = 【Text 🟢 Yes 】 【 Images 🔴 No 】 【 Code 🟠 Depends* 】&lt;br /&gt;
| details = LLM Generated text and code must be thoroughly reviewed and proofread. . .it should be used as a tool to &#039;&#039;assist&#039;&#039; and enhance your contributions, not replace them. *Code is allowed only if a) it is manually proofread and checked for quality or b) it is used as a temporary proof of concept/demo and is clearly labeled as such.&lt;br /&gt;
}}&lt;br /&gt;
{{ProjectMeta&lt;br /&gt;
| name        = Example Project&lt;br /&gt;
| status      = Completed&lt;br /&gt;
| license     = CC BY-SA 4.0&lt;br /&gt;
| creator     = UnfinishedProjects&lt;br /&gt;
| description = This is an example project. It demonstrates how a project page should be set up.&lt;br /&gt;
| image       = Unfinished Projects Logo x512.png&lt;br /&gt;
| tags        = example, demo, template&lt;br /&gt;
| website     = forum.unfinishedprojects.net&lt;br /&gt;
| repository  = https://codeberg.org/UnfinishedProjects/UnfinishedProjects.net&lt;br /&gt;
| field1label = Current Project Lead&lt;br /&gt;
| field1value = [https://forum.unfinishedprojects.net/user/unfinishedprojects UnfinishedProjects]&lt;br /&gt;
| field2label = Contributors&lt;br /&gt;
| field2value = [https://forum.unfinishedprojects.net/user/anthony Anthony]&lt;br /&gt;
&lt;br /&gt;
[https://forum.unfinishedprojects.net/user/www-gem www-gem]&lt;br /&gt;
&lt;br /&gt;
[https://forum.unfinishedprojects.net/user/alectronic alectronic]&lt;br /&gt;
| field3label = Forked From&lt;br /&gt;
| field3value = [[Example Page| Another Project (Creator Name)]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Animi et et quis ut totam inventore. Eligendi est ut ullam voluptatibus dolorum ex. In quisquam est enim soluta distinctio explicabo quidem voluptatem. Maxime neque dolor id in sunt quisquam quos.&lt;br /&gt;
&lt;br /&gt;
Maiores in dolores laborum molestiae possimus. Ipsum ut et rerum. Neque et perspiciatis eaque autem unde molestias omnis voluptatem.&lt;br /&gt;
&lt;br /&gt;
Aspernatur ut non impedit ea natus eveniet distinctio. Perferendis non eveniet in nihil aut. Quo aut atque natus quisquam laboriosam.&lt;br /&gt;
&lt;br /&gt;
Dolor cumque sed quia quia quis debitis minus ipsa. Veniam recusandae voluptatem quia aut possimus veritatis. Omnis dolores unde quibusdam fugit officiis fugiat. Porro vel qui quia sequi enim nesciunt at. Omnis consequatur veniam quisquam numquam.&lt;br /&gt;
&lt;br /&gt;
Suscipit ipsum impedit reprehenderit magni asperiores tempore tenetur. Id consequatur aut earum voluptas autem qui. Cum laboriosam suscipit est autem non voluptatem aut. Quae error repellendus libero aliquam. Quod quia atque qui doloremque est cupiditate libero. Necessitatibus illum provident et.&lt;/div&gt;</summary>
		<author><name>Anthony</name></author>
	</entry>
</feed>