{{ define "main" }} {{ $pub_type_csl := "" }} {{ $pub_type_display := "" }} {{ if .Params.publication_types }} {{ if reflect.IsSlice .Params.publication_types }} {{ $pub_type_csl = index .Params.publication_types 0 }} {{ $pub_type_display = i18n (printf "pub_%s" (strings.Replace $pub_type_csl "-" "_")) | default (strings.Title $pub_type_csl) }} {{ end }} {{ end }}
{{ partial "components/sidebar.html" (dict "context" . "no_sidebar" true) }} {{ partial "components/toc.html" . }}
{{ if .Params.show_breadcrumb }}
{{ partial "components/breadcrumb.html" . }}
{{ end }}

{{- .Title -}}

{{- if .Date | and (not .Params.hide_date) -}} {{- .Date | time.Format (site.Params.locale.date_format | default ":date_long") -}} {{- if .Params.authors }}·{{ end -}} {{- end -}} {{/* Set Alpine.js flag if author notes exist */}} {{ if isset .Params "author_notes" }} {{ .Store.Set "has_alpine" true }} {{ end }} {{ $taxonomy := "authors" }} {{ range $i, $author_obj := (.GetTerms $taxonomy) }} {{ $author_page := $author_obj.Page }} {{ $avatar := ($author_page.Resources.ByType "image").GetMatch "*avatar*" }} {{- if and $i (not $avatar) }},{{ end -}} {{ with $author_page.Params.website }} {{ end }}
{{ with $avatar }} {{/* Simple 2x retina image for small avatar */}} {{ $avatar_32 := $avatar.Process "Fill 32x32 Center webp" }} {{ $author_page.Title }} {{ end }}
{{ $author_page.Title }}
{{ with $author_page.Params.website }}
{{ end }} {{/* Add author note tooltip if available */}} {{- if isset $.Params "author_notes" -}} {{- with (index $.Params.author_notes $i) -}}
{{.}}
{{- end -}} {{- end -}} {{ end }} {{ if ne .Params.reading_time false }} · {{ .ReadingTime }} {{ i18n "minute_read" }} {{ end }}
{{ partial "page_links_div.html" . }}
{{ $featured := partial "functions/get_featured_image.html" . }} {{/* Featured image layout */}} {{ if and $featured (not .Params.image.preview_only) }} {{/* Fit image within max size. */}} {{ $image := $featured }} {{/* Determine image placement. */}} {{ $placement := .Params.image.placement | default 1 }}{{/* Default to full column width. */}} {{/* Configure responsive processing based on placement */}} {{ $image_container := "" }} {{ $responsive_sizes := slice }} {{ $sizes_attr := "" }} {{ if eq $placement 2}} {{ $image_container = "container" }} {{ $responsive_sizes = slice 480 768 1024 1200 1600 }} {{ $sizes_attr = "(max-width: 480px) 100vw, (max-width: 768px) 90vw, (max-width: 1200px) 80vw, 1200px" }} {{else if eq $placement 3}} {{ $image_container = "container-fluid" }} {{ $responsive_sizes = slice 768 1024 1366 1920 2560 }} {{ $sizes_attr = "(max-width: 768px) 100vw, (max-width: 1366px) 90vw, (max-width: 1920px) 80vw, 2560px" }} {{else}} {{ $image_container = "article-container" }} {{ $responsive_sizes = slice 320 480 640 720 960 }} {{ $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 ne $featured.MediaType.SubType "gif" }} {{/* Pre-fit image to placement constraints, then apply responsive processing */}} {{ $fitted_image := $featured }} {{ if eq $placement 2}} {{ $fitted_image = $featured.Fit "1200x2500" }} {{else if eq $placement 3}} {{ $fitted_image = $featured.Fit "2560x2560" }} {{else}} {{ $fitted_image = $featured.Fit "720x2500" }} {{end}} {{ $responsive := partial "functions/process_responsive_image.html" (dict "image" $fitted_image "mode" "responsive" "sizes" $responsive_sizes ) }} {{/* Featured image - use fitted image dimensions for container, responsive for srcset */}}
{{ with $.Params.image.alt_text }}{{.}}{{ end }} {{ with $.Params.image.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 $.Params.image.alt_text }}{{.}}{{ end }} {{ with $.Params.image.caption }}{{ . | markdownify | emojify }}{{ end }}
{{ end }} {{end}} {{/* EVENT / PUBLICATION METADATA */}} {{ if .Params.abstract | or (eq .Type "publication") | or (eq .Type "event") }}
{{ if .Params.abstract }}
{{ i18n "abstract" }}
{{ .Params.abstract | markdownify }}
{{ end }} {{/* If the type is Uncategorized, hide the type. */}} {{ if $pub_type_display }}
{{ i18n "publication_type" }}
{{ if and .Params.publication_types (gt (len .Params.publication_types) 0) }} {{ $pub_type_display }} {{ end }}
{{ end }} {{ if .Params.publication }}
{{ i18n "publication" }}
{{ .Params.publication | markdownify }}
{{ end }} {{ if eq .Type "event" }}
{{ i18n "date" }}
{{ partial "functions/get_event_dates" . }}
{{ end }} {{ if .Params.event }}
{{ i18n "event" }}
{{ with .Params.event_url }}{{ end }} {{ .Params.event | markdownify }} {{ if .Params.event_url }}{{ end }}
{{ end }} {{ if .Params.location }}
{{ i18n "location" }}

{{ .Params.location | markdownify }}

{{ if .Params.address }}

{{partial "functions/get_address" (dict "root" . "address" .Params.address) }}

{{end}}
{{ end }}
{{ end }}
{{ .Content }}
{{ partial "components/last-edited.html" . }}
{{ .Scratch.Set "invert_pager" true }} {{ partial "page_footer" . }}
{{ end }}