diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index feac4a0..6016464 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -25,5 +25,11 @@ jobs: - name: Validate canonical catalogue surfaces run: python3 scripts/validate_catalog.py --base-ref "${{ github.event.pull_request.base.sha }}" + - name: Install preview validation dependency + run: python3 -m pip install -r requirements-dev.txt + + - name: Validate preview timing and still alternatives + run: python3 scripts/validate_previews.py + - name: Check patch whitespace run: git diff --check "${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}" diff --git a/.gitignore b/.gitignore index ea0efda..2f56b81 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ Thumbs.db *.swp *.tmp +.venv/ +__pycache__/ .playwright-cli/ /work/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d3439d0..4b776fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,6 +46,7 @@ the gap is clear before you build the pull request. ```text pets// site/assets/-preview.gif + site/assets/-preview.png site/install//index.html catalog.json README.md @@ -95,6 +96,7 @@ pets// ├── pet.json ├── spritesheet.webp ├── preview.gif +├── preview.png ├── README.md └── qa/ ├── contact-sheet.png @@ -178,15 +180,20 @@ python3 scripts/render_idle_preview.py \ --output "pets/${PET_ID}/preview.gif" ``` -The command requires Python 3 and Pillow. The renderer preserves the standard idle -timing, creates a `384 × 416` 2x presentation asset for clean browser downsampling, and +The command requires Python 3 and Pillow; follow the [development setup](docs/MAINTENANCE.md). +It renders a 6.6-second desktop-paced idle loop and matching static PNG at +`384 × 416` size for clean browser downsampling (`--scale 1` uses native cells), and uses a deterministic alpha cutoff before GIF encoding. This prevents GIF's binary transparency from turning faint edge pixels into a grainy fringe. Copy the resulting -preview to `site/assets/` when the pet is shown in the public catalogue. +GIF and PNG to `site/assets/` when the pet is shown in the public catalogue. +Use a `` source with `media="(prefers-reduced-motion: reduce)"` for the PNG +on each website card and installer. The static image must equal GIF frame zero. +Run `python3 scripts/validate_previews.py` in the activated development environment. The cache token is the first 12 lowercase characters of the exact referenced preview file's SHA-256. Package README references hash `pets//preview.gif`; website and -installer references hash `site/assets/-preview.gif`. The two previews may +installer references hash `site/assets/-preview.gif` and the corresponding +PNG separately. Package and site previews may differ after documented presentation-only cleanup. ## Change matrix diff --git a/README.md b/README.md index 5a59df1..df380ea 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,13 @@ An independent community catalogue of custom animated pets for the Codex desktop ![License](https://img.shields.io/badge/license-CC%20BY%204.0-fbbf24?style=flat-square) [![Give Codex Pets a star on GitHub](https://img.shields.io/github/stars/senyo888/codex-pets?style=flat-square&logo=github&label=Give%20us%20a%20star&color=fbbf24)](https://github.com/senyo888/codex-pets) -Bella's dimensional idle animation -AetherWing's calm idle animation -AetherCore's polished metallic idle animation -AetherMite's dimensional idle animation -Aetherbite's cinematic idle animation -Calian's calm idle animation -Scarlet's calm idle animation +Bella's dimensional idle animation +AetherWing's calm idle animation +AetherCore's polished metallic idle animation +AetherMite's dimensional idle animation +Aetherbite's cinematic idle animation +Calian's calm idle animation +Scarlet's calm idle animation ## [Bella](pets/bella/README.md) · [AetherWing](pets/aetherwing/README.md) · [AetherCore](pets/aethercore/README.md) · [AetherMite](pets/aethermite/README.md) · [Aetherbite](pets/aetherbite/README.md) · [Calian](pets/calian/README.md) · [Scarlet](pets/scarlet/README.md) @@ -44,7 +44,11 @@ An independent community catalogue of custom animated pets for the Codex desktop | 006 | [**Calian**](pets/calian/README.md) | Calian isolates decisive faults and restores deliberate control with calm, methodical judgement. | Sprite v2 | Validated and ready | | 007 | [**Scarlet**](pets/scarlet/README.md) | Scarlet pairs vigilant drift tracing with propulsive follow-through, carrying every correction to verified closure beside Calian. | Sprite v2 | Validated and ready | -Each companion has a distinct identity and animation language. Every animated preview above is rendered directly from its current validated atlas. +Each companion has a distinct identity and animation language. Every animated preview above is derived from its current validated atlas and uses a +6.6-second idle loop, matching the desktop renderer checked in version 26.930.21537. +The website displays still images when reduced motion is requested; each pet README +also links to a static preview. +See [maintenance and compatibility checks](docs/MAINTENANCE.md). ### Calian and Scarlet — the sister act @@ -117,6 +121,7 @@ codex-pets/ │ ├── pet.json │ ├── spritesheet.webp │ ├── preview.gif +│ ├── preview.png │ ├── README.md │ └── qa/ ├── site/ diff --git a/docs/CATALOG_CONTRACT.md b/docs/CATALOG_CONTRACT.md index 621cfc0..7c0450f 100644 --- a/docs/CATALOG_CONTRACT.md +++ b/docs/CATALOG_CONTRACT.md @@ -136,3 +136,16 @@ output, external availability, or real desktop-app installer behaviour. - A successful Pages deployment and live readback are required before publication is declared complete. - No validator, agent, workflow, or generated output may approve its own work. + +## Preview playback and accessibility + +Package and site idle GIFs use six frames with durations of 1680, 660, 660, 840, +840, and 1920 ms (6.6 seconds total), matching the desktop renderer inspected in +26.930.21537. This is a dated presentation baseline, not a package timing override. +Each GIF has a same-stem static PNG equal to its first decoded frame. Website cards +and installers select that PNG through a reduced-motion `` source. +PNG cache tokens follow the same exact-file SHA-256 rule as GIF tokens. + +`python3 scripts/validate_previews.py` checks timing, geometry, transparency, disposal, +looping, and still-frame equality using the pinned development dependency. The standard +library catalogue validator checks source markup, tokens, and local PNG references. diff --git a/docs/MAINTENANCE.md b/docs/MAINTENANCE.md new file mode 100644 index 0000000..05ab561 --- /dev/null +++ b/docs/MAINTENANCE.md @@ -0,0 +1,57 @@ +# Maintenance and compatibility + +## Development setup + +Use Python 3.12 or newer and a complete Git installation with HTTPS helpers. +Keep image tooling in a project environment rather than installing into system Python: + +```sh +python3 -m venv .venv +. .venv/bin/activate +python -m pip install -r requirements-dev.txt +python scripts/validate_catalog.py +python scripts/validate_previews.py +``` + +Repeat setup for each checkout. The standard-library catalogue check can also run +without the environment. CI installs the same pinned Pillow dependency for previews. +If Git reports a missing `remote-https`, inspect `git --exec-path` and the selected +Git distribution; restore its matching helper directory rather than changing credentials. + +## October 2026 maintenance changes + +- Idle previews now use a 6.6-second loop rather than the previous 1.1-second loop. + Timing was checked against desktop app 26.930.21537 on 2026-10-03. Original decoded + GIF artwork is retained; only frame delays changed. +- Static PNG alternatives show frame zero under reduced motion on the catalogue and + every installer. GIF and PNG cache tokens track the exact referenced files. +- Preview validation runs in CI alongside catalogue validation. +- Authoritative atlases, package IDs, descriptions, sprite versions, installer queries, + and published v1.0.0 release assets are unchanged by these presentation changes. + +## Runtime boundaries + +The desktop app owns playback, state priority, pointer responses, pet size, and +reduced-motion handling. Package artwork does not implement agent reasoning or control +Home Assistant. Changing preview timing cannot change installed runtime timing. + +Desktop v2 atlases and ChatGPT web derivatives have separate contracts. Desktop files +are local; web adoption links and uploads are separate distribution records. Do not +replace an eleven-row desktop atlas with a nine-row web export. + +Sources: [Pets](https://learn.chatgpt.com/docs/pets) and +[September 11 pet controls update](https://learn.chatgpt.com/docs/changelog), checked +2026-10-03. Recheck renderer timing on future app updates before changing this baseline. + +## Validation before distribution + +Run both validators, inspect catalogue and all installers at desktop and 390 px mobile +widths, and switch reduced motion both ways. Confirm each loaded still is static and +matches the visible idle character. Check for image failures, overflow, console errors, +and unchanged install actions. Preview-only changes do not require reinstalling atlases. +For installed packages, compare both pet.json and spritesheet bytes with the chosen +canonical package; preserve prior files before synchronizing metadata. + +For an artwork change, rerun structural and visual QA across all states and directions, +update hashes and previews together, and verify at actual display sizes. A frame-difference +outlier alone is not sufficient evidence to regenerate a character. diff --git a/pets/aetherbite/README.md b/pets/aetherbite/README.md index 206cb8b..98d0f5a 100644 --- a/pets/aetherbite/README.md +++ b/pets/aetherbite/README.md @@ -4,7 +4,7 @@ **The Bio-Digital Systems Tinkerer** -Aetherbite's cinematic idle animation +Aetherbite's cinematic idle animation *Humidity Intelligence's cinematic dimensional systems tinkerer, with crystalline wings, layered articulated armour, and expressive motion.* @@ -12,6 +12,8 @@ +[View the static idle preview](preview.png) + ## Personality Aetherbite is energetic, resolute, and inventive. It brings a compact but dimensional presence to systems work while keeping the same practical instinct: observe carefully, explain the change, and improve the smallest useful thing first. diff --git a/pets/aetherbite/preview.gif b/pets/aetherbite/preview.gif index a786a55..327bce7 100644 Binary files a/pets/aetherbite/preview.gif and b/pets/aetherbite/preview.gif differ diff --git a/pets/aetherbite/preview.png b/pets/aetherbite/preview.png new file mode 100644 index 0000000..4ab0af8 Binary files /dev/null and b/pets/aetherbite/preview.png differ diff --git a/pets/aethercore/README.md b/pets/aethercore/README.md index d7ce1eb..c74712b 100644 --- a/pets/aethercore/README.md +++ b/pets/aethercore/README.md @@ -4,7 +4,7 @@ **The Continuity Engine** -AetherCore's polished metallic idle animation +AetherCore's polished metallic idle animation *A calm clockwork guardian built to keep decisions connected, drift visible, and governance coherent.* @@ -12,6 +12,8 @@ +[View the static idle preview](preview.png) + ## Personality AetherCore is measured, dependable, and quietly vigilant. It treats continuity as a living system: decisions should remain traceable, architectural intent should survive change, and hidden drift should never be allowed to accumulate unnoticed. diff --git a/pets/aethercore/preview.gif b/pets/aethercore/preview.gif index e7eed87..9ed8e6f 100644 Binary files a/pets/aethercore/preview.gif and b/pets/aethercore/preview.gif differ diff --git a/pets/aethercore/preview.png b/pets/aethercore/preview.png new file mode 100644 index 0000000..78b2d76 Binary files /dev/null and b/pets/aethercore/preview.png differ diff --git a/pets/aethermite/README.md b/pets/aethermite/README.md index a34082a..43f85c5 100644 --- a/pets/aethermite/README.md +++ b/pets/aethermite/README.md @@ -4,7 +4,7 @@ **The Systems Tinkerer** -AetherMite's dimensional idle animation +AetherMite's dimensional idle animation *A premium dimensional Humidity Intelligence champion with a layered mechanical shell and luminous environmental core.* @@ -12,6 +12,8 @@ +[View the static idle preview](preview.png) + ## Personality AetherMite is curious, energetic, and inventive. It notices tiny inconsistencies, explores practical refinements, and prefers small explainable improvements over clever but fragile shortcuts. diff --git a/pets/aethermite/preview.gif b/pets/aethermite/preview.gif index 3ce5302..f760abb 100644 Binary files a/pets/aethermite/preview.gif and b/pets/aethermite/preview.gif differ diff --git a/pets/aethermite/preview.png b/pets/aethermite/preview.png new file mode 100644 index 0000000..5c10339 Binary files /dev/null and b/pets/aethermite/preview.png differ diff --git a/pets/aetherwing/README.md b/pets/aetherwing/README.md index 0f29ccd..8bf8ff0 100644 --- a/pets/aetherwing/README.md +++ b/pets/aetherwing/README.md @@ -4,7 +4,7 @@ **Pet 002 · The Runtime Sentinel** -AetherWing's calm idle animation +AetherWing's calm idle animation *A flight-first guardian of deterministic control, architectural discipline, and truth-backed runtime behaviour.* @@ -12,6 +12,8 @@ +[View the static idle preview](preview.png) + ## Personality AetherWing watches the boundary between intent and execution. She challenges weakened architecture, detects drift early, and protects deterministic behaviour without disrupting stable systems. diff --git a/pets/aetherwing/preview.gif b/pets/aetherwing/preview.gif index 7ceeb2a..b1b08e2 100644 Binary files a/pets/aetherwing/preview.gif and b/pets/aetherwing/preview.gif differ diff --git a/pets/aetherwing/preview.png b/pets/aetherwing/preview.png new file mode 100644 index 0000000..ddb8da3 Binary files /dev/null and b/pets/aetherwing/preview.png differ diff --git a/pets/bella/README.md b/pets/bella/README.md index 0c3b459..6acf8b5 100644 --- a/pets/bella/README.md +++ b/pets/bella/README.md @@ -4,7 +4,7 @@ **The 1 True Source** -Bella's dimensional idle animation +Bella's dimensional idle animation *A premium dimensional crystalline coherence guardian with layered depth, graceful flight, and a precise eye for truth.* @@ -12,6 +12,8 @@ +[View the static idle preview](preview.png) + ## Personality Bella is composed, precise, and gently sceptical. She prefers truth over theatre, deterministic systems over hidden magic, and a clean review over an enthusiastic guess. diff --git a/pets/bella/preview.gif b/pets/bella/preview.gif index 536ff01..04fb036 100644 Binary files a/pets/bella/preview.gif and b/pets/bella/preview.gif differ diff --git a/pets/bella/preview.png b/pets/bella/preview.png new file mode 100644 index 0000000..b346190 Binary files /dev/null and b/pets/bella/preview.png differ diff --git a/pets/calian/README.md b/pets/calian/README.md index 13706ef..b2502b9 100644 --- a/pets/calian/README.md +++ b/pets/calian/README.md @@ -4,7 +4,7 @@ **The Tactical Sentinel** -Calian's calm idle animation +Calian's calm idle animation *A composed tactical guardian and one half of a sister act of unmatched diligence, known for calm judgement, deliberate control, and exact follow-through.* @@ -12,6 +12,8 @@ +[View the static idle preview](preview.png) + ## Personality Calian is calm, tactical, and steady under pressure. She isolates the decisive fault, establishes a clear plan, and restores control with measured action. diff --git a/pets/calian/preview.gif b/pets/calian/preview.gif index a1663e9..53312a6 100644 Binary files a/pets/calian/preview.gif and b/pets/calian/preview.gif differ diff --git a/pets/calian/preview.png b/pets/calian/preview.png new file mode 100644 index 0000000..039f86a Binary files /dev/null and b/pets/calian/preview.png differ diff --git a/pets/scarlet/README.md b/pets/scarlet/README.md index d2995b0..8d3a6b4 100644 --- a/pets/scarlet/README.md +++ b/pets/scarlet/README.md @@ -4,7 +4,7 @@ **The Propulsive Execution Guardian** -Scarlet's calm idle animation +Scarlet's calm idle animation *A poised CGI guardian and one half of a sister act of unmatched diligence, built to trace drift and carry every correction to verified closure.* @@ -12,6 +12,8 @@ +[View the static idle preview](preview.png) + ## Personality Scarlet is poised, vigilant, and exacting. She follows weak signals across the full execution path, contains drift before it spreads, and closes gaps with controlled precision. diff --git a/pets/scarlet/preview.gif b/pets/scarlet/preview.gif index 044657c..a03784c 100644 Binary files a/pets/scarlet/preview.gif and b/pets/scarlet/preview.gif differ diff --git a/pets/scarlet/preview.png b/pets/scarlet/preview.png new file mode 100644 index 0000000..de01d82 Binary files /dev/null and b/pets/scarlet/preview.png differ diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..e7cc6c1 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1 @@ +Pillow==12.3.0 diff --git a/scripts/render_idle_preview.py b/scripts/render_idle_preview.py index 5f00839..07d75b1 100755 --- a/scripts/render_idle_preview.py +++ b/scripts/render_idle_preview.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Render a crisp six-frame idle GIF from a validated Codex v2 atlas.""" +"""Render a six-frame idle GIF and matching still from a validated Codex v2 atlas.""" from __future__ import annotations @@ -13,7 +13,9 @@ ATLAS_SIZE = (1536, 2288) CELL_SIZE = (192, 208) IDLE_FRAME_COUNT = 6 -IDLE_DURATIONS = [280, 110, 110, 140, 140, 320] +# Desktop renderer observed in 26.930.21537: base idle holds multiplied by six. +# Presentation timing only; pet.json cannot override the app's animation timing. +IDLE_DURATIONS = [1680, 660, 660, 840, 840, 1920] DEFAULT_ALPHA_THRESHOLD = 192 DEFAULT_SCALE = 2 @@ -132,6 +134,9 @@ def main() -> None: ) result = validate_preview(output, args.scale) + with Image.open(output) as preview: + preview.convert("RGBA").save(output.with_suffix(".png")) + result["stillOutput"] = str(output.with_suffix(".png")) result["spritesheet"] = str(spritesheet) result["alphaThreshold"] = args.alpha_threshold print(json.dumps(result, indent=2)) diff --git a/scripts/validate_catalog.py b/scripts/validate_catalog.py index d836d5a..31abd42 100755 --- a/scripts/validate_catalog.py +++ b/scripts/validate_catalog.py @@ -68,9 +68,9 @@ def __init__(self) -> None: self.values: list[str] = [] def handle_starttag(self, _tag: str, attrs: list[tuple[str, str | None]]) -> None: - """Record href and src values from an HTML start tag.""" + """Record href, src, and single-candidate srcset values from an HTML start tag.""" values = dict(attrs) - for key in ("href", "src"): + for key in ("href", "src", "srcset"): if values.get(key): self.values.append(values[key] or "") @@ -300,11 +300,13 @@ def validate_package( metadata_path, spritesheet, preview, + preview.with_suffix(".png"), readme, validation, ROOT / "pets" / pet_id / "qa" / "contact-sheet.png", ROOT / "pets" / pet_id / "qa" / "look-directions.png", site_preview, + site_preview.with_suffix(".png"), installer, ) for path in required_paths: @@ -503,6 +505,12 @@ def text_value(value: object) -> str: return html.escape(str(value), quote=False) +def still_token(pet_id: str) -> str: + """Missing stills are reported by package validation, without a hash traceback.""" + path = SITE_ROOT / "assets" / f"{pet_id}-preview.png" + return sha256(path)[:12] if path.is_file() else "" + + def validate_site_index( pets: list[dict[str, object]], site_tokens: dict[str, str], errors: list[str] ) -> None: @@ -528,6 +536,7 @@ def validate_site_index( presentation = pet["presentation"] token = site_tokens[pet_id] required_snippets = ( + f'', f'src="./assets/{pet_id}-preview.gif?v={token}" alt="{presentation["previewAlt"]}"', f'

