+
+ {{/* Banner Image */}}
+ {{ $img := "" }}
+ {{/* Resolve image from page bundle, site assets, remote, or static URLs */}}
+ {{ $image_resource := false }}
+ {{ $image_url := "" }}
+
+ {{ if $banner_filename }}
+ {{ $image_path := strings.TrimSpace (printf "%v" $banner_filename) }}
+ {{ $is_remote := or (strings.HasPrefix $image_path "http://") (strings.HasPrefix $image_path "https://") }}
+
+ {{ if $is_remote }}
+ {{ $remote := try (resources.GetRemote $image_path) }}
+ {{ if and $remote (not $remote.Err) }}
+ {{ $image_resource = $remote.Value }}
+ {{ else }}
+ {{ $image_url = $image_path }}
+ {{ end }}
+ {{ else }}
+ {{ $image_path = strings.TrimPrefix "/" $image_path }}
+ {{ $image_path = strings.TrimPrefix "./" $image_path }}
+ {{ $image_path = strings.TrimPrefix "assets/" $image_path }}
+ {{ $image_path = strings.TrimPrefix "media/" $image_path }}
+ {{ $normalized := path.Clean $image_path }}
+
+ {{ if and $normalized (ne $normalized ".") }}
+ {{ with $page }}
+ {{ $image_resource = (.Resources.ByType "image").GetMatch $normalized }}
+ {{ end }}
+ {{ if not $image_resource }}
+ {{ $image_resource = resources.Get (path.Join "media" $normalized) }}
+ {{ end }}
+ {{ if not $image_resource }}
+ {{ $image_url = printf "/media/%s" $normalized }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+ {{ $img = $image_resource }}
+
+ {{ if $img }}
+
+ {{ if ne $img.MediaType.SubType "gif" }}
+ {{ $responsive := partial "functions/process_responsive_image.html" (dict
+ "image" $img
+ "mode" "fill"
+ "aspect_ratio" "16:9"
+ "sizes" (slice 768 1024 1366 1920 2560)
+ ) }}
+

+ {{ else }}
+ {{- $img = $img.Process "webp" -}}
+

+ {{ end }}
+
+ {{ else if $image_url }}
+ {{ $is_external := or (strings.HasPrefix $image_url "http://") (strings.HasPrefix $image_url "https://") }}
+
+

+
+ {{ end }}
+
+ {{/* Avatar */}}
+ {{ $status_icon := "" }}
+ {{ $status := $profile.status }}
+ {{ if and $status (reflect.IsMap $status) }}
+ {{ $status_icon_raw := index $status "icon" }}
+ {{ if eq (printf "%T" $status_icon_raw) "string" }}
+ {{ $status_icon = strings.TrimSpace $status_icon_raw }}
+ {{ end }}
+ {{ end }}
+
+ {{ if $avatar }}
+
+ {{ $avatar_image := $avatar.Fill (printf "%sx%s Center" $generation_size $generation_size) }}
+

+ {{ with $status_icon }}
{{ . | emojify }}{{ end }}
+
+ {{ end }}
+
+ {{/* Name and Role - Centered */}}
+
+ {{/* Extract pronunciation for ruby annotation */}}
+ {{ $name_pronunciation := "" }}
+ {{ with $profile.name_pronunciation }}
+ {{ if eq (printf "%T" .) "string" }}
+ {{ $name_pronunciation = strings.TrimSpace . }}
+ {{ end }}
+ {{ end }}
+
+ {{/* Name with optional ruby pronunciation */}}
+ {{ if and $profile.title $name_pronunciation }}
+
+ {{ $profile.title }}
+
+ {{ else }}
+
+ {{ $profile.title }}
+
+ {{ end }}
+
+ {{ $pronouns := "" }}
+ {{ with $profile.pronouns }}
+ {{ if eq (printf "%T" .) "string" }}
+ {{ $pronouns = . }}
+ {{ end }}
+ {{ end }}
+ {{ with $pronouns }}
+
({{ . }})
+ {{ end }}
+
+ {{ $role_text := "" }}
+ {{ with $profile.role }}
+ {{ if eq (printf "%T" .) "string" }}
+ {{ $role_text = . }}
+ {{ end }}
+ {{ end }}
+ {{ with $role_text }}
+
{{ . | markdownify | emojify }}
+ {{ end }}
+
+ {{ $affiliations_raw := $profile.affiliations }}
+ {{ $affiliations := slice }}
+ {{ if reflect.IsSlice $affiliations_raw }}
+ {{ $affiliations = $affiliations_raw }}
+ {{ else if eq (printf "%T" $affiliations_raw) "string" }}
+ {{ $affiliations = slice $affiliations_raw }}
+ {{ end }}
+ {{ range $affiliations }}
+ {{ $aff_name := "" }}
+ {{ $aff_url := "" }}
+ {{ if reflect.IsMap . }}
+ {{ $nameRaw := index . "name" | default (index . "title") }}
+ {{ if ne $nameRaw nil }}
+ {{ $aff_name = printf "%v" $nameRaw }}
+ {{ end }}
+ {{ $urlRaw := index . "url" }}
+ {{ if eq (printf "%T" $urlRaw) "string" }}
+ {{ $aff_url = $urlRaw }}
+ {{ end }}
+ {{ else if eq (printf "%T" .) "string" }}
+ {{ $aff_name = . }}
+ {{ end }}
+ {{ $aff_name = strings.TrimSpace $aff_name }}
+ {{ $aff_url = strings.TrimSpace $aff_url }}
+ {{ if $aff_name }}
+
+ {{ if $aff_url }}
+ {{ $link := $aff_url }}
+ {{ $scheme := (urls.Parse $link).Scheme }}
+ {{ $target := "" }}
+ {{ if not $scheme }}
+ {{ if not (hasPrefix $link "#") }}
+ {{ $link = $link | relLangURL }}
+ {{ end }}
+ {{ if eq (path.Ext $link) ".pdf" }}{{ $target = "target=\"_blank\" rel=\"noopener\"" }}{{ end }}
+ {{ else if in (slice "http" "https") $scheme }}
+ {{ $target = "target=\"_blank\" rel=\"noopener\"" }}
+ {{ end }}
+ {{ $aff_name }}
+ {{ else }}
+ {{ $aff_name }}
+ {{ end }}
+
+ {{ end }}
+ {{ end }}
+
+
+ {{/* Social Icons */}}
+ {{ $links_raw := $profile.links }}
+ {{ $links := slice }}
+ {{ if reflect.IsSlice $links_raw }}
+ {{ $links = $links_raw }}
+ {{ else if eq (printf "%T" $links_raw) "string" }}
+ {{ $links = slice $links_raw }}
+ {{ end }}
+ {{ if gt (len $links) 0 }}
+
+ {{ range $links }}
+ {{ $linkUrl := "" }}
+ {{ $iconName := "hero/link" }}
+ {{ $linkLabel := "" }}
+ {{ if reflect.IsMap . }}
+ {{ $urlRaw := index . "url" | default (index . "link") }}
+ {{ if eq (printf "%T" $urlRaw) "string" }}
+ {{ $linkUrl = $urlRaw }}
+ {{ end }}
+ {{ $iconRaw := index . "icon" }}
+ {{ if eq (printf "%T" $iconRaw) "string" }}
+ {{ $iconName = $iconRaw }}
+ {{ end }}
+ {{ $labelRaw := index . "label" }}
+ {{ if eq (printf "%T" $labelRaw) "string" }}
+ {{ $linkLabel = $labelRaw }}
+ {{ end }}
+ {{ else if eq (printf "%T" .) "string" }}
+ {{ $linkUrl = . }}
+ {{ end }}
+ {{ $linkUrl = strings.TrimSpace $linkUrl }}
+ {{ if $linkUrl }}
+ {{ $scheme := (urls.Parse $linkUrl).Scheme }}
+ {{ $target := "" }}
+ {{ if not $scheme }}
+ {{ if not (hasPrefix $linkUrl "#") }}
+ {{ $linkUrl = $linkUrl | relLangURL }}
+ {{ end }}
+ {{ if eq (path.Ext $linkUrl) ".pdf" }}{{ $target = "target=\"_blank\" rel=\"noopener\"" }}{{ end }}
+ {{ else if in (slice "http" "https") $scheme }}
+ {{ $target = "target=\"_blank\" rel=\"noopener\"" }}
+ {{ end }}
+
+ {{ partial "functions/get_icon" (dict "name" $iconName "attributes" "class=\"w-6 h-6\"") }}
+
+ {{ end }}
+ {{ end }}
+
+ {{ end }}
+
+
+ {{/* Bio Section */}}
+ {{ $bio_content := "" }}
+ {{ $bio_override_raw := index $content "text" }}
+ {{ if ne $bio_override_raw nil }}
+ {{ $bio_content = printf "%v" $bio_override_raw | emojify | $page.RenderString }}
+ {{ end }}
+ {{ if not $bio_content }}
+ {{ with $profile.bio }}{{ $bio_content = printf "%v" . | emojify | $page.RenderString }}{{ end }}
+ {{ end }}
+ {{ with $bio_content }}
+
+
+
+ {{ partial "functions/get_icon" (dict "name" "identification" "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }}
+
+ {{ $i18n_about := i18n "about_me" }}
+ {{ $about_default := cond (eq $i18n_about "about_me") "Professional Summary" $i18n_about }}
+ {{ $about_heading := $about_default }}
+ {{ $about_heading_raw := index $headings "about" }}
+ {{ if eq (printf "%T" $about_heading_raw) "string" }}
+ {{ $about_heading_raw = strings.TrimSpace $about_heading_raw }}
+ {{ if ne $about_heading_raw "" }}
+ {{ $about_heading = $about_heading_raw }}
+ {{ end }}
+ {{ end }}
+
{{ $about_heading }}
+
+
+
+ {{ end }}
+
+ {{/* CV Download Buttons - supports singular "button" or plural "buttons" */}}
+ {{ $all_buttons := slice }}
+ {{ $button_raw := index $content "button" }}
+ {{ if and $button_raw (reflect.IsMap $button_raw) }}
+ {{ $all_buttons = slice $button_raw }}
+ {{ end }}
+ {{ $buttons_raw := index $content "buttons" }}
+ {{ if and $buttons_raw (reflect.IsSlice $buttons_raw) }}
+ {{ $all_buttons = $buttons_raw }}
+ {{ end }}
+ {{ if gt (len $all_buttons) 0 }}
+
+ {{ range $all_buttons }}
+ {{ if reflect.IsMap . }}
+ {{ $button_text := "" }}
+ {{ $button_url := "" }}
+ {{ with index . "text" }}{{ $button_text = printf "%v" . }}{{ end }}
+ {{ with index . "url" }}{{ $button_url = printf "%v" . }}{{ end }}
+ {{ $button_text = strings.TrimSpace $button_text }}
+ {{ $button_url = strings.TrimSpace $button_url }}
+ {{ if and $button_text $button_url }}
+ {{ $button_link := $button_url }}
+ {{ $scheme := (urls.Parse $button_link).Scheme }}
+ {{ $target := "" }}
+ {{ if not $scheme }}
+ {{ if not (hasPrefix $button_link "#") }}
+ {{ $button_link = $button_link | relLangURL }}
+ {{ end }}
+ {{ if eq (path.Ext $button_link) ".pdf" }}{{ $target = "target=\"_blank\" rel=\"noopener\"" }}{{ end }}
+ {{ else if in (slice "http" "https") $scheme }}
+ {{ $target = "target=\"_blank\" rel=\"noopener\"" }}
+ {{ end }}
+
+ {{ partial "functions/get_icon" (dict "name" "document-arrow-down" "attributes" "class='w-5 h-5 mr-3'") }}
+ {{ $button_text }}
+
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+ {{ end }}
+
+ {{/* Education Section */}}
+ {{ $education_raw := $profile.education }}
+ {{ $education := slice }}
+ {{ if reflect.IsSlice $education_raw }}
+ {{ $education = $education_raw }}
+ {{ end }}
+ {{ if gt (len $education) 0 }}
+
+
+
+ {{ partial "functions/get_icon" (dict "name" "academic-cap" "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }}
+
+ {{ $education_heading := i18n "education" }}
+ {{ $education_heading_raw := index $headings "education" }}
+ {{ if eq (printf "%T" $education_heading_raw) "string" }}
+ {{ $education_heading_raw = strings.TrimSpace $education_heading_raw }}
+ {{ if ne $education_heading_raw "" }}
+ {{ $education_heading = $education_heading_raw }}
+ {{ end }}
+ {{ end }}
+
{{ $education_heading | markdownify }}
+
+
+ {{ range $education }}
+ {{ if reflect.IsMap . }}
+ {{ $degree := "" }}
+ {{ $degreeRaw := index . "degree" | default (index . "area") }}
+ {{ if ne $degreeRaw nil }}{{ $degree = printf "%v" $degreeRaw }}{{ end }}
+ {{ $year := "" }}
+ {{ with index . "year" }}{{ $year = printf "%v" . }}{{ end }}
+ {{ $start := "" }}
+ {{ with index . "start" }}{{ $start = printf "%v" . }}{{ end }}
+ {{ $end := "" }}
+ {{ with index . "end" }}{{ $end = printf "%v" . }}{{ end }}
+ {{ $institution := "" }}
+ {{ with index . "institution" }}{{ $institution = printf "%v" . }}{{ end }}
+ {{ $icon := "" }}
+ {{ $iconRaw := index . "icon" }}
+ {{ if eq (printf "%T" $iconRaw) "string" }}
+ {{ $icon = $iconRaw }}
+ {{ end }}
+
+
+
+ {{ if $icon }}
+ {{ partial "functions/get_icon" (dict "name" $icon "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }}
+ {{ else }}
+ {{ partial "functions/get_icon" (dict "name" "academic-cap" "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }}
+ {{ end }}
+
+
+ {{ if $degree }}
+
+ {{ $degree }}
+
+ {{ end }}
+ {{ if $year }}
+
{{ $year }}
+ {{ else if $start }}
+
+ {{ $start }}
+ {{ if $end }}
{{ $end }}{{ end }}
+
+ {{ end }}
+ {{ if $institution }}
+
{{ $institution }}
+ {{ end }}
+
+
+
+ {{ end }}
+ {{ end }}
+
+
+ {{ end }}
+
+ {{/* Interests Section */}}
+ {{ $interests_raw := $profile.interests }}
+ {{ $interests := slice }}
+ {{ if reflect.IsSlice $interests_raw }}
+ {{ $interests = $interests_raw }}
+ {{ else if eq (printf "%T" $interests_raw) "string" }}
+ {{ $interests = slice $interests_raw }}
+ {{ end }}
+ {{ if gt (len $interests) 0 }}
+
+
+
+ {{ partial "functions/get_icon" (dict "name" "sparkles" "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }}
+
+ {{ $interests_heading := i18n "interests" }}
+ {{ $interests_heading_raw := index $headings "interests" }}
+ {{ if eq (printf "%T" $interests_heading_raw) "string" }}
+ {{ $interests_heading_raw = strings.TrimSpace $interests_heading_raw }}
+ {{ if ne $interests_heading_raw "" }}
+ {{ $interests_heading = $interests_heading_raw }}
+ {{ end }}
+ {{ end }}
+
{{ $interests_heading | markdownify }}
+
+
+ {{ range $interests }}
+ {{ $interest := strings.TrimSpace (printf "%v" .) }}
+ {{ if $interest }}
+
+ {{ $interest | markdownify | emojify }}
+
+ {{ end }}
+ {{ end }}
+
+
+ {{ end }}
+