{# NOTE: dynamic_font_size is now provided as a Python global function in manage.py The old macro has been removed to avoid namespace collision. Usage: {% set size = dynamic_font_size(text, width_mm, max_pt, min_pt) %} #} {%- macro render_sidebar_entries(entries, available_width, base_font_pt=9, min_font_pt=7) -%} {%- set ns = namespace(normalized=[]) -%} {%- if entries is mapping -%} {%- for value in entries.values() -%} {%- if value is iterable and value is not mapping and value is not string -%} {%- for item in value -%} {%- set item_str = item | string | trim -%} {%- if item_str -%}{%- set ns.normalized = ns.normalized + [item_str] -%}{%- endif -%} {%- endfor -%} {%- else -%} {%- set item_str = value | string | trim -%} {%- if item_str -%}{%- set ns.normalized = ns.normalized + [item_str] -%}{%- endif -%} {%- endif -%} {%- endfor -%} {%- elif entries is string -%} {%- set ns.normalized = [entries] -%} {%- elif entries is iterable -%} {%- for value in entries -%} {%- if value is iterable and value is not mapping and value is not string -%} {%- for item in value -%} {%- set item_str = item | string | trim -%} {%- if item_str -%}{%- set ns.normalized = ns.normalized + [item_str] -%}{%- endif -%} {%- endfor -%} {%- else -%} {%- set item_str = value | string | trim -%} {%- if item_str -%}{%- set ns.normalized = ns.normalized + [item_str] -%}{%- endif -%} {%- endif -%} {%- endfor -%} {%- else -%} {%- set ns.normalized = [entries | string] -%} {%- endif -%} {%- set delimiter = resume_config.get("sidebar_inline_delimiter") %} {%- if delimiter %} {%- set clean_delimiter = delimiter.strip() %} {%- if clean_delimiter %} {%- set join_token = " " ~ clean_delimiter ~ " " %} {%- else %} {%- set join_token = " " %} {%- endif %} {%- set joined = ns.normalized | join(join_token) %}

{{ joined }}

{%- else %} {%- for entry in ns.normalized %} {%- set text = entry %}

{{ text }}

{%- endfor %} {%- endif %} {%- endmacro %} {%- macro section_icon_svg(section_name) -%} {%- set name_lower = section_name.lower() -%} {% if 'experience' in name_lower or 'work' in name_lower or 'employment' in name_lower %} {# Briefcase icon #} {% elif 'education' in name_lower or 'school' in name_lower or 'university' in name_lower %} {# Graduation cap icon #} {% elif 'project' in name_lower %} {# Projects gear icon #} {% elif 'speak' in name_lower or 'talk' in name_lower or 'presentation' in name_lower %} {# Microphone icon for speaking engagements #} {% elif 'volunteer' in name_lower or 'service' in name_lower %} {# Volunteer service icon #} {% elif 'publication' in name_lower or 'paper' in name_lower or 'journal' in name_lower %} {# Publications icon #} {% elif 'award' in name_lower or 'honor' in name_lower or 'achievement' in name_lower %} {# Award/trophy icon - Simple Flat UI Design #} {% else %} {# Default icon - document/file #} {% endif %} {%- endmacro %} {%- macro section_icon(section_name) -%}
{%- endmacro %} {%- macro section_icon_inline(section_name) -%} {%- endmacro %} {% macro contact_icon(kind) -%} {%- endmacro %} {# ========================================================================== #} {# ICON COLOR CALCULATION WITH WCAG CONTRAST CHECKING #} {# ========================================================================== #} {# This section calculates the optimal icon color to ensure accessibility #} {# by checking WCAG contrast ratios against the sidebar background. #} {# ========================================================================== #} {%- set sidebar_color = resume_config.get("sidebar_color", "#FFFFFF") -%} {%- set sidebar_luminance = none -%} {%- set sidebar_parse_error = false -%} {# Parse sidebar background color and calculate luminance #} {%- if sidebar_color and sidebar_color.startswith('#') -%} {%- set hex_sidebar = sidebar_color[1:] -%} {%- if hex_sidebar|length == 3 -%} {%- set r_bg = (hex_sidebar[0:1] * 2) | int(base=16) -%} {%- set g_bg = (hex_sidebar[1:2] * 2) | int(base=16) -%} {%- set b_bg = (hex_sidebar[2:3] * 2) | int(base=16) -%} {%- elif hex_sidebar|length == 6 -%} {%- set r_bg = hex_sidebar[0:2] | int(base=16) -%} {%- set g_bg = hex_sidebar[2:4] | int(base=16) -%} {%- set b_bg = hex_sidebar[4:6] | int(base=16) -%} {%- else -%} {# Invalid hex format - set error flag #} {%- set sidebar_parse_error = true -%} {%- set r_bg = 255 -%} {%- set g_bg = 255 -%} {%- set b_bg = 255 -%} {%- endif -%} {# Calculate relative luminance (ITU-R BT.601) #} {%- set sidebar_luminance = (0.299 * r_bg + 0.587 * g_bg + 0.114 * b_bg) / 255 -%} {%- else -%} {# Non-hex color - assume light background as fallback #} {%- set sidebar_parse_error = true -%} {%- set sidebar_luminance = 0.9 -%} {%- endif -%} {# Determine automatic high-contrast icon color based on sidebar luminance #} {# Using luminance threshold of 0.5 (midpoint) to decide light vs dark icons #} {%- set icon_contrast_color = none -%} {%- if sidebar_luminance is not none -%} {%- if sidebar_luminance < 0.5 -%} {# Dark background -> use white icons #} {%- set icon_contrast_color = "#FFFFFF" -%} {%- else -%} {# Light background -> use dark icons #} {%- set icon_contrast_color = "#2c3e50" -%} {%- endif -%} {%- else -%} {# Fallback if luminance couldn't be calculated #} {%- set icon_contrast_color = "#2c3e50" -%} {%- endif -%} {# ========================================================================== #} {# RESOLVE FINAL ICON COLOR WITH WCAG CONTRAST VALIDATION #} {# ========================================================================== #} {# Check if user explicitly requested a sidebar icon color #} {%- set requested_sidebar_icon_color = resume_config.get("sidebar_icon_color") -%} {%- set section_icon_color = requested_sidebar_icon_color if requested_sidebar_icon_color else icon_contrast_color -%} {# Parse the requested/initial icon color and calculate its luminance #} {%- set icon_luminance = none -%} {%- set icon_parse_error = false -%} {%- if section_icon_color and section_icon_color.startswith('#') -%} {%- set hex_icon = section_icon_color[1:] -%} {%- if hex_icon|length == 3 -%} {%- set r_icon = (hex_icon[0:1] * 2) | int(base=16) -%} {%- set g_icon = (hex_icon[1:2] * 2) | int(base=16) -%} {%- set b_icon = (hex_icon[2:3] * 2) | int(base=16) -%} {%- elif hex_icon|length == 6 -%} {%- set r_icon = hex_icon[0:2] | int(base=16) -%} {%- set g_icon = hex_icon[2:4] | int(base=16) -%} {%- set b_icon = hex_icon[4:6] | int(base=16) -%} {%- else -%} {%- set icon_parse_error = true -%} {%- set r_icon = none -%} {%- set g_icon = none -%} {%- set b_icon = none -%} {%- endif -%} {%- if r_icon is not none and g_icon is not none and b_icon is not none -%} {%- set icon_luminance = (0.299 * r_icon + 0.587 * g_icon + 0.114 * b_icon) / 255 -%} {%- endif -%} {%- else -%} {%- set icon_parse_error = true -%} {%- endif -%} {# Calculate WCAG contrast ratio and validate accessibility #} {%- set contrast_ratio = none -%} {%- set contrast_check_passed = false -%} {%- if icon_luminance is not none and sidebar_luminance is not none -%} {# WCAG contrast ratio formula: (L1 + 0.05) / (L2 + 0.05) where L1 >= L2 #} {%- if icon_luminance > sidebar_luminance -%} {%- set contrast_ratio = (icon_luminance + 0.05) / (sidebar_luminance + 0.05) -%} {%- else -%} {%- set contrast_ratio = (sidebar_luminance + 0.05) / (icon_luminance + 0.05) -%} {%- endif -%} {# WCAG AA requires 3.0:1 for large text/icons, 4.5:1 for normal text #} {# Using 3.0 threshold for icons (they're similar to large text) #} {%- if contrast_ratio >= 3.0 -%} {%- set contrast_check_passed = true -%} {%- endif -%} {%- endif -%} {# Override with high-contrast color if WCAG check failed or colors couldn't be parsed #} {%- if not contrast_check_passed or icon_parse_error or sidebar_parse_error -%} {%- set section_icon_color = icon_contrast_color -%} {# Recalculate contrast ratio for debug output #} {%- if icon_contrast_color == "#FFFFFF" -%} {%- set final_icon_luminance = 1.0 -%} {%- elif icon_contrast_color == "#2c3e50" -%} {%- set final_icon_luminance = 0.196 -%} {%- else -%} {%- set final_icon_luminance = none -%} {%- endif -%} {%- if final_icon_luminance is not none and sidebar_luminance is not none -%} {%- if final_icon_luminance > sidebar_luminance -%} {%- set contrast_ratio = (final_icon_luminance + 0.05) / (sidebar_luminance + 0.05) -%} {%- else -%} {%- set contrast_ratio = (sidebar_luminance + 0.05) / (final_icon_luminance + 0.05) -%} {%- endif -%} {%- endif -%} {%- endif -%} {# ========================================================================== #} {# SECTION HEADER COLOR CALCULATION #} {# ========================================================================== #} {# Calculate section header color based on theme color luminance. #} {# Light theme colors get dark text, dark theme colors keep their color. #} {# ========================================================================== #} {%- set theme_color = resume_config.get("theme_color", "#0395DE") -%} {%- set section_header_color = theme_color -%} {%- if theme_color.startswith('#') -%} {%- set hex_color = theme_color[1:] -%} {%- if hex_color|length == 3 -%} {%- set r = (hex_color[0:1] * 2) | int(base=16) -%} {%- set g = (hex_color[1:2] * 2) | int(base=16) -%} {%- set b = (hex_color[2:3] * 2) | int(base=16) -%} {%- elif hex_color|length == 6 -%} {%- set r = hex_color[0:2] | int(base=16) -%} {%- set g = hex_color[2:4] | int(base=16) -%} {%- set b = hex_color[4:6] | int(base=16) -%} {%- else -%} {%- set r = 0 -%} {%- set g = 0 -%} {%- set b = 0 -%} {%- endif -%} {%- set luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255 -%} {%- if luminance >= 0.5 -%} {%- set section_header_color = "#2c3e50" -%} {%- endif -%} {%- else -%} {# Fallback for non-hex colors #} {%- set section_header_color = "#2c3e50" -%} {%- endif -%} {% if preview %}
{% endif %}
{% block body %}{% endblock %}
{% if preview %}
{% endif %}