Pet {pet["catalogueNumber"]}

', f'id="{pet_id}-title"', @@ -564,6 +573,7 @@ def validate_installer( text = path.read_text(encoding="utf-8") readme_url = f"https://github.com/senyo888/codex-pets/blob/main/pets/{pet_id}/README.md" required_snippets = ( + f'', ( f'' diff --git a/scripts/validate_previews.py b/scripts/validate_previews.py new file mode 100644 index 0000000..9a00d81 --- /dev/null +++ b/scripts/validate_previews.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +"""Check every distributed idle preview and its reduced-motion still.""" + +import json +from pathlib import Path + +from PIL import Image, ImageChops + +from render_idle_preview import validate_preview + +ROOT = Path(__file__).resolve().parents[1] + + +def main() -> None: + count = 0 + for pet in json.loads((ROOT / "catalog.json").read_text())["pets"]: + for gif in (ROOT / pet["previewPath"], ROOT / "site/assets" / f"{pet['id']}-preview.gif"): + with Image.open(gif) as preview: + if preview.width % 192: + raise SystemExit(f"invalid preview width: {gif}") + validate_preview(gif, preview.width // 192) + with Image.open(gif.with_suffix(".png")) as still: + if getattr(still, "n_frames", 1) != 1 or still.size != preview.size: + raise SystemExit(f"invalid still dimensions or frame count: {still.filename}") + if ImageChops.difference(still.convert("RGBA"), preview.convert("RGBA")).getbbox(alpha_only=False): + raise SystemExit(f"still differs from idle frame zero: {still.filename}") + count += 1 + print(f"previews: {count} GIFs at 6600 ms, matching static PNGs; passed") + + +if __name__ == "__main__": + main() diff --git a/site/assets/aetherbite-preview.gif b/site/assets/aetherbite-preview.gif index a786a55..327bce7 100644 Binary files a/site/assets/aetherbite-preview.gif and b/site/assets/aetherbite-preview.gif differ diff --git a/site/assets/aetherbite-preview.png b/site/assets/aetherbite-preview.png new file mode 100644 index 0000000..4ab0af8 Binary files /dev/null and b/site/assets/aetherbite-preview.png differ diff --git a/site/assets/aethercore-preview.gif b/site/assets/aethercore-preview.gif index e7eed87..9ed8e6f 100644 Binary files a/site/assets/aethercore-preview.gif and b/site/assets/aethercore-preview.gif differ diff --git a/site/assets/aethercore-preview.png b/site/assets/aethercore-preview.png new file mode 100644 index 0000000..78b2d76 Binary files /dev/null and b/site/assets/aethercore-preview.png differ diff --git a/site/assets/aethermite-preview.gif b/site/assets/aethermite-preview.gif index 3ce5302..f760abb 100644 Binary files a/site/assets/aethermite-preview.gif and b/site/assets/aethermite-preview.gif differ diff --git a/site/assets/aethermite-preview.png b/site/assets/aethermite-preview.png new file mode 100644 index 0000000..5c10339 Binary files /dev/null and b/site/assets/aethermite-preview.png differ diff --git a/site/assets/aetherwing-preview.gif b/site/assets/aetherwing-preview.gif index 7ceeb2a..b1b08e2 100644 Binary files a/site/assets/aetherwing-preview.gif and b/site/assets/aetherwing-preview.gif differ diff --git a/site/assets/aetherwing-preview.png b/site/assets/aetherwing-preview.png new file mode 100644 index 0000000..ddb8da3 Binary files /dev/null and b/site/assets/aetherwing-preview.png differ diff --git a/site/assets/bella-preview.gif b/site/assets/bella-preview.gif index 536ff01..04fb036 100644 Binary files a/site/assets/bella-preview.gif and b/site/assets/bella-preview.gif differ diff --git a/site/assets/bella-preview.png b/site/assets/bella-preview.png new file mode 100644 index 0000000..b346190 Binary files /dev/null and b/site/assets/bella-preview.png differ diff --git a/site/assets/calian-preview.gif b/site/assets/calian-preview.gif index a1663e9..53312a6 100644 Binary files a/site/assets/calian-preview.gif and b/site/assets/calian-preview.gif differ diff --git a/site/assets/calian-preview.png b/site/assets/calian-preview.png new file mode 100644 index 0000000..039f86a Binary files /dev/null and b/site/assets/calian-preview.png differ diff --git a/site/assets/scarlet-preview.gif b/site/assets/scarlet-preview.gif index 044657c..a03784c 100644 Binary files a/site/assets/scarlet-preview.gif and b/site/assets/scarlet-preview.gif differ diff --git a/site/assets/scarlet-preview.png b/site/assets/scarlet-preview.png new file mode 100644 index 0000000..de01d82 Binary files /dev/null and b/site/assets/scarlet-preview.png differ diff --git a/site/index.html b/site/index.html index 26953ab..1da2ce1 100644 --- a/site/index.html +++ b/site/index.html @@ -49,7 +49,10 @@

Codex
- Bella's dimensional idle animation + + + Bella's dimensional idle animation +
@@ -75,7 +78,10 @@

- AetherWing's calm idle animation + + + AetherWing's calm idle animation +
@@ -101,7 +107,10 @@

- AetherCore's polished metallic idle animation + + + AetherCore's polished metallic idle animation +
@@ -127,7 +136,10 @@

- AetherMite's dimensional idle animation + + + AetherMite's dimensional idle animation +
@@ -153,7 +165,10 @@

- Aetherbite's cinematic idle animation + + + Aetherbite's cinematic idle animation +
@@ -179,7 +194,10 @@

- Calian's calm idle animation + + + Calian's calm idle animation +
@@ -205,7 +223,10 @@

- Scarlet's calm idle animation + + + Scarlet's calm idle animation +
diff --git a/site/install/aetherbite/index.html b/site/install/aetherbite/index.html index 11dfb79..eda0f19 100644 --- a/site/install/aetherbite/index.html +++ b/site/install/aetherbite/index.html @@ -21,7 +21,10 @@
- Aetherbite's cinematic idle animation + + + Aetherbite's cinematic idle animation +

Pet 005 · sprite v2

diff --git a/site/install/aethercore/index.html b/site/install/aethercore/index.html index 69dbb99..e5c7671 100644 --- a/site/install/aethercore/index.html +++ b/site/install/aethercore/index.html @@ -21,7 +21,10 @@
- AetherCore's polished metallic idle animation + + + AetherCore's polished metallic idle animation +

