{{end}}
diff --git a/internal/web/templates/partials.html b/internal/web/templates/partials.html
index 726386c..40d0ea0 100644
--- a/internal/web/templates/partials.html
+++ b/internal/web/templates/partials.html
@@ -297,7 +297,8 @@
{{- if .Attachments}}
{{- range $ai, $att := .Attachments}}
- {{- if and (eq $att.Kind "image") (imgRenderable $.Source $.ConvName $att.RelPath)}}
+ {{- $tstate := imgTileState $.Source $.ConvName $att.RelPath}}
+ {{- if and (eq $att.Kind "image") (eq $tstate "img")}}
{{/* Renderable image: the thumbnail opens the same pure-CSS :target
lightbox the Media tab uses (gallery.html gallery_images_page),
keyed to the overlay emitted just after this row (issue #3). The
@@ -307,6 +308,13 @@
+ {{- else if eq $tstate "missing"}}
+ {{/* The attachment row exists but the file is absent from the archive
+ on this machine (issues #4/#15): a download anchor here would
+ fetch a 404 under the `download` attribute, which browsers
+ surface as a silently failed download — "clicking does nothing".
+ Same inert labeled treatment as the gallery's missing tile/card. */}}
+
{{if eq $att.Kind "image"}}{{template "icon-photo" $}}{{else}}{{template "icon-paperclip" $}}{{end}}{{if $att.OriginalName}}{{$att.OriginalName}}{{else}}{{$att.RelPath}}{{end}}missing
{{- else}}
{{/* Files, and images with no browser-renderable rendition (e.g. an
un-transcoded HEIC), render as a labeled attachment chip: