diff --git a/modules/blox/blox/logos/block.html b/modules/blox/blox/logos/block.html
index 71e2424c..c2363072 100644
--- a/modules/blox/blox/logos/block.html
+++ b/modules/blox/blox/logos/block.html
@@ -149,13 +149,13 @@
{{ $img := $image_resource }}
{{ if $img }}
- {{ $isSVG := eq $img.MediaType.SubType "svg" }}
- {{ if not $isSVG }}
+ {{ $isProcessable := reflect.IsImageResourceProcessable $img }}
+ {{ if $isProcessable }}
{{ $img = $img.Fit "280x140 webp" }}
{{ end }}
-
{{ else if $image_url }}
@@ -191,13 +191,13 @@
{{ $image := . }}
- {{ $isSVG := eq $image.MediaType.SubType "svg" }}
- {{ if not $isSVG }}
+ {{ $isProcessable := reflect.IsImageResourceProcessable $image }}
+ {{ if $isProcessable }}
{{ $image = $image.Fit "280x140 webp" }}
{{ end }}
-
@@ -234,13 +234,13 @@
{{ if .image }}
{{ $img := resources.Get (printf "media/%s" .image) }}
{{ if $img }}
- {{ $isSVG := eq $img.MediaType.SubType "svg" }}
- {{ if not $isSVG }}
+ {{ $isProcessable := reflect.IsImageResourceProcessable $img }}
+ {{ if $isProcessable }}
{{ $img = $img.Fit "280x140 webp" }}
{{ end }}
-

{{ end }}
@@ -254,13 +254,13 @@
{{ if .image }}
{{ $img := resources.Get (printf "media/%s" .image) }}
{{ if $img }}
- {{ $isSVG := eq $img.MediaType.SubType "svg" }}
- {{ if not $isSVG }}
+ {{ $isProcessable := reflect.IsImageResourceProcessable $img }}
+ {{ if $isProcessable }}
{{ $img = $img.Fit "280x140 webp" }}
{{ end }}
-

{{ end }}
@@ -286,13 +286,13 @@
{{ if $image_name }}
{{ $img := resources.Get (printf "media/%s" $image_name) }}
{{ if $img }}
- {{ $isSVG := eq $img.MediaType.SubType "svg" }}
- {{ if not $isSVG }}
+ {{ $isProcessable := reflect.IsImageResourceProcessable $img }}
+ {{ if $isProcessable }}
{{ $img = $img.Fit "280x140 webp" }}
{{ end }}
-

{{ end }}
diff --git a/modules/blox/blox/portfolio/block.html b/modules/blox/blox/portfolio/block.html
index fc9f16ac..b4203c18 100644
--- a/modules/blox/blox/portfolio/block.html
+++ b/modules/blox/blox/portfolio/block.html
@@ -277,9 +277,9 @@
{{ $image := $item.Resources.GetMatch "{featured,cover,thumbnail}*" }}
{{ if $image }}
- {{ if strings.Contains $image.MediaType.SubType "svg" }}
-

diff --git a/modules/blox/blox/research-areas/block.html b/modules/blox/blox/research-areas/block.html
index 6c9a6498..39fddae6 100644
--- a/modules/blox/blox/research-areas/block.html
+++ b/modules/blox/blox/research-areas/block.html
@@ -211,7 +211,9 @@
{{ $img := $image_resource }}
{{ if $img }}
- {{ $img = $img.Fill "600x400 Center webp" }}
+ {{ if reflect.IsImageResourceProcessable $img }}
+ {{ $img = $img.Fill "600x400 Center webp" }}
+ {{ end }}
{{ $alt := $name | plainify }}
{{ $header_content = printf "

" $img.RelPermalink $alt }}
{{ else if $image_url }}
diff --git a/modules/blox/blox/resume-biography-3/block.html b/modules/blox/blox/resume-biography-3/block.html
index c24713df..a8fd6558 100644
--- a/modules/blox/blox/resume-biography-3/block.html
+++ b/modules/blox/blox/resume-biography-3/block.html
@@ -131,10 +131,10 @@
{{ $img = $image_resource }}
{{ if $img }}
- {{ $isSVG := eq $img.MediaType.SubType "svg" }}
- {{ $isGIF := eq $img.MediaType.SubType "gif" }}
+ {{/* reflect.IsImageResourceProcessable → false for SVG; GIF skipped to preserve animation */}}
+ {{ $canProcess := and (reflect.IsImageResourceProcessable $img) (ne $img.MediaType.SubType "gif") }}
- {{ if not (or $isSVG $isGIF) }}
+ {{ if $canProcess }}
{{ $responsive := partial "functions/process_responsive_image.html" (dict
"image" $img
"mode" "fill"
@@ -147,7 +147,7 @@
src="{{ $responsive.fallback.RelPermalink }}"
alt="" />
{{ else }}
- {{ if not $isSVG }}{{ $img = $img.Process "webp" }}{{ end }}
+ {{/* SVG or GIF: pass through without responsive processing */}}

diff --git a/modules/blox/blox/resume-biography/block.html b/modules/blox/blox/resume-biography/block.html
index a90fa2d8..4a8b88ab 100644
--- a/modules/blox/blox/resume-biography/block.html
+++ b/modules/blox/blox/resume-biography/block.html
@@ -103,9 +103,9 @@
{{ $img = $image_resource }}
{{ if $img }}
- {{ $isSVG := eq $img.MediaType.SubType "svg" }}
- {{ $isGIF := eq $img.MediaType.SubType "gif" }}
- {{ if not (or $isSVG $isGIF) }}
+ {{/* reflect.IsImageResourceProcessable → false for SVG; GIF skipped to preserve animation */}}
+ {{ $canProcess := and (reflect.IsImageResourceProcessable $img) (ne $img.MediaType.SubType "gif") }}
+ {{ if $canProcess }}
{{ $responsive := partial "functions/process_responsive_image.html" (dict
"image" $img
"mode" "fill"
@@ -126,8 +126,7 @@
{{ else }}
- {{/* Handle SVG/GIF without processing */}}
- {{ if not $isSVG }}{{ $img = $img.Process "webp" }}{{ end }}
+ {{/* SVG or GIF: pass through without responsive processing */}}
diff --git a/modules/blox/layouts/_markup/render-image.html b/modules/blox/layouts/_markup/render-image.html
index 09e9b1f8..c0a2492f 100644
--- a/modules/blox/layouts/_markup/render-image.html
+++ b/modules/blox/layouts/_markup/render-image.html
@@ -27,9 +27,13 @@
{{- if $img -}}
- {{- $isSVG := eq $img.MediaType.SubType "svg" -}}
- {{- $isGIF := eq $img.MediaType.SubType "gif" -}}
- {{- if $isSVG | or $isGIF -}}
+ {{/*
+ Image processing gate:
+ - reflect.IsImageResourceProcessable → false for SVG (not processable by Hugo).
+ - GIF: processable by Hugo but we skip to preserve animation frames.
+ */}}
+ {{- $canProcess := and (reflect.IsImageResourceProcessable $img) (ne $img.MediaType.SubType "gif") -}}
+ {{- if not $canProcess -}}

{{/* Cover Image */}}
- {{ if ne $cover.MediaType.SubType "gif" }}
-

{{ if $avatar }}
- {{ $isSVG := eq $avatar.MediaType.SubType "svg" }}
- {{ if $isSVG }}
+ {{ if not (reflect.IsImageResourceProcessable $avatar) }}

diff --git a/modules/blox/layouts/_partials/views/card.html b/modules/blox/layouts/_partials/views/card.html
index 51169347..46e8ac12 100644
--- a/modules/blox/layouts/_partials/views/card.html
+++ b/modules/blox/layouts/_partials/views/card.html
@@ -36,17 +36,23 @@
{{ end }}
{{ end }}
{{ with $resource }}
- {{ if strings.Contains .MediaType.SubType "svg" }}
+ {{/*
+ Image processing gate:
+ - reflect.IsImageResourceProcessable → false for SVG (not processable by Hugo).
+ - GIF: processable by Hugo but we skip to preserve animation frames.
+ */}}
+ {{ $canProcess := and (reflect.IsImageResourceProcessable .) (ne .MediaType.SubType "gif") }}
+ {{ if not $canProcess }}
-
- {{ else if ne .MediaType.SubType "gif" }}
+ {{ else }}
{{ $original_image := "" }}
{{ if $fill_image }}
{{ $original_image = .Fill (printf "800x450 %s" $anchor) }}
@@ -72,17 +78,6 @@
style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;"
alt="{{ $item.Title | plainify }} featured image">
- {{ else }}
-
-
-
{{ end }}
{{ else }}
diff --git a/modules/blox/layouts/_partials/views/slides-gallery.html b/modules/blox/layouts/_partials/views/slides-gallery.html
index 25dab71f..f84f3401 100644
--- a/modules/blox/layouts/_partials/views/slides-gallery.html
+++ b/modules/blox/layouts/_partials/views/slides-gallery.html
@@ -59,39 +59,34 @@
{{/* Slide Preview Image - 16:9 aspect ratio */}}
{{ with $resource }}
- {{ if strings.Contains .MediaType.SubType "svg" }}
-
- {{ else if ne .MediaType.SubType "gif" }}
- {{ $image := .Fill "800x450 Center" }}
- {{ $responsive := partial "functions/process_responsive_image.html" (dict
- "image" $image
- "mode" "responsive"
- "sizes" (slice 400 600 800)
- "formats" (slice "avif" "webp" "jpg")
- ) }}
-
- {{ else }}
-
+ {{ else }}
+ {{ $image := .Fill "800x450 Center" }}
+ {{ $responsive := partial "functions/process_responsive_image.html" (dict
+ "image" $image
+ "mode" "responsive"
+ "sizes" (slice 400 600 800)
+ "formats" (slice "avif" "webp" "jpg")
+ ) }}
+
{{ end }}
{{ else }}
{{/* Fallback: Decorative gradient with slide icon - smaller, cleaner */}}
diff --git a/modules/blox/layouts/authors/term.html b/modules/blox/layouts/authors/term.html
index 247a18fa..42ea452b 100644
--- a/modules/blox/layouts/authors/term.html
+++ b/modules/blox/layouts/authors/term.html
@@ -9,8 +9,7 @@
{{ if $avatar }}
- {{ $isSVG := eq $avatar.MediaType.SubType "svg" }}
- {{ if $isSVG }}
+ {{ if not (reflect.IsImageResourceProcessable $avatar) }}

{{ . | markdownify | emojify }}{{ end }}
- {{ else if ne $featured.MediaType.SubType "gif" }}
+ {{ else }}
{{/* Pre-fit image to placement constraints, then apply responsive processing */}}
{{ $fitted_image := $featured }}
{{ if eq $placement 2}}
@@ -215,27 +220,6 @@
{{ with $image_params.caption }}
{{ . | markdownify | emojify }}{{ end }}
- {{ else }}
- {{/* Handle GIF - apply same placement constraints without responsive processing */}}
- {{ $image := $featured }}
- {{ if eq $placement 2}}
- {{ $image = $featured.Fit "1200x2500" }}
- {{else if eq $placement 3}}
- {{ $image = $featured.Fit "2560x2560" }}
- {{else}}
- {{ $image = $featured.Fit "720x2500" }}
- {{end}}
-
-
-

- {{ with $image_params.caption }}
{{ . | markdownify | emojify }}{{ end }}
-
-
{{ end }}
{{end}}
{{ end }}
diff --git a/modules/blox/layouts/single.html b/modules/blox/layouts/single.html
index ad1bbb8c..e5410d84 100644
--- a/modules/blox/layouts/single.html
+++ b/modules/blox/layouts/single.html
@@ -177,9 +177,14 @@
{{ $sizes_attr = "(max-width: 480px) 100vw, (max-width: 640px) 90vw, (max-width: 720px) 80vw, 720px" }}
{{end}}
- {{/* Process featured image using utility with placement-specific constraints */}}
- {{ if strings.Contains $featured.MediaType.SubType "svg" }}
- {{/* SVGs cannot be processed by Hugo (Fit/Fill). Render directly. */}}
+ {{/*
+ Image processing gate:
+ - reflect.IsImageResourceProcessable → false for SVG (not processable by Hugo).
+ - GIF: processable by Hugo but we skip to preserve animation frames.
+ */}}
+ {{ $canProcess := and (reflect.IsImageResourceProcessable $featured) (ne $featured.MediaType.SubType "gif") }}
+ {{ if not $canProcess }}
+ {{/* SVG or GIF: render directly without responsive processing */}}

{{ . | markdownify | emojify }}{{ end }}
- {{ else if ne $featured.MediaType.SubType "gif" }}
+ {{ else }}
{{/* Pre-fit image to placement constraints, then apply responsive processing */}}
{{ $fitted_image := $featured }}
{{ if eq $placement 2}}
@@ -222,28 +227,6 @@
{{ with $image_params.caption }}
{{ . | markdownify | emojify }}{{ end }}
- {{ else }}
- {{/* Handle GIF - apply same placement constraints without responsive processing */}}
- {{ $image := $featured }}
- {{ if eq $placement 2}}
- {{ $image = $featured.Fit "1200x2500" }}
- {{else if eq $placement 3}}
- {{ $image = $featured.Fit "2560x2560" }}
- {{else}}
- {{ $image = $featured.Fit "720x2500" }}
- {{end}}
-
-
-

- {{ with $image_params.caption }}
{{ . | markdownify | emojify }}{{ end }}
-
-
{{ end }}
{{end}}