Pet 003 · sprite v2

diff --git a/site/install/aethermite/index.html b/site/install/aethermite/index.html index 7f47d7b..9021a5f 100644 --- a/site/install/aethermite/index.html +++ b/site/install/aethermite/index.html @@ -21,7 +21,10 @@
- AetherMite's dimensional idle animation + + + AetherMite's dimensional idle animation +

Pet 004 · sprite v2

diff --git a/site/install/aetherwing/index.html b/site/install/aetherwing/index.html index 03e5eaf..cb6d980 100644 --- a/site/install/aetherwing/index.html +++ b/site/install/aetherwing/index.html @@ -21,7 +21,10 @@
- AetherWing's calm idle animation + + + AetherWing's calm idle animation +

Pet 002 · sprite v2

diff --git a/site/install/bella/index.html b/site/install/bella/index.html index 7f9e0a5..0b87d53 100644 --- a/site/install/bella/index.html +++ b/site/install/bella/index.html @@ -21,7 +21,10 @@
- Bella's dimensional idle animation + + + Bella's dimensional idle animation +

Pet 001 · sprite v2

diff --git a/site/install/calian/index.html b/site/install/calian/index.html index 2e89164..2098568 100644 --- a/site/install/calian/index.html +++ b/site/install/calian/index.html @@ -21,7 +21,10 @@
- Calian's calm idle animation + + + Calian's calm idle animation +

Pet 006 · sprite v2

diff --git a/site/install/scarlet/index.html b/site/install/scarlet/index.html index 662a2d9..ee2fc4e 100644 --- a/site/install/scarlet/index.html +++ b/site/install/scarlet/index.html @@ -21,7 +21,10 @@
- Scarlet's calm idle animation + + + Scarlet's calm idle animation +

Pet 007 · sprite v2

diff --git a/site/styles.css b/site/styles.css index 0cc80e7..b89eafa 100644 --- a/site/styles.css +++ b/site/styles.css @@ -347,6 +347,11 @@ h1 { filter: drop-shadow(0 18px 26px rgba(var(--accent-rgb), 0.2)); } +.pet-visual picture, +.installer-visual picture { + display: contents; +} + .contribution-visual img { width: min(154px, 70%); }