mirror of
https://github.com/tiennm99/HugoBlox-kit.git
synced 2026-10-12 18:15:31 +00:00
feat: modernize blocks with 2025 glassmorphism & UX improvements
CTA Card: - Add 2025 glassmorphism styling with backdrop blur - Implement icon support for buttons with hover animations - Add contrast control (text_color, overlay_opacity) - Support custom backgrounds (image, gradient, texture layers) Hero Block: - Fix hash fragment URL parsing (#portfolio -> #portfolio, not /#portfolio) Infrastructure: - Add reusable glassmorphism CSS components - Create SVG noise texture for glassmorphism effects
This commit is contained in:
1 parent
ef2b77ea92
commit
9140e2f776
7 files changed
+655
-34
No files matched your search
@@ -1,9 +1,10 @@
|
||||
@import "page.css";
|
||||
@import "task-list.css";
|
||||
@import "copy.css";
|
||||
@import "sidebar-left.css";
|
||||
@import "charts.css";
|
||||
@import "steps.css";
|
||||
@import "cards.css";
|
||||
@import "math.css";
|
||||
@import "author-notes.css";
|
||||
@import 'page.css';
|
||||
@import 'task-list.css';
|
||||
@import 'copy.css';
|
||||
@import 'sidebar-left.css';
|
||||
@import 'charts.css';
|
||||
@import 'steps.css';
|
||||
@import 'cards.css';
|
||||
@import 'math.css';
|
||||
@import 'author-notes.css';
|
||||
@import 'glassmorphism.css';
|
||||
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* 2025 Hugo Blox Glassmorphism Utility Classes
|
||||
*
|
||||
* Modern glassmorphism effects for Hugo Blox CTA cards and other components
|
||||
*/
|
||||
|
||||
/* ==========================================================================
|
||||
Glassmorphism Base Classes
|
||||
========================================================================== */
|
||||
|
||||
.glassmorphism-primary {
|
||||
@apply relative overflow-hidden;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgb(var(--color-primary-500) / 0.9),
|
||||
rgb(var(--color-primary-600) / 0.95),
|
||||
rgb(var(--color-primary-700) / 0.9)
|
||||
);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.glassmorphism-primary::before {
|
||||
content: '';
|
||||
@apply absolute inset-0 pointer-events-none;
|
||||
background: linear-gradient(45deg, rgb(0 0 0 / 0.1), transparent, rgb(255 255 255 / 0.1));
|
||||
mix-blend-mode: overlay;
|
||||
}
|
||||
|
||||
.glassmorphism-secondary {
|
||||
@apply relative overflow-hidden;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgb(var(--color-secondary-500) / 0.9),
|
||||
rgb(var(--color-secondary-600) / 0.95),
|
||||
rgb(var(--color-secondary-700) / 0.9)
|
||||
);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.glassmorphism-secondary::before {
|
||||
content: '';
|
||||
@apply absolute inset-0 pointer-events-none;
|
||||
background: linear-gradient(45deg, rgb(0 0 0 / 0.1), transparent, rgb(255 255 255 / 0.1));
|
||||
mix-blend-mode: overlay;
|
||||
}
|
||||
|
||||
.glassmorphism-dark {
|
||||
@apply relative overflow-hidden;
|
||||
background: linear-gradient(135deg, rgb(0 0 0 / 0.7), rgb(31 41 55 / 0.8), rgb(0 0 0 / 0.9));
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.glassmorphism-dark::before {
|
||||
content: '';
|
||||
@apply absolute inset-0 pointer-events-none;
|
||||
background: linear-gradient(45deg, rgb(255 255 255 / 0.05), transparent, rgb(255 255 255 / 0.1));
|
||||
mix-blend-mode: overlay;
|
||||
}
|
||||
|
||||
.glassmorphism-light {
|
||||
@apply relative overflow-hidden;
|
||||
background: linear-gradient(135deg, rgb(255 255 255 / 0.9), rgb(248 250 252 / 0.95), rgb(241 245 249 / 0.9));
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.glassmorphism-light::before {
|
||||
content: '';
|
||||
@apply absolute inset-0 pointer-events-none;
|
||||
background: linear-gradient(45deg, rgb(0 0 0 / 0.02), transparent, rgb(255 255 255 / 0.05));
|
||||
mix-blend-mode: overlay;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Noise Texture Classes (when used as background image)
|
||||
========================================================================== */
|
||||
|
||||
.noise-texture {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.noise-texture::after {
|
||||
content: '';
|
||||
@apply absolute inset-0 pointer-events-none;
|
||||
background-image: url('/media/textures/noise-pattern.svg');
|
||||
background-size: 100px 100px;
|
||||
background-repeat: repeat;
|
||||
opacity: 0.03;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
.dark .noise-texture::after {
|
||||
mix-blend-mode: screen;
|
||||
opacity: 0.02;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Enhanced Ring Classes for 2025 Design
|
||||
========================================================================== */
|
||||
|
||||
.glass-ring {
|
||||
@apply ring-1 ring-white/20 hover:ring-white/40 dark:ring-gray-700/50 dark:hover:ring-gray-600/70;
|
||||
}
|
||||
|
||||
.glass-shadow {
|
||||
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25), 0 0 0 1px rgb(255 255 255 / 0.1),
|
||||
inset 0 1px 0 rgb(255 255 255 / 0.1);
|
||||
}
|
||||
|
||||
.dark .glass-shadow {
|
||||
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5), 0 0 0 1px rgb(255 255 255 / 0.05),
|
||||
inset 0 1px 0 rgb(255 255 255 / 0.05);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
CTA Card Glassmorphism Overlay (works with section backgrounds)
|
||||
========================================================================== */
|
||||
|
||||
.cta-glassmorphism {
|
||||
@apply relative;
|
||||
|
||||
/* Dynamic overlay opacity control */
|
||||
--glassmorphism-opacity: 0.15;
|
||||
|
||||
/* Subtle overlay tint that works with any background */
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgb(255 255 255 / var(--glassmorphism-opacity)) 0%,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) * 0.5)) 50%,
|
||||
rgb(255 255 255 / var(--glassmorphism-opacity)) 100%
|
||||
);
|
||||
|
||||
/* Enhanced glassmorphism effects */
|
||||
backdrop-filter: blur(20px) saturate(1.2);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(1.2);
|
||||
|
||||
/* Modern border and shadow for light mode */
|
||||
border: 1px solid rgb(255 255 255 / calc(var(--glassmorphism-opacity) + 0.1));
|
||||
box-shadow: 0 32px 64px -12px rgb(0 0 0 / 0.25),
|
||||
inset 0 1px 0 rgb(255 255 255 / calc(var(--glassmorphism-opacity) + 0.05));
|
||||
}
|
||||
|
||||
.cta-glassmorphism:hover {
|
||||
/* Enhanced hover state */
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) + 0.05)) 0%,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) * 0.7)) 50%,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) + 0.05)) 100%
|
||||
);
|
||||
|
||||
border: 1px solid rgb(255 255 255 / calc(var(--glassmorphism-opacity) + 0.2));
|
||||
box-shadow: 0 40px 80px -16px rgb(0 0 0 / 0.3),
|
||||
inset 0 1px 0 rgb(255 255 255 / calc(var(--glassmorphism-opacity) + 0.1));
|
||||
}
|
||||
|
||||
/* Dark mode adjustments for CTA glassmorphism */
|
||||
.dark .cta-glassmorphism {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) * 0.5)) 0%,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) * 0.25)) 50%,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) * 0.5)) 100%
|
||||
);
|
||||
|
||||
border: 1px solid rgb(255 255 255 / var(--glassmorphism-opacity));
|
||||
box-shadow: 0 32px 64px -12px rgb(0 0 0 / 0.4),
|
||||
inset 0 1px 0 rgb(255 255 255 / calc(var(--glassmorphism-opacity) * 0.5));
|
||||
}
|
||||
|
||||
.dark .cta-glassmorphism:hover {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) * 0.75)) 0%,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) * 0.4)) 50%,
|
||||
rgb(255 255 255 / calc(var(--glassmorphism-opacity) * 0.75)) 100%
|
||||
);
|
||||
|
||||
border: 1px solid rgb(255 255 255 / calc(var(--glassmorphism-opacity) + 0.05));
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
CTA Button Glassmorphism (nested within CTA cards)
|
||||
========================================================================== */
|
||||
|
||||
.cta-glassmorphism .group {
|
||||
/* Ensure proper text contrast in light mode */
|
||||
color: rgb(var(--color-gray-900));
|
||||
}
|
||||
|
||||
.dark .cta-glassmorphism .group {
|
||||
/* Maintain white text in dark mode */
|
||||
color: rgb(var(--color-gray-100));
|
||||
}
|
||||
|
||||
/* Enhanced button glassmorphism for light mode visibility */
|
||||
.cta-glassmorphism .group > div:first-child {
|
||||
/* Light mode button background */
|
||||
background: rgb(255 255 255 / 0.9);
|
||||
border: 1px solid rgb(0 0 0 / 0.1);
|
||||
box-shadow: 0 10px 25px -5px rgb(0 0 0 / 0.1), 0 4px 6px -2px rgb(0 0 0 / 0.1), inset 0 1px 0 rgb(255 255 255 / 0.3);
|
||||
}
|
||||
|
||||
.dark .cta-glassmorphism .group > div:first-child {
|
||||
/* Dark mode button background */
|
||||
background: rgb(0 0 0 / 0.4);
|
||||
border: 1px solid rgb(255 255 255 / 0.2);
|
||||
box-shadow: 0 10px 25px -5px rgb(0 0 0 / 0.3), 0 4px 6px -2px rgb(0 0 0 / 0.2), inset 0 1px 0 rgb(255 255 255 / 0.1);
|
||||
}
|
||||
|
||||
.cta-glassmorphism .group:hover > div:first-child {
|
||||
background: rgb(255 255 255);
|
||||
border: 1px solid rgb(0 0 0 / 0.15);
|
||||
box-shadow: 0 20px 40px -8px rgb(0 0 0 / 0.15), 0 8px 12px -4px rgb(0 0 0 / 0.1), inset 0 1px 0 rgb(255 255 255 / 0.4);
|
||||
}
|
||||
|
||||
.dark .cta-glassmorphism .group:hover > div:first-child {
|
||||
background: rgb(0 0 0 / 0.6);
|
||||
border: 1px solid rgb(255 255 255 / 0.3);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32">
|
||||
<defs>
|
||||
<!-- Define a noise filter -->
|
||||
<filter id="glassmorphism-noise-filter">
|
||||
<feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="4" stitchTiles="stitch"/>
|
||||
<feColorMatrix type="saturate" values="0"/> <!-- make grayscale -->
|
||||
<feComponentTransfer>
|
||||
<feFuncA type="linear" slope="0.05"/> <!-- opacity of noise -->
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
|
||||
<!-- Define pattern -->
|
||||
<pattern id="glassmorphism-noise" width="32" height="32" patternUnits="userSpaceOnUse">
|
||||
<rect width="32" height="32" filter="url(#glassmorphism-noise-filter)" />
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<!-- Apply noise pattern -->
|
||||
<rect width="32" height="32" fill="url(#glassmorphism-noise)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 799 B |
@@ -6,12 +6,13 @@ Make a bold statement and drive immediate action with the CTA Card block - a hig
|
||||
|
||||
## ✨ Key Features
|
||||
|
||||
- **Bold Typography**: Eye-catching large text that commands attention
|
||||
- **Customizable Styling**: Full control over background colors, CSS classes, and custom styles
|
||||
- **High-Contrast Design**: Dark backgrounds with light text for maximum readability
|
||||
- **Prominent Button**: Conversion-optimized button styling with hover effects
|
||||
- **Markdown Support**: Rich text formatting for titles and descriptions
|
||||
- **Mobile Responsive**: Scales beautifully from mobile to desktop
|
||||
- **🪟 2025 Glassmorphism**: Modern translucent backgrounds with backdrop blur effects
|
||||
- **🎨 Gradient Typography**: Beautiful gradient text effects for maximum visual appeal
|
||||
- **🔗 Smart Icon Support**: Add icons to buttons with automatic sizing and hover animations
|
||||
- **📱 Enhanced Responsiveness**: Fluid typography scaling from mobile to desktop
|
||||
- **✨ Micro-Interactions**: Smooth hover animations with glow effects and transforms
|
||||
- **🎯 Customizable Styling**: Multiple glassmorphism presets or custom CSS classes
|
||||
- **♿ Accessibility Enhanced**: Improved focus states and semantic markup
|
||||
|
||||
## 🎯 Perfect For
|
||||
|
||||
@@ -48,3 +49,163 @@ Make a bold statement and drive immediate action with the CTA Card block - a hig
|
||||
|
||||
Transform casual visitors into engaged users with a CTA Card that's impossible to ignore.
|
||||
|
||||
## 🎨 2025 Glassmorphism Styling Options
|
||||
|
||||
### **Glassmorphism Primary** (Recommended)
|
||||
|
||||
```yaml
|
||||
- block: cta-card
|
||||
content:
|
||||
title: 'Ready to Get Started?'
|
||||
text: 'Join thousands of users creating amazing websites'
|
||||
button:
|
||||
text: 'Get Started Free'
|
||||
url: '/signup/'
|
||||
icon: 'hero/rocket-launch'
|
||||
design:
|
||||
card:
|
||||
css_class: 'cta-glassmorphism'
|
||||
text_color: 'auto' # auto|light|dark
|
||||
overlay_opacity: 0.15 # 0.0-1.0 for contrast control
|
||||
background:
|
||||
gradient:
|
||||
start: 'primary-500'
|
||||
end: 'primary-700'
|
||||
direction: 135
|
||||
image:
|
||||
filename: 'textures/noise-pattern.svg'
|
||||
size: '32px'
|
||||
position: 'repeat'
|
||||
```
|
||||
|
||||
### **Glassmorphism Dark**
|
||||
|
||||
```yaml
|
||||
design:
|
||||
card:
|
||||
css_class: 'glassmorphism-dark glass-ring glass-shadow text-white'
|
||||
```
|
||||
|
||||
### **Glassmorphism Light**
|
||||
|
||||
```yaml
|
||||
design:
|
||||
card:
|
||||
css_class: 'glassmorphism-light glass-ring glass-shadow text-gray-900'
|
||||
```
|
||||
|
||||
### **Custom Background + Glassmorphism**
|
||||
|
||||
```yaml
|
||||
design:
|
||||
card:
|
||||
css_class: 'glassmorphism-secondary noise-texture text-white'
|
||||
background:
|
||||
color: 'primary-600'
|
||||
image:
|
||||
filename: 'your-background.jpg'
|
||||
size: 'cover'
|
||||
position: 'center'
|
||||
opacity: 0.8
|
||||
gradient:
|
||||
start: 'primary-500'
|
||||
end: 'secondary-600'
|
||||
direction: 135
|
||||
```
|
||||
|
||||
## 🔗 Icon Support
|
||||
|
||||
Add icons to your CTA buttons:
|
||||
|
||||
```yaml
|
||||
button:
|
||||
text: 'Download Now'
|
||||
url: '/download/'
|
||||
icon: 'hero/download' # Download icon
|
||||
|
||||
button:
|
||||
text: 'Contact Us'
|
||||
url: 'mailto:hello@example.com'
|
||||
icon: 'hero/paper-airplane' # Email icon
|
||||
|
||||
button:
|
||||
text: 'Learn More'
|
||||
url: '#features'
|
||||
icon: 'hero/arrow-right' # Arrow icon
|
||||
```
|
||||
|
||||
## 🎨 Contrast Control Options
|
||||
|
||||
### **Text Color Modes**
|
||||
|
||||
```yaml
|
||||
card:
|
||||
text_color: 'auto' # Auto-detects based on background brightness
|
||||
text_color: 'light' # Force white text (for dark backgrounds)
|
||||
text_color: 'dark' # Force dark text (for light backgrounds)
|
||||
```
|
||||
|
||||
### **Overlay Opacity Control**
|
||||
|
||||
```yaml
|
||||
card:
|
||||
overlay_opacity: 0.1 # Subtle glassmorphism (better for text contrast)
|
||||
overlay_opacity: 0.15 # Default glassmorphism
|
||||
overlay_opacity: 0.25 # Strong glassmorphism (may reduce contrast)
|
||||
overlay_opacity: 0.05 # Minimal glassmorphism (maximum contrast)
|
||||
```
|
||||
|
||||
### **Perfect Contrast Examples**
|
||||
|
||||
**Dark Background (Light Text):**
|
||||
|
||||
```yaml
|
||||
design:
|
||||
card:
|
||||
css_class: 'cta-glassmorphism'
|
||||
text_color: 'light'
|
||||
overlay_opacity: 0.1
|
||||
background:
|
||||
gradient:
|
||||
start: 'gray-800'
|
||||
end: 'gray-900'
|
||||
```
|
||||
|
||||
**Light Background (Dark Text):**
|
||||
|
||||
```yaml
|
||||
design:
|
||||
card:
|
||||
css_class: 'cta-glassmorphism'
|
||||
text_color: 'dark'
|
||||
overlay_opacity: 0.2
|
||||
background:
|
||||
gradient:
|
||||
start: 'gray-100'
|
||||
end: 'gray-300'
|
||||
```
|
||||
|
||||
**Vibrant Background (Auto Detection):**
|
||||
|
||||
```yaml
|
||||
design:
|
||||
card:
|
||||
css_class: 'cta-glassmorphism'
|
||||
text_color: 'auto' # Will detect primary-500 as medium and use adaptive colors
|
||||
overlay_opacity: 0.15
|
||||
background:
|
||||
gradient:
|
||||
start: 'primary-500'
|
||||
end: 'primary-700'
|
||||
```
|
||||
|
||||
## ✨ Available Glassmorphism Classes
|
||||
|
||||
- **`cta-glassmorphism`**: Smart adaptive glassmorphism with contrast controls
|
||||
- **`glassmorphism-primary`**: Primary color glassmorphism (legacy)
|
||||
- **`glassmorphism-secondary`**: Secondary color glassmorphism (legacy)
|
||||
- **`glassmorphism-dark`**: Dark glassmorphism (legacy)
|
||||
- **`glassmorphism-light`**: Light glassmorphism (legacy)
|
||||
- **`glass-ring`**: Enhanced ring borders
|
||||
- **`glass-shadow`**: Multi-layer glass shadows
|
||||
- **`noise-texture`**: Subtle noise texture overlay
|
||||
@@ -11,20 +11,95 @@
|
||||
{{ $card_class := $block.design.card.css_class }}
|
||||
{{ $card_style := $block.design.card.css_style }}
|
||||
|
||||
{{/* Contrast and accessibility controls */}}
|
||||
{{ $text_color_mode := $block.design.card.text_color | default "auto" }}
|
||||
{{ $overlay_opacity := $block.design.card.overlay_opacity | default 0.15 }}
|
||||
|
||||
<div class="{{with $card_class}}{{.}}{{else}}bg-black{{end}} p-8 md:px-20 md:py-20 mx-auto max-w-5xl rounded-lg flex flex-col items-center text-center"
|
||||
{{with $card_style}}style="{{. | safeCSS}}"{{end}}>
|
||||
<h2 class="text-white text-4xl md:text-6xl tracking-tight">
|
||||
{{ $title }}
|
||||
</h2>
|
||||
<div class="text-gray-100 mt-4 text-lg md:text-xl prose">
|
||||
{{ $text }}
|
||||
</div>
|
||||
{{ with $block.content.button }}
|
||||
<div class="flex mt-5">
|
||||
<a href="{{.url}}" class="rounded text-center transition focus-visible:ring-2 ring-offset-2 ring-gray-200 px-5 py-2.5 bg-white hover:bg-gray-300 text-black border-2 border-transparent">
|
||||
{{.text}}
|
||||
</a>
|
||||
</div>
|
||||
{{/* Auto-detect text color based on background */}}
|
||||
{{ $text_classes := "" }}
|
||||
{{ $button_classes := "" }}
|
||||
{{ if eq $text_color_mode "light" }}
|
||||
{{ $text_classes = "text-white" }}
|
||||
{{ $button_classes = "text-gray-900" }}
|
||||
{{ else if eq $text_color_mode "dark" }}
|
||||
{{ $text_classes = "text-gray-900" }}
|
||||
{{ $button_classes = "text-gray-900" }}
|
||||
{{ else }}
|
||||
{{/* Auto mode - detect based on gradient colors */}}
|
||||
{{ $is_dark_bg := false }}
|
||||
{{ with $block.design.background.gradient.start }}
|
||||
{{ if or (hasPrefix . "primary-7") (hasPrefix . "primary-8") (hasPrefix . "primary-9") (hasPrefix . "secondary-7") (hasPrefix . "secondary-8") (hasPrefix . "secondary-9") }}
|
||||
{{ $is_dark_bg = true }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if $is_dark_bg }}
|
||||
{{ $text_classes = "text-white" }}
|
||||
{{ $button_classes = "text-gray-900" }}
|
||||
{{ else }}
|
||||
{{ $text_classes = "text-gray-900 dark:text-white" }}
|
||||
{{ $button_classes = "text-gray-900 dark:text-gray-100" }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
|
||||
{{/* Modern 2025 CTA Card - Background controlled via design.background in front matter */}}
|
||||
{{ $custom_style := printf "--glassmorphism-opacity: %s;" (string $overlay_opacity) }}
|
||||
{{ if $card_style }}
|
||||
{{ $custom_style = printf "%s%s" $custom_style $card_style }}
|
||||
{{ end }}
|
||||
|
||||
<div class="relative overflow-hidden {{with $card_class}}{{.}}{{else}}bg-gradient-to-br from-primary-500/90 via-primary-600/95 to-primary-700/90{{end}} p-8 sm:p-12 lg:p-16 xl:p-20 mx-auto max-w-6xl rounded-3xl shadow-2xl flex flex-col items-center text-center"
|
||||
style="{{ $custom_style | safeCSS }}">
|
||||
|
||||
{{/* Modern Typography Hierarchy - Responsive text colors */}}
|
||||
<h2 class="{{ $text_classes }} text-4xl sm:text-5xl lg:text-6xl xl:text-7xl font-bold tracking-tight leading-tight">
|
||||
{{ $title }}
|
||||
</h2>
|
||||
|
||||
{{/* Enhanced Text with Better Spacing - Responsive colors */}}
|
||||
<div class="{{ $text_classes }}/80 mt-6 text-lg sm:text-xl lg:text-2xl max-w-3xl leading-relaxed font-light">
|
||||
{{ $text }}
|
||||
</div>
|
||||
|
||||
{{ with $block.content.button }}
|
||||
{{/* Modern 2025 Button Container */}}
|
||||
<div class="flex mt-10">
|
||||
{{ $button_link := .url }}
|
||||
{{ $button_scheme := (urls.Parse $button_link).Scheme }}
|
||||
{{ $button_target := "" }}
|
||||
{{ if not $button_scheme }}
|
||||
{{/* Check if it's a hash fragment (page anchor) */}}
|
||||
{{ if hasPrefix $button_link "#" }}
|
||||
{{/* Keep hash fragments as-is */}}
|
||||
{{ $button_link = $button_link }}
|
||||
{{ else }}
|
||||
{{/* Apply relLangURL for relative paths */}}
|
||||
{{ $button_link = $button_link | relLangURL }}
|
||||
{{ end }}
|
||||
{{ else if in (slice "http" "https") $button_scheme }}
|
||||
{{ $button_target = "target=\"_blank\" rel=\"noopener\"" }}
|
||||
{{ end }}
|
||||
|
||||
{{/* 2025 Glassmorphism Button */}}
|
||||
<a href="{{ $button_link | safeURL }}"
|
||||
{{ $button_target | safeHTMLAttr }}
|
||||
class="group relative inline-flex items-center gap-3 px-8 py-4 text-lg font-semibold {{ $button_classes }} transition-all duration-300 ease-out hover:scale-105 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-gray-500/50 dark:focus-visible:ring-white/50 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent">
|
||||
|
||||
{{/* Button Background with Glassmorphism */}}
|
||||
<div class="absolute inset-0 bg-white/95 dark:bg-gray-900/95 backdrop-blur-md rounded-2xl ring-1 ring-gray-200/30 dark:ring-white/30 shadow-lg group-hover:bg-white dark:group-hover:bg-gray-800 group-hover:ring-gray-300/50 dark:group-hover:ring-white/50 group-hover:shadow-2xl transition-all duration-300"></div>
|
||||
|
||||
{{/* Button Content */}}
|
||||
<span class="relative z-10">{{ .text }}</span>
|
||||
{{ with .icon }}
|
||||
<span class="relative z-10 transition-transform duration-300 group-hover:translate-x-1">
|
||||
{{ partial "functions/get_icon" (dict "name" . "attributes" "style=\"height: 1.25em\" class='inline-block'") }}
|
||||
</span>
|
||||
{{ end }}
|
||||
|
||||
{{/* Subtle glow effect */}}
|
||||
<div class="absolute inset-0 bg-white/20 dark:bg-white/10 rounded-2xl opacity-0 group-hover:opacity-100 transition-opacity duration-300 blur-xl"></div>
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
</div>
|
||||
@@ -31,19 +31,129 @@
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "Button URL"
|
||||
"description": "Button URL (supports hash fragments, relative paths, and absolute URLs)"
|
||||
},
|
||||
"text": {
|
||||
"type": "string",
|
||||
"description": "Button text"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string",
|
||||
"description": "Optional button icon (icon pack format: pack/icon-name)"
|
||||
}
|
||||
},
|
||||
"required": ["url", "text"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"design": {
|
||||
"type": "object",
|
||||
"description": "Design and styling options",
|
||||
"properties": {
|
||||
"card": {
|
||||
"type": "object",
|
||||
"description": "Card-specific styling",
|
||||
"properties": {
|
||||
"css_class": {
|
||||
"type": "string",
|
||||
"description": "CSS classes to apply to the card (supports glassmorphism classes: glassmorphism-primary, glassmorphism-dark, glass-ring, glass-shadow, noise-texture)"
|
||||
},
|
||||
"text_color": {
|
||||
"type": "string",
|
||||
"enum": ["auto", "light", "dark"],
|
||||
"description": "Text color mode for optimal contrast (auto detects based on background)",
|
||||
"default": "auto"
|
||||
},
|
||||
"overlay_opacity": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"description": "Glassmorphism overlay opacity for fine-tuning contrast",
|
||||
"default": 0.15
|
||||
},
|
||||
"css_style": {
|
||||
"type": "string",
|
||||
"description": "Custom CSS styles to apply to the card"
|
||||
}
|
||||
}
|
||||
},
|
||||
"background": {
|
||||
"type": "object",
|
||||
"description": "Modern background options supporting layered effects",
|
||||
"properties": {
|
||||
"color": {
|
||||
"type": "string",
|
||||
"description": "Background color"
|
||||
},
|
||||
"gradient": {
|
||||
"type": "object",
|
||||
"description": "Modern gradient syntax for 2025 glassmorphism",
|
||||
"properties": {
|
||||
"start": {
|
||||
"type": "string",
|
||||
"description": "Gradient start color (e.g., 'primary-500', 'blue-600')"
|
||||
},
|
||||
"end": {
|
||||
"type": "string",
|
||||
"description": "Gradient end color (e.g., 'primary-700', 'blue-800')"
|
||||
},
|
||||
"direction": {
|
||||
"type": "number",
|
||||
"description": "Gradient angle in degrees (default: 90)",
|
||||
"default": 90
|
||||
}
|
||||
}
|
||||
},
|
||||
"image": {
|
||||
"type": "object",
|
||||
"description": "Background image (layers with gradient for glassmorphism)",
|
||||
"properties": {
|
||||
"filename": {
|
||||
"type": "string",
|
||||
"description": "Image filename in assets/media/"
|
||||
},
|
||||
"size": {
|
||||
"type": "string",
|
||||
"enum": ["cover", "contain", "auto", "100px", "50%"],
|
||||
"description": "Background size",
|
||||
"default": "cover"
|
||||
},
|
||||
"position": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"center",
|
||||
"top",
|
||||
"bottom",
|
||||
"left",
|
||||
"right",
|
||||
"repeat",
|
||||
"top left",
|
||||
"top right",
|
||||
"bottom left",
|
||||
"bottom right"
|
||||
],
|
||||
"description": "Background position (use 'repeat' for tiling textures)",
|
||||
"default": "center"
|
||||
},
|
||||
"repeat": {
|
||||
"type": "string",
|
||||
"enum": ["repeat", "repeat-x", "repeat-y", "no-repeat"],
|
||||
"description": "Explicit background-repeat control",
|
||||
"default": "no-repeat"
|
||||
},
|
||||
"opacity": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"description": "Image opacity for subtle textures"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,7 +13,24 @@
|
||||
{{ $announcement := $block.content.announcement }}
|
||||
<div class="hidden sm:mb-8 sm:flex sm:justify-center">
|
||||
<div class="relative rounded-full px-3 py-1 text-sm leading-6 text-gray-600 dark:text-gray-300 ring-1 ring-gray-900/10 dark:ring-gray-300 hover:ring-gray-900/20 dark:hover:ring-gray-400">
|
||||
{{$announcement.text | markdownify}} {{if $announcement.link.text}}<a href="{{$announcement.link.url}}" class="font-semibold text-primary-600 dark:text-primary-300"><span class="absolute inset-0" aria-hidden="true"></span>{{$announcement.link.text}} <span aria-hidden="true">→</span></a>{{end}}
|
||||
{{$announcement.text | markdownify}}
|
||||
{{if $announcement.link.text}}
|
||||
{{ $announcement_link := $announcement.link.url }}
|
||||
{{ $announcement_scheme := (urls.Parse $announcement_link).Scheme }}
|
||||
{{ if not $announcement_scheme }}
|
||||
{{/* Check if it's a hash fragment (page anchor) */}}
|
||||
{{ if hasPrefix $announcement_link "#" }}
|
||||
{{/* Keep hash fragments as-is */}}
|
||||
{{ $announcement_link = $announcement_link }}
|
||||
{{ else }}
|
||||
{{/* Apply relLangURL for relative paths */}}
|
||||
{{ $announcement_link = $announcement_link | relLangURL }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<a href="{{$announcement_link | safeURL}}" class="font-semibold text-primary-600 dark:text-primary-300">
|
||||
<span class="absolute inset-0" aria-hidden="true"></span>{{$announcement.link.text}} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
@@ -27,7 +44,14 @@
|
||||
{{ $scheme := (urls.Parse $link).Scheme }}
|
||||
{{ $target := "" }}
|
||||
{{ if not $scheme }}
|
||||
{{ $link = $link | relLangURL }}
|
||||
{{/* Check if it's a hash fragment (page anchor) */}}
|
||||
{{ if hasPrefix $link "#" }}
|
||||
{{/* Keep hash fragments as-is */}}
|
||||
{{ $link = $link }}
|
||||
{{ else }}
|
||||
{{/* Apply relLangURL for relative paths */}}
|
||||
{{ $link = $link | relLangURL }}
|
||||
{{ end }}
|
||||
{{ else if in (slice "http" "https") $scheme }}
|
||||
{{ $target = "target=\"_blank\" rel=\"noopener\"" }}
|
||||
{{ end }}
|
||||
@@ -45,7 +69,14 @@
|
||||
{{ $scheme_alt := (urls.Parse $link_alt).Scheme }}
|
||||
{{ $target_alt := "" }}
|
||||
{{ if not $scheme_alt }}
|
||||
{{ $link_alt = $link_alt | relLangURL }}
|
||||
{{/* Check if it's a hash fragment (page anchor) */}}
|
||||
{{ if hasPrefix $link_alt "#" }}
|
||||
{{/* Keep hash fragments as-is */}}
|
||||
{{ $link_alt = $link_alt }}
|
||||
{{ else }}
|
||||
{{/* Apply relLangURL for relative paths */}}
|
||||
{{ $link_alt = $link_alt | relLangURL }}
|
||||
{{ end }}
|
||||
{{ else if in (slice "http" "https") $scheme_alt }}
|
||||
{{ $target_alt = "target=\"_blank\" rel=\"noopener\"" }}
|
||||
{{ end }}
|
||||
|
||||
Reference in new issue
Block a user