diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..1b6386d
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,6 @@
+# Screens PR
+> I certify that these images I'm adding have been tested at [tailor.trmnl.com](https://tailor.trmnl.com)
+
+For all imagery used in these images, I have the right to publish them as CC0 licensed files.
+**OR**
+All imagery can be distributed freely and was sourced here:
\ No newline at end of file
diff --git a/.github/workflows/validate-images.yml b/.github/workflows/validate-images.yml
new file mode 100644
index 0000000..76a842c
--- /dev/null
+++ b/.github/workflows/validate-images.yml
@@ -0,0 +1,41 @@
+name: Image Validation and Gallery Update
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ paths:
+ - 'screens/800x480/**'
+
+jobs:
+ process-images:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write # Needed to push the GALLERY.md update
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Validate PNG dimensions
+ run: |
+ FILES=$(find screens/800x480 -name "*.png")
+ for FILE in $FILES; do
+ DIMENSIONS=$(identify -format "%wx%h" "$FILE")
+ if [ "$DIMENSIONS" != "800x480" ]; then
+ echo "::error file=$FILE::Invalid dimensions: $DIMENSIONS. Must be 800x480."
+ exit 1
+ fi
+ done
+
+ - name: Generate Gallery
+ run: python3 generate_gallery.py
+
+ - name: Commit and Push Gallery
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
+ run: |
+ git config --global user.name "Gallery Bot"
+ git config --global user.email "bot@github.com"
+ git add GALLERY_800x480.md
+ git diff --quiet && git diff --staged --quiet || (git commit -m "docs: update 800x480 gallery" && git push)
\ No newline at end of file
diff --git a/README.md b/README.md
index ea2c8c1..3c74ea6 100644
--- a/README.md
+++ b/README.md
@@ -15,3 +15,28 @@ You can make customizations to the following brand attributes
4. Install emscripten eg: `brew install emscripten`
5. Compile and create a wasm file `bash build.sh`
6. open `index.html` on your browser.
+
+# Community Screens
+[tailor.trmnl.com](https://tailor.trmnl.com/)
+Customize TRMNL with Tailor, our firmware tool that writes custom splash and loading screens for your TRMNL device.
+
+## Devices Supported
+- TRMNL OG (800x480)
+
+## Folder and File Structure
+```
+screens/
+├─ 800x480/
+│ ├─ CATEGORY/
+│ │ ├─ splash/
+│ │ ├─ loading/
+```
+> New categories and subsequent folders can be created as part of a Pull Request.
+
+### Filename Structure
+Hyphen separated sections, with underscore for spaces within a section. _Credit is optional._
+**WIDTHxHEIGHT-TYPE-UNIQUE_NAME-CREDIT?.png**
+_e.g._
+`800x480-splash-dungeon_crawler_carl_safehouse-mashermello.png`
+`800x480-loading-dungeon_crawler_carl_princess_donut.png`
+
diff --git a/generate_gallery.py b/generate_gallery.py
new file mode 100644
index 0000000..1557435
--- /dev/null
+++ b/generate_gallery.py
@@ -0,0 +1,59 @@
+import os
+import urllib.parse
+
+# Configuration
+BASE_DIR = "screens/800x480"
+OUTPUT_FILE = "GALLERY_800x480.md"
+REPO_URL = "https://github.com/usetrmnl/trmnl-designs/raw/main"
+
+def generate_gallery():
+ # Adjusted title and back-link reference for the specific size
+ markdown = [
+ "# 🖼️ 800x480 Screen Gallery",
+ "Browse and download splash and loading screens for TRMNL OG. All images are pre-validated to **800x480 PNG**.\n",
+ "> **Tip:** Right-click 'Download' and select 'Save Link As...' to save directly to your device.\n"
+ ]
+
+ if not os.path.exists(BASE_DIR):
+ print(f"Directory {BASE_DIR} not found. Skipping.")
+ return
+
+ # Table of Contents
+ categories = sorted([d for d in os.listdir(BASE_DIR) if os.path.isdir(os.path.join(BASE_DIR, d))])
+ markdown.append("### 📂 Categories")
+ for cat in categories:
+ markdown.append(f"- [{cat.replace('_', ' ').title()}](#{cat.lower()})")
+ markdown.append("\n---\n")
+
+ for category in categories:
+ cat_name = category.replace('_', ' ').title()
+ markdown.append(f"## {cat_name}")
+ markdown.append("| Type | Preview | Action |")
+ markdown.append("| :--- | :--- | :--- |")
+
+ cat_path = os.path.join(BASE_DIR, category)
+ for sub in ["splash", "loading"]:
+ sub_path = os.path.join(cat_path, sub)
+ if os.path.exists(sub_path):
+ files = sorted([f for f in os.listdir(sub_path) if f.lower().endswith('.png')])
+ for f in files:
+ img_path = f"{sub_path}/{f}"
+ encoded_path = urllib.parse.quote(img_path)
+ download_url = f"{REPO_URL}/{encoded_path}"
+
+ # Using HTML for controlled scaling in the Markdown table
+ preview = f'
'
+ download_link = f"**[💾 Download]({download_url})**"
+
+ markdown.append(f"| {sub.capitalize()} | {preview} | {download_link}
`{f}` |")
+
+ # Anchor link back to the specific 800x480 header
+ markdown.append("\n[↑ Back to Top](#-800x480-screen-gallery)\n")
+ markdown.append("---\n")
+
+ with open(OUTPUT_FILE, "w") as f:
+ f.write("\n".join(markdown))
+ print(f"Successfully generated {OUTPUT_FILE}")
+
+if __name__ == "__main__":
+ generate_gallery()
\ No newline at end of file