diff --git a/modules/blox-tailwind/assets/css/framework/components.css b/modules/blox-tailwind/assets/css/framework/components.css index 5ee95567..cb7846ca 100644 --- a/modules/blox-tailwind/assets/css/framework/components.css +++ b/modules/blox-tailwind/assets/css/framework/components.css @@ -5,12 +5,12 @@ padding-top: 6rem; padding-bottom: 6rem; } - + .section-subheading { font-size: 1.25rem; font-weight: 700; } - + /* Home section background styles */ .home-section-bg { position: absolute; @@ -20,13 +20,27 @@ width: 100%; z-index: -1; } - + .home-section-bg.bg-image { background-position: center; background-repeat: no-repeat; background-size: cover; } - + + /* 2025 Glassmorphism texture support - disable conflicting defaults */ + .home-section-bg.bg-image[style*='background-size'][style*='background-repeat'] { + background-size: revert !important; + background-repeat: revert !important; + background-position: revert !important; + } + + /* Specific glassmorphism texture class override */ + .blox-cta-card .home-section-bg.bg-image { + background-size: revert; + background-repeat: revert; + background-position: revert; + } + /* Video background */ .bg-video { position: absolute; @@ -38,12 +52,12 @@ object-position: center center; opacity: 1; } - + /* Flip video horizontally */ .bg-video.flip { transform: scaleX(-1); } - + /* Container styles */ .universal-wrapper { margin: 0 auto; @@ -51,18 +65,18 @@ padding-left: 1rem; width: 100%; } - + @media (min-width: 1200px) { .universal-wrapper { max-width: 1200px; } } - + .article-container { max-width: 760px; margin: 0 auto; } - + /* Button toolbar */ .btn-toolbar { display: flex; @@ -70,26 +84,26 @@ justify-content: center; gap: 0.5rem; } - + /* Documentation specific */ .docs-article-container { max-width: 760px; } - + /* Powered-by footer styles */ .powered-by { font-size: 0.75rem; } - + .powered-by a { color: inherit; text-decoration: none; } - + .powered-by a:hover { text-decoration: underline; } - + /* Parallax effect */ .parallax { background-attachment: fixed; @@ -98,17 +112,17 @@ background-size: cover; position: relative; } - + /* When parallax is used with home-section-bg, preserve absolute positioning */ .home-section-bg.parallax { position: absolute; } - + /* Section color schemes - for backward compatibility */ section.light { background-color: transparent; } - + section.dark { background-color: transparent; } diff --git a/modules/blox-tailwind/layouts/_partials/functions/get-block-scripts.html b/modules/blox-tailwind/layouts/_partials/functions/get-block-scripts.html new file mode 100644 index 00000000..c577222c --- /dev/null +++ b/modules/blox-tailwind/layouts/_partials/functions/get-block-scripts.html @@ -0,0 +1,19 @@ +{{/* + Get Block Scripts + Discovers and returns a slice of JavaScript files for blocks used on the current page. +*/}} +{{ $block_scripts := slice }} +{{ if .IsPage }} + {{/* Get the list of unique block types used on this page from the Page Store */}} + {{ $block_types := .Page.Store.Get "block_types" | default (slice) | uniq }} + + {{ range $block_type := $block_types }} + {{/* Check if a JS file exists for this block type */}} + {{ $script_path := printf "js/hbx/blocks/%s/%s.js" $block_type $block_type }} + {{ with resources.Get $script_path }} + {{ $block_scripts = $block_scripts | append . }} + {{ end }} + {{ end }} +{{ end }} +{{ return $block_scripts }} + diff --git a/modules/blox-tailwind/layouts/_partials/functions/parse_block_v2.html b/modules/blox-tailwind/layouts/_partials/functions/parse_block_v2.html index 68bbd508..017d5179 100644 --- a/modules/blox-tailwind/layouts/_partials/functions/parse_block_v2.html +++ b/modules/blox-tailwind/layouts/_partials/functions/parse_block_v2.html @@ -33,12 +33,176 @@ {{ $style_bg := "" }} {{ if $bg.color }} - {{ $style_bg = printf "background-color: %s;" ($bg.color | default "transparent") }} + {{/* Check if color is a map/dict (light/dark structure) or a simple string */}} + {{ $color_type := printf "%T" $bg.color }} + {{ if eq $color_type "map[string]interface {}" }} + {{/* New nested light/dark structure */}} + {{ if and $bg.color.light $bg.color.dark }} + {{ $light_color := $bg.color.light }} + {{ $dark_color := $bg.color.dark }} + + {{/* Convert light color */}} + {{ if not (or (hasPrefix $light_color "var(") (hasPrefix $light_color "rgb(") (hasPrefix $light_color "#") (eq $light_color "transparent")) }} + {{ if hasPrefix $light_color "primary-" }} + {{ $shade := strings.TrimPrefix "primary-" $light_color }} + {{ $light_color = printf "var(--color-primary-%s)" $shade }} + {{ else if hasPrefix $light_color "secondary-" }} + {{ $shade := strings.TrimPrefix "secondary-" $light_color }} + {{ $light_color = printf "var(--color-secondary-%s)" $shade }} + {{ else if strings.Contains $light_color "-" }} + {{ $parts := split $light_color "-" }} + {{ if eq (len $parts) 2 }} + {{ $color := index $parts 0 }} + {{ $shade := index $parts 1 }} + {{ $light_color = printf "var(--color-%s-%s)" $color $shade }} + {{ end }} + {{ end }} + {{ end }} + + {{/* Convert dark color */}} + {{ if not (or (hasPrefix $dark_color "var(") (hasPrefix $dark_color "rgb(") (hasPrefix $dark_color "#") (eq $dark_color "transparent")) }} + {{ if hasPrefix $dark_color "primary-" }} + {{ $shade := strings.TrimPrefix "primary-" $dark_color }} + {{ $dark_color = printf "var(--color-primary-%s)" $shade }} + {{ else if hasPrefix $dark_color "secondary-" }} + {{ $shade := strings.TrimPrefix "secondary-" $dark_color }} + {{ $dark_color = printf "var(--color-secondary-%s)" $shade }} + {{ else if strings.Contains $dark_color "-" }} + {{ $parts := split $dark_color "-" }} + {{ if eq (len $parts) 2 }} + {{ $color := index $parts 0 }} + {{ $shade := index $parts 1 }} + {{ $dark_color = printf "var(--color-%s-%s)" $color $shade }} + {{ end }} + {{ end }} + {{ end }} + + {{ $style_bg = printf "background-color: %s;" $light_color }} + {{ $style_bg = printf "%s--dark-bg-color: %s;" $style_bg $dark_color }} + {{ else if $bg.color.light }} + {{ $light_color := $bg.color.light }} + + {{/* Convert light color */}} + {{ if not (or (hasPrefix $light_color "var(") (hasPrefix $light_color "rgb(") (hasPrefix $light_color "#") (eq $light_color "transparent")) }} + {{ if hasPrefix $light_color "primary-" }} + {{ $shade := strings.TrimPrefix "primary-" $light_color }} + {{ $light_color = printf "var(--color-primary-%s)" $shade }} + {{ else if hasPrefix $light_color "secondary-" }} + {{ $shade := strings.TrimPrefix "secondary-" $light_color }} + {{ $light_color = printf "var(--color-secondary-%s)" $shade }} + {{ else if strings.Contains $light_color "-" }} + {{ $parts := split $light_color "-" }} + {{ if eq (len $parts) 2 }} + {{ $color := index $parts 0 }} + {{ $shade := index $parts 1 }} + {{ $light_color = printf "var(--color-%s-%s)" $color $shade }} + {{ end }} + {{ end }} + {{ end }} + + {{ $style_bg = printf "background-color: %s;" $light_color }} + {{ else if $bg.color.dark }} + {{ $dark_color := $bg.color.dark }} + + {{/* Convert dark color */}} + {{ if not (or (hasPrefix $dark_color "var(") (hasPrefix $dark_color "rgb(") (hasPrefix $dark_color "#") (eq $dark_color "transparent")) }} + {{ if hasPrefix $dark_color "primary-" }} + {{ $shade := strings.TrimPrefix "primary-" $dark_color }} + {{ $dark_color = printf "var(--color-primary-%s)" $shade }} + {{ else if hasPrefix $dark_color "secondary-" }} + {{ $shade := strings.TrimPrefix "secondary-" $dark_color }} + {{ $dark_color = printf "var(--color-secondary-%s)" $shade }} + {{ else if strings.Contains $dark_color "-" }} + {{ $parts := split $dark_color "-" }} + {{ if eq (len $parts) 2 }} + {{ $color := index $parts 0 }} + {{ $shade := index $parts 1 }} + {{ $dark_color = printf "var(--color-%s-%s)" $color $shade }} + {{ end }} + {{ end }} + {{ end }} + + {{ $style_bg = printf "--dark-bg-color: %s; background-color: var(--dark-bg-color);" $dark_color }} + {{ end }} + {{ else }} + {{/* Legacy single color support - backwards compatible */}} + {{ $bg_color := $bg.color }} + + {{/* Convert single color */}} + {{ if not (or (hasPrefix $bg_color "var(") (hasPrefix $bg_color "rgb(") (hasPrefix $bg_color "#") (eq $bg_color "transparent")) }} + {{ if hasPrefix $bg_color "primary-" }} + {{ $shade := strings.TrimPrefix "primary-" $bg_color }} + {{ $bg_color = printf "var(--color-primary-%s)" $shade }} + {{ else if hasPrefix $bg_color "secondary-" }} + {{ $shade := strings.TrimPrefix "secondary-" $bg_color }} + {{ $bg_color = printf "var(--color-secondary-%s)" $shade }} + {{ else if strings.Contains $bg_color "-" }} + {{ $parts := split $bg_color "-" }} + {{ if eq (len $parts) 2 }} + {{ $color := index $parts 0 }} + {{ $shade := index $parts 1 }} + {{ $bg_color = printf "var(--color-%s-%s)" $color $shade }} + {{ end }} + {{ end }} + {{ end }} + + {{ $style_bg = printf "background-color: %s;" $bg_color }} + {{ end }} {{ end }} +{{/* Modern layered background support for 2025 glassmorphism */}} +{{ $background_layers := slice }} +{{ $gradient_layer := "" }} + +{{/* Process gradients first but don't add to layers yet */}} +{{/* Support legacy gradient syntax */}} {{ if and $bg.gradient_start $bg.gradient_end }} {{ $angle := string $bg.gradient_angle | default "90" }} - {{ $style_bg = printf "%sbackground-image: linear-gradient(%sdeg, %s, %s);" $style_bg $angle $bg.gradient_start $bg.gradient_end }} + {{ $gradient_layer = printf "linear-gradient(%sdeg, %s, %s)" $angle $bg.gradient_start $bg.gradient_end }} +{{ end }} + +{{/* Support modern gradient syntax for 2025 */}} +{{ if and $bg.gradient.start $bg.gradient.end }} + {{ $angle := string $bg.gradient.direction | default "135" }} + {{ $start_color := $bg.gradient.start }} + {{ $end_color := $bg.gradient.end }} + + {{/* Convert Tailwind color names to CSS custom properties */}} + {{ if not (or (hasPrefix $start_color "var(") (hasPrefix $start_color "rgb(") (hasPrefix $start_color "#")) }} + {{ if hasPrefix $start_color "primary-" }} + {{ $shade := strings.TrimPrefix "primary-" $start_color }} + {{ $start_color = printf "var(--color-primary-%s)" $shade }} + {{ else if hasPrefix $start_color "secondary-" }} + {{ $shade := strings.TrimPrefix "secondary-" $start_color }} + {{ $start_color = printf "var(--color-secondary-%s)" $shade }} + {{ else if strings.Contains $start_color "-" }} + {{ $parts := split $start_color "-" }} + {{ if eq (len $parts) 2 }} + {{ $color := index $parts 0 }} + {{ $shade := index $parts 1 }} + {{ $start_color = printf "var(--color-%s-%s)" $color $shade }} + {{ end }} + {{ end }} + {{ end }} + + {{ if not (or (hasPrefix $end_color "var(") (hasPrefix $end_color "rgb(") (hasPrefix $end_color "#")) }} + {{ if hasPrefix $end_color "primary-" }} + {{ $shade := strings.TrimPrefix "primary-" $end_color }} + {{ $end_color = printf "var(--color-primary-%s)" $shade }} + {{ else if hasPrefix $end_color "secondary-" }} + {{ $shade := strings.TrimPrefix "secondary-" $end_color }} + {{ $end_color = printf "var(--color-secondary-%s)" $shade }} + {{ else if strings.Contains $end_color "-" }} + {{ $parts := split $end_color "-" }} + {{ if eq (len $parts) 2 }} + {{ $color := index $parts 0 }} + {{ $shade := index $parts 1 }} + {{ $end_color = printf "var(--color-%s-%s)" $color $shade }} + {{ end }} + {{ end }} + {{ end }} + + {{ $gradient_layer = printf "linear-gradient(%sdeg, %s, %s)" $angle $start_color $end_color }} {{ end }} {{ $bg_video := "" }} @@ -58,17 +222,64 @@ {{ if ne $bg_img.MediaType.SubType "svg" }} {{ $bg_img = $bg_img.Fit "1920x1920 webp" }} {{ end }} - {{ $style_bg = printf "%sbackground-image: url('%s');" $style_bg $bg_img.Permalink }} + + {{/* Add image layer to background layers for glassmorphism support */}} + {{ $image_layer := printf "url('%s')" $bg_img.Permalink }} + {{ $background_layers = $background_layers | append $image_layer }} + + {{/* Background properties will be set in the multi-layer section below */}} {{ else }} {{ errorf "Couldn't find `%s` in the `assets/media/` folder - please add it." $bg.image.filename }} {{ end }} - {{ with $bg.image.size }} - {{/* Allow sizes: actual, cover, and contain. */}} - {{ $style_bg = printf "%sbackground-size: %s;" $style_bg (replace . "actual" "auto") }} +{{ end }} + +{{/* Combine all background layers for 2025 glassmorphism effects */}} +{{/* Layer order: image (top) comes first, then gradient (bottom) */}} +{{ if or $background_layers $gradient_layer }} + {{ $all_layers := $background_layers }} + {{ if $gradient_layer }} + {{ $all_layers = $all_layers | append $gradient_layer }} {{ end }} - {{ with $bg.image.position }} - {{/* Allow valid CSS positions including left, center, and right. */}} - {{ $style_bg = printf "%sbackground-position: %s;" $style_bg . }} + {{ if $all_layers }} + {{ $combined_backgrounds := delimit $all_layers ", " }} + {{ $style_bg = printf "%sbackground-image: %s;" $style_bg $combined_backgrounds }} + + {{/* Build multi-layer background properties */}} + {{ $layer_count := len $all_layers }} + + {{/* Generate properties for each layer */}} + {{ if gt $layer_count 1 }} + {{/* Multiple layers: image + gradient */}} + {{ $img_size := $bg.image.size | default "100px" }} + {{ $img_position := $bg.image.position | default "center" }} + {{ $img_repeat := $bg.image.repeat | default "repeat" }} + + {{/* Handle 'repeat' in position */}} + {{ if eq $img_position "repeat" }} + {{ $img_repeat = "repeat" }} + {{ $img_position = "center" }} + {{ end }} + + {{/* Combine properties for both layers */}} + {{ $style_bg = printf "%sbackground-size: %s, cover !important;" $style_bg $img_size }} + {{ $style_bg = printf "%sbackground-position: %s, center !important;" $style_bg $img_position }} + {{ $style_bg = printf "%sbackground-repeat: %s, no-repeat !important;" $style_bg $img_repeat }} + {{ else }} + {{/* Single layer: apply properties normally */}} + {{ if $background_layers }} + {{ with $bg.image.size }} + {{ $style_bg = printf "%sbackground-size: %s !important;" $style_bg . }} + {{ end }} + {{ with $bg.image.position }} + {{ if eq . "repeat" }} + {{ $style_bg = printf "%sbackground-position: center !important;" $style_bg }} + {{ $style_bg = printf "%sbackground-repeat: repeat !important;" $style_bg }} + {{ else }} + {{ $style_bg = printf "%sbackground-position: %s !important;" $style_bg . }} + {{ end }} + {{ end }} + {{ end }} + {{ end }} {{ end }} {{ end }} @@ -129,9 +340,12 @@ {{end}} */}} +{{/* Extract background-specific CSS classes */}} +{{ $bg_css_classes := $bg.css_class | default "" }} + {{/* Dedicated child div for bg prevents parallax 100% height issue within new CSS grid page wrapper. */}}
-
+
{{with $bg_video}}{{end}}
{{if $use_container}}
{{end}} diff --git a/modules/blox-tailwind/layouts/_partials/init.html b/modules/blox-tailwind/layouts/_partials/init.html index 9e499cf3..c86f3457 100644 --- a/modules/blox-tailwind/layouts/_partials/init.html +++ b/modules/blox-tailwind/layouts/_partials/init.html @@ -18,6 +18,13 @@ {{ range $r := .Site.Data.blox_aliases.renames }} {{ $block_type = cond (eq $block_type $r.old) $r.new $block_type }} {{ end }} + + {{/* Store the block type in the page store for asset bundling */}} + {{ $current_blocks := $page.Store.Get "block_types" | default (slice) }} + {{ $page.Store.Set "block_types" ($current_blocks | append $block_type) }} + + {{/* Gallery block is now pure CSS - no Alpine.js needed */}} + {{ $widget_config_file := printf "blox/%s--CONFIG.html" $block_type }} {{ if templates.Exists (printf "_partials/%s" $widget_config_file) }} {{ $hash_id := $block.id | default (printf "section-%s" (replace $block_type "." "-")) }} diff --git a/modules/blox-tailwind/layouts/_partials/site_head.html b/modules/blox-tailwind/layouts/_partials/site_head.html index 0dd7ae5b..3c151ee6 100644 --- a/modules/blox-tailwind/layouts/_partials/site_head.html +++ b/modules/blox-tailwind/layouts/_partials/site_head.html @@ -211,9 +211,6 @@ {{/* !CACHED! Initialized once at site level and then cached for each page */}} {{- partialCached "init.html" . "hb_init_once" -}} - {{/* Load Third-Party Libraries */}} - {{ partial "libraries.html" . }} - {{ $js_license := printf "/*! Hugo Blox Builder Tailwind UI v%s | https://hugoblox.com/ */\n" site.Data.hugoblox.version }} {{ $js_license := $js_license | printf "%s/*! Copyright 2016-present George Cushen (https://georgecushen.com/) */\n" }} {{ $js_license := $js_license | printf "%s/*! License: https://github.com/HugoBlox/hugo-blox-builder/blob/main/LICENSE.md */\n" }} @@ -229,7 +226,16 @@ {{- $js_notifier := resources.Get "js/hb-notifier.js" | js.Build (dict "targetPath" (printf "js/hb-notifier-%s.js" .Lang ) "params" $js_params) | resources.Minify -}} {{- $js_clipboard := resources.Get "js/hb-clipboard.js" | js.Build (dict "targetPath" (printf "js/hb-clipboard-%s.js" .Lang ) "params" $js_params) | resources.Minify -}} {{- $js_citation := resources.Get "js/hb-citation.js" | js.Build (dict "targetPath" (printf "js/hb-citation-%s.js" .Lang ) "params" $js_params) | resources.Minify -}} - {{ $js_bundle := slice $js_bundle_head $js_hugoblox $js_theme $js_lang $js_nav $js_sidebar $js_notifier $js_clipboard $js_citation | resources.Concat (printf "js/hugo-blox-%s.min.js" .Lang) }} + + {{/* Start with the core scripts */}} + {{ $js_bundle_contents := slice $js_bundle_head $js_hugoblox $js_theme $js_lang $js_nav $js_sidebar $js_notifier $js_clipboard $js_citation }} + + {{/* Discover and include block-specific JavaScript */}} + {{- with partial "functions/get-block-scripts.html" . -}} + {{ $js_bundle_contents = $js_bundle_contents | append . }} + {{- end -}} + + {{ $js_bundle := $js_bundle_contents | resources.Concat (printf "js/hugo-blox-%s.min.js" .Lang) }} {{- if hugo.IsProduction -}} {{ $js_bundle = $js_bundle | fingerprint "sha256" }} {{- end -}} @@ -239,6 +245,9 @@ integrity="{{ $js_bundle.Data.Integrity }}" > + {{/* Load Third-Party Libraries */}} + {{ partial "libraries.html" . }} + {{/* EXTENSIBILITY HOOK: HEAD-END */}} {{ partial "functions/get_hook" (dict "hook" "head-end" "context" .) }}