Minor tweaks and bug fixes.

This commit is contained in:
2026-03-08 01:58:59 -04:00
parent c5d8630ca9
commit 66c505e313
8 changed files with 199 additions and 50 deletions

View File

@@ -173,8 +173,7 @@
function openVideoModal(url) { function openVideoModal(url) {
var ytId = parseYouTubeId(url); var ytId = parseYouTubeId(url);
if (ytId) { if (ytId) {
var origin = encodeURIComponent(window.location.origin); videoPlayer.innerHTML = '<iframe src="https://www.youtube-nocookie.com/embed/' + ytId + '?autoplay=1&rel=0" allow="autoplay; encrypted-media; fullscreen" allowfullscreen frameborder="0"></iframe>';
videoPlayer.innerHTML = '<iframe src="https://www.youtube.com/embed/' + ytId + '?autoplay=1&rel=0&origin=' + origin + '&enablejsapi=1" allow="autoplay; encrypted-media" allowfullscreen frameborder="0"></iframe>';
} else { } else {
videoPlayer.innerHTML = '<video src="' + url + '" controls autoplay></video>'; videoPlayer.innerHTML = '<video src="' + url + '" controls autoplay></video>';
} }

View File

@@ -25,8 +25,9 @@ const TABS = [
id: "hero", id: "hero",
label: "Hero", label: "Hero",
settings: new Set([ settings: new Set([
"hero_title", "hero_subtitle", "hero_card_enabled", "hero_background_image_url", "hero_title", "hero_accent_word", "hero_subtitle",
"hero_image_urls", "hero_image_max_height", "hero_card_enabled", "hero_image_first", "hero_content_width",
"hero_background_image_url", "hero_image_urls", "hero_image_max_height",
"hero_primary_button_enabled", "hero_primary_button_label", "hero_primary_button_url", "hero_primary_button_enabled", "hero_primary_button_label", "hero_primary_button_url",
"hero_secondary_button_enabled", "hero_secondary_button_label", "hero_secondary_button_url", "hero_secondary_button_enabled", "hero_secondary_button_label", "hero_secondary_button_url",
"hero_video_url", "hero_video_button_color", "hero_video_blur_on_hover", "hero_video_url", "hero_video_button_color", "hero_video_blur_on_hover",
@@ -56,8 +57,7 @@ const TABS = [
settings: new Set([ settings: new Set([
"about_enabled", "about_heading_enabled", "about_heading", "about_enabled", "about_heading_enabled", "about_heading",
"about_title", "about_role", "about_body", "about_image_url", "about_title", "about_role", "about_body", "about_image_url",
"about_gradient_start", "about_gradient_mid", "about_gradient_end", "about_card_color", "about_background_image_url",
"about_background_image_url",
"about_bg_dark", "about_bg_light", "about_min_height", "about_border_style" "about_bg_dark", "about_bg_light", "about_min_height", "about_border_style"
]) ])
}, },
@@ -102,6 +102,18 @@ const TABS = [
} }
]; ];
// Dark/light background pairs — light row gets merged into dark row
const BG_PAIRS = [
["hero_bg_dark", "hero_bg_light"],
["hero_card_bg_dark", "hero_card_bg_light"],
["stats_bg_dark", "stats_bg_light"],
["about_bg_dark", "about_bg_light"],
["topics_bg_dark", "topics_bg_light"],
["groups_bg_dark", "groups_bg_light"],
["app_cta_bg_dark", "app_cta_bg_light"],
["footer_bg_dark", "footer_bg_light"],
];
let currentTab = "settings"; let currentTab = "settings";
let filterActive = false; let filterActive = false;
let isActive = false; let isActive = false;
@@ -122,6 +134,8 @@ function applyTabFilter() {
if (!tab) return; if (!tab) return;
container.querySelectorAll(".row.setting[data-setting]").forEach((row) => { container.querySelectorAll(".row.setting[data-setting]").forEach((row) => {
// Keep merged light rows permanently hidden
if (row.classList.contains("cl-merged-hidden")) return;
const name = row.getAttribute("data-setting"); const name = row.getAttribute("data-setting");
row.classList.toggle( row.classList.toggle(
"cl-tab-hidden", "cl-tab-hidden",
@@ -224,6 +238,71 @@ function cleanupTabs() {
filterActive = false; filterActive = false;
} }
/**
* Merge dark/light bg color pairs into a single row.
* Moves the light setting-value into the dark row and hides the light row.
*/
function mergeBgPairs() {
const container = getContainer();
if (!container) return;
BG_PAIRS.forEach(([darkName, lightName]) => {
const darkRow = container.querySelector(`.row.setting[data-setting="${darkName}"]`);
const lightRow = container.querySelector(`.row.setting[data-setting="${lightName}"]`);
if (!darkRow || !lightRow) return;
// Already merged
if (darkRow.querySelector(".cl-merged-value")) return;
const lightValue = lightRow.querySelector(".setting-value");
const lightLabel = lightRow.querySelector(".setting-label");
if (!lightValue) return;
// Rename the dark row label to just show the base name (e.g. "Hero BG" instead of "Hero BG dark")
const darkH3 = darkRow.querySelector(".setting-label h3");
if (darkH3) {
darkH3.textContent = darkH3.textContent.replace(/\s*dark$/i, "").trim();
}
// Create a wrapper that holds both color pickers side by side
const darkValue = darkRow.querySelector(".setting-value");
if (!darkValue) return;
// Wrap existing dark value
const wrapper = document.createElement("div");
wrapper.className = "cl-merged-value";
const darkCol = document.createElement("div");
darkCol.className = "cl-color-col";
const darkLbl = document.createElement("span");
darkLbl.className = "cl-color-col__label";
darkLbl.textContent = "Dark";
darkCol.appendChild(darkLbl);
// Move dark value's children into the column
while (darkValue.firstChild) {
darkCol.appendChild(darkValue.firstChild);
}
const lightCol = document.createElement("div");
lightCol.className = "cl-color-col";
const lightLbl = document.createElement("span");
lightLbl.className = "cl-color-col__label";
lightLbl.textContent = "Light";
lightCol.appendChild(lightLbl);
// Move light value's children into the column
while (lightValue.firstChild) {
lightCol.appendChild(lightValue.firstChild);
}
wrapper.appendChild(darkCol);
wrapper.appendChild(lightCol);
darkValue.appendChild(wrapper);
// Hide the now-empty light row permanently
lightRow.classList.add("cl-merged-hidden");
lightRow.style.display = "none";
});
}
function buildTabsUI() { function buildTabsUI() {
const container = getContainer(); const container = getContainer();
if (!container) return false; if (!container) return false;
@@ -284,7 +363,7 @@ function buildTabsUI() {
}); });
container.classList.add("cl-tabs-active"); container.classList.add("cl-tabs-active");
mergeBgPairs();
applyTabFilter(); applyTabFilter();
return true; return true;
} }
@@ -329,7 +408,7 @@ function buildTabsUI() {
} }
container.classList.add("cl-tabs-active"); container.classList.add("cl-tabs-active");
wrapBgPairs(); mergeBgPairs();
applyTabFilter(); applyTabFilter();
return true; return true;
} }

View File

@@ -82,6 +82,35 @@ html.dark-scheme .cl-admin-tabs .cl-admin-tab:hover {
color: var(--primary, #ddd); color: var(--primary, #ddd);
} }
/* ── Merged dark/light color pairs (two pickers in one row) ── */
.cl-merged-value {
display: flex;
gap: 24px;
}
.cl-color-col {
flex: 1;
min-width: 0;
}
.cl-color-col__label {
display: block;
font-size: var(--font-down-1);
font-weight: 600;
color: var(--primary-medium);
margin-bottom: 4px;
text-transform: uppercase;
letter-spacing: 0.04em;
}
@media (max-width: 767px) {
.cl-merged-value {
flex-direction: column;
gap: 12px;
}
}
/* ── When tabs are active, remove separator borders ── */ /* ── When tabs are active, remove separator borders ── */
.cl-tabs-active .row.setting[data-setting] { .cl-tabs-active .row.setting[data-setting] {

View File

@@ -30,7 +30,7 @@
--cl-radius-sm: 12px; --cl-radius-sm: 12px;
--cl-radius-xs: 8px; --cl-radius-xs: 8px;
--cl-stat-icon-color: #d4a24e; --cl-stat-icon-color: #d4a24e;
--cl-about-gradient: linear-gradient(135deg, #0a0a14, #080812, #0a0a14); --cl-about-card-bg: linear-gradient(135deg, #0a0a14, #080812, #0a0a14);
--cl-app-gradient: linear-gradient(135deg, #d4a24e, #c4922e, #b8862e); --cl-app-gradient: linear-gradient(135deg, #d4a24e, #c4922e, #b8862e);
--cl-blur: blur(12px); --cl-blur: blur(12px);
color-scheme: dark; color-scheme: dark;
@@ -59,7 +59,7 @@
--cl-orb-2: rgba(100, 150, 255, 0.05); --cl-orb-2: rgba(100, 150, 255, 0.05);
--cl-gradient-text: linear-gradient(135deg, #c4922e, #a3711d, #c4922e); --cl-gradient-text: linear-gradient(135deg, #c4922e, #a3711d, #c4922e);
--cl-scrolled-nav: rgba(250, 249, 246, 0.85); --cl-scrolled-nav: rgba(250, 249, 246, 0.85);
--cl-about-gradient: linear-gradient(135deg, #fdfcf9, #f9f8f4, #fdfcf9); --cl-about-card-bg: linear-gradient(135deg, #fdfcf9, #f9f8f4, #fdfcf9);
--cl-app-gradient: linear-gradient(135deg, #c4922e, #b3811d, #a3711d); --cl-app-gradient: linear-gradient(135deg, #c4922e, #b3811d, #a3711d);
--cl-blur: blur(16px); --cl-blur: blur(16px);
color-scheme: light; color-scheme: light;
@@ -88,7 +88,7 @@
--cl-orb-1: rgba(212, 162, 78, 0.08); --cl-orb-1: rgba(212, 162, 78, 0.08);
--cl-gradient-text: linear-gradient(135deg, #d4a24e, #b8862e, #d4a24e); --cl-gradient-text: linear-gradient(135deg, #d4a24e, #b8862e, #d4a24e);
--cl-scrolled-nav: rgba(250, 246, 240, 0.95); --cl-scrolled-nav: rgba(250, 246, 240, 0.95);
--cl-about-gradient: linear-gradient(135deg, #fdf6ec, #fef9f0, #fdf6ec); --cl-about-card-bg: linear-gradient(135deg, #fdf6ec, #fef9f0, #fdf6ec);
--cl-app-gradient: linear-gradient(135deg, #d4a24e, #c4922e, #b8862e); --cl-app-gradient: linear-gradient(135deg, #d4a24e, #c4922e, #b8862e);
color-scheme: light; color-scheme: light;
} }
@@ -637,6 +637,18 @@
text-align: left; text-align: left;
} }
@media (min-width: 1024px) {
.cl-hero__content {
flex: 0 0 var(--cl-hero-content-w, 50%);
max-width: var(--cl-hero-content-w, 50%);
}
.cl-hero__image {
flex: 1;
min-width: 0;
}
}
.cl-hero__title { .cl-hero__title {
font-size: clamp(2.5rem, 8vw, 4.5rem); font-size: clamp(2.5rem, 8vw, 4.5rem);
font-weight: 900; font-weight: 900;
@@ -691,9 +703,15 @@
height: auto; height: auto;
border-radius: var(--cl-radius); border-radius: var(--cl-radius);
object-fit: cover; object-fit: cover;
object-position: center;
transition: opacity 0.6s ease; transition: opacity 0.6s ease;
} }
/* ── Hero Image First (swap order) ── */
.cl-hero--image-first .cl-hero__image {
order: -1;
}
/* ── Hero Card Mode ── */ /* ── Hero Card Mode ── */
.cl-hero--card .cl-hero__inner { .cl-hero--card .cl-hero__inner {
background: var(--cl-hero-card-bg, var(--cl-card)); background: var(--cl-hero-card-bg, var(--cl-card));
@@ -1046,7 +1064,7 @@
} }
.cl-about__card { .cl-about__card {
background: var(--cl-about-gradient); background: var(--cl-about-card-bg);
border: 1px solid var(--cl-border); border: 1px solid var(--cl-border);
border-radius: 20px; border-radius: 20px;
overflow: hidden; overflow: hidden;

View File

@@ -29,9 +29,12 @@ en:
navbar_border_style: "Border style at the bottom of the navbar when scrolled." navbar_border_style: "Border style at the bottom of the navbar when scrolled."
# ── 2. Hero Section ── # ── 2. Hero Section ──
hero_title: "━━ ROW 2: HERO ━━ — Large welcome area at the top with headline, subtitle, CTA buttons, and optional imagery. This is the main headline text. The last word is highlighted with your accent color." hero_title: "━━ ROW 2: HERO ━━ — Large welcome area at the top with headline, subtitle, CTA buttons, and optional imagery. This is the main headline text."
hero_accent_word: "Which word in the title gets the accent shimmer animation. 0 = last word (default). 1 = first word, 2 = second word, etc."
hero_subtitle: "Supporting text below the hero headline. Describe your community's purpose or value proposition." hero_subtitle: "Supporting text below the hero headline. Describe your community's purpose or value proposition."
hero_card_enabled: "Display the hero content inside a rounded card container with border and shadow. When off, the hero uses a flat full-width layout." hero_card_enabled: "Display the hero content inside a rounded card container with border and shadow. When off, the hero uses a flat full-width layout."
hero_image_first: "Show the hero image above the text on mobile and to the left on desktop. When off, text appears first (default)."
hero_content_width: "Width of the text column as a percentage (2080). The image column fills the remaining space. Default 50 gives equal columns."
hero_background_image_url: "Full-bleed background image behind the hero section. In card mode, fills the card with a dark overlay. In flat mode, covers the entire section." hero_background_image_url: "Full-bleed background image behind the hero section. In card mode, fills the card with a dark overlay. In flat mode, covers the entire section."
hero_image_urls: "Images displayed on the right side of the hero. Add up to 5 URLs — a random one is shown on each page load." hero_image_urls: "Images displayed on the right side of the hero. Add up to 5 URLs — a random one is shown on each page load."
hero_image_max_height: "Maximum height in pixels for the hero image (1001200)." hero_image_max_height: "Maximum height in pixels for the hero image (1001200)."
@@ -44,12 +47,12 @@ en:
hero_video_url: "URL for a hero video. Supports MP4 and YouTube links. A play button appears in the hero area; clicking opens a lightbox modal with the video." hero_video_url: "URL for a hero video. Supports MP4 and YouTube links. A play button appears in the hero area; clicking opens a lightbox modal with the video."
hero_video_button_color: "Custom background color for the hero video play button. Leave blank to use the accent color." hero_video_button_color: "Custom background color for the hero video play button. Leave blank to use the accent color."
hero_video_blur_on_hover: "Apply a blur effect to the hero image when hovering the play button." hero_video_blur_on_hover: "Apply a blur effect to the hero image when hovering the play button."
hero_bg_dark: "Background color for the hero section in dark mode. Hex value. Leave blank for default." hero_bg_dark: "Section background color override. Dark (left) and light (right) color pickers. Leave blank for default."
hero_bg_light: "Background color for the hero section in light mode. Hex value. Leave blank for default." hero_bg_light: "Light mode background for the hero section."
hero_min_height: "Minimum height for the hero section in pixels. Set to 0 for auto height." hero_min_height: "Minimum height for the hero section in pixels. Set to 0 for auto height."
hero_border_style: "Border style at the bottom of the hero section." hero_border_style: "Border style at the bottom of the hero section."
hero_card_bg_dark: "Background color for the hero card overlay in dark mode. Only applies when hero card mode is enabled. Leave blank for default glass effect." hero_card_bg_dark: "Hero card overlay background. Dark (left) and light (right) color pickers. Only applies in card mode. Leave blank for default glass effect."
hero_card_bg_light: "Background color for the hero card overlay in light mode. Only applies when hero card mode is enabled. Leave blank for default glass effect." hero_card_bg_light: "Light mode background for the hero card overlay."
hero_card_opacity: "Opacity of the hero card background (0 to 1, default 0.85). Lower values make the card more transparent, showing the background image through." hero_card_opacity: "Opacity of the hero card background (0 to 1, default 0.85). Lower values make the card more transparent, showing the background image through."
# ── 3. Stats Section ── # ── 3. Stats Section ──
@@ -68,25 +71,23 @@ en:
stat_likes_label: "Custom label for the Likes stat card." stat_likes_label: "Custom label for the Likes stat card."
stat_chats_label: "Custom label for the Chats stat card. Shows total chat messages if the Chat plugin is active." stat_chats_label: "Custom label for the Chats stat card. Shows total chat messages if the Chat plugin is active."
stat_round_numbers: "Round large numbers for a cleaner display: 1000 becomes 1K, 12345 becomes 12.3K, 1234567 becomes 1.2M." stat_round_numbers: "Round large numbers for a cleaner display: 1000 becomes 1K, 12345 becomes 12.3K, 1234567 becomes 1.2M."
stats_bg_dark: "Background color for the stats section in dark mode. Leave blank for default." stats_bg_dark: "Section background color override. Dark (left) and light (right) color pickers. Leave blank for default."
stats_bg_light: "Background color for the stats section in light mode. Leave blank for default." stats_bg_light: "Light mode background for the stats section."
stats_min_height: "Minimum height for the stats section in pixels. Set to 0 for auto height." stats_min_height: "Minimum height for the stats section in pixels. Set to 0 for auto height."
stats_border_style: "Border style at the bottom of the stats section." stats_border_style: "Border style at the bottom of the stats section."
# ── 4. About Section ── # ── 4. About Section ──
about_enabled: "━━ ROW 4: ABOUT ━━ — Show the About section: a gradient card with bold heading, decorative quote icon, community description, and author attribution (avatar, name, role). Supports a 3-color gradient background and optional overlay image." about_enabled: "━━ ROW 4: ABOUT ━━ — Show the About section: a card with bold heading, decorative quote icon, community description, and author attribution (avatar, name, role)."
about_heading_enabled: "Show the bold heading text at the top of the About card. Turn off to start with the quote icon and description." about_heading_enabled: "Show the bold heading text at the top of the About card. Turn off to start with the quote icon and description."
about_heading: "The heading text at the top of the About card (e.g. 'About Community', 'Our Story')." about_heading: "The heading text at the top of the About card (e.g. 'About Community', 'Our Story')."
about_title: "Author or community name shown in the card's bottom attribution, next to the avatar." about_title: "Author or community name shown in the card's bottom attribution, next to the avatar."
about_role: "Subtitle below the author name (e.g. 'Community Manager'). If blank, the site name is used." about_role: "Subtitle below the author name (e.g. 'Community Manager'). If blank, the site name is used."
about_body: "Main body text for the About card. Supports basic HTML: p, a, strong, em, ul, li, br." about_body: "Main body text for the About card. Supports basic HTML: p, a, strong, em, ul, li, br."
about_image_url: "Small avatar image shown next to the author name. Square images work best." about_image_url: "Small avatar image shown next to the author name. Square images work best."
about_gradient_start: "First color (left) of the About card's 3-color gradient. Hex value." about_card_color: "Background color for the About card. Leave blank for the default theme color."
about_gradient_mid: "Middle color of the About card gradient. Hex value."
about_gradient_end: "Third color (right) of the About card gradient. Hex value."
about_background_image_url: "Background image layered on top of the gradient. Use a subtle pattern or texture." about_background_image_url: "Background image layered on top of the gradient. Use a subtle pattern or texture."
about_bg_dark: "Background color for the about section wrapper in dark mode. Leave blank for default." about_bg_dark: "Section background color override. Dark (left) and light (right) color pickers. Leave blank for default."
about_bg_light: "Background color for the about section wrapper in light mode. Leave blank for default." about_bg_light: "Light mode background for the about section."
about_min_height: "Minimum height for the about section in pixels. Set to 0 for auto height." about_min_height: "Minimum height for the about section in pixels. Set to 0 for auto height."
about_border_style: "Border style at the bottom of the about section." about_border_style: "Border style at the bottom of the about section."
@@ -96,8 +97,8 @@ en:
topics_title: "Heading text above the scrollable topic cards." topics_title: "Heading text above the scrollable topic cards."
topics_count: "Number of trending topic cards to display." topics_count: "Number of trending topic cards to display."
topics_card_bg_color: "Background color for each trending topic card. Leave blank for default card styling." topics_card_bg_color: "Background color for each trending topic card. Leave blank for default card styling."
topics_bg_dark: "Background color for the trending section in dark mode. Leave blank for default." topics_bg_dark: "Section background color override. Dark (left) and light (right) color pickers. Leave blank for default."
topics_bg_light: "Background color for the trending section in light mode. Leave blank for default." topics_bg_light: "Light mode background for the trending section."
topics_min_height: "Minimum height for the trending section in pixels. Set to 0 for auto height." topics_min_height: "Minimum height for the trending section in pixels. Set to 0 for auto height."
topics_border_style: "Border style at the bottom of the trending section." topics_border_style: "Border style at the bottom of the trending section."
@@ -120,8 +121,8 @@ en:
groups_count: "Number of group cards to display." groups_count: "Number of group cards to display."
groups_selected: "Show only specific groups. Enter group names separated by pipes (e.g. designers|developers|artists). Leave blank to auto-select public groups." groups_selected: "Show only specific groups. Enter group names separated by pipes (e.g. designers|developers|artists). Leave blank to auto-select public groups."
groups_card_bg_color: "Background color for each space card. Leave blank for default card styling." groups_card_bg_color: "Background color for each space card. Leave blank for default card styling."
groups_bg_dark: "Background color for the spaces section in dark mode. Leave blank for default." groups_bg_dark: "Section background color override. Dark (left) and light (right) color pickers. Leave blank for default."
groups_bg_light: "Background color for the spaces section in light mode. Leave blank for default." groups_bg_light: "Light mode background for the spaces section."
groups_min_height: "Minimum height for the spaces section in pixels. Set to 0 for auto height." groups_min_height: "Minimum height for the spaces section in pixels. Set to 0 for auto height."
groups_border_style: "Border style at the bottom of the spaces section." groups_border_style: "Border style at the bottom of the spaces section."
@@ -139,8 +140,8 @@ en:
app_cta_gradient_mid: "Middle color of the app CTA gradient. Hex value." app_cta_gradient_mid: "Middle color of the app CTA gradient. Hex value."
app_cta_gradient_end: "Third color (right) of the app CTA gradient. Hex value." app_cta_gradient_end: "Third color (right) of the app CTA gradient. Hex value."
app_cta_image_url: "Promotional image on the right side of the CTA (e.g. phone mockup). PNG for transparent backgrounds." app_cta_image_url: "Promotional image on the right side of the CTA (e.g. phone mockup). PNG for transparent backgrounds."
app_cta_bg_dark: "Background color for the app CTA section in dark mode. Leave blank for default." app_cta_bg_dark: "Section background color override. Dark (left) and light (right) color pickers. Leave blank for default."
app_cta_bg_light: "Background color for the app CTA section in light mode. Leave blank for default." app_cta_bg_light: "Light mode background for the app CTA section."
app_cta_min_height: "Minimum height for the app CTA section in pixels. Set to 0 for auto height." app_cta_min_height: "Minimum height for the app CTA section in pixels. Set to 0 for auto height."
app_cta_border_style: "Border style at the bottom of the app CTA section." app_cta_border_style: "Border style at the bottom of the app CTA section."
@@ -148,6 +149,6 @@ en:
footer_description: "━━ ROW 9: FOOTER ━━ — Bottom of the page with logo, navigation links, copyright, and optional description. This adds a description paragraph above the footer bar." footer_description: "━━ ROW 9: FOOTER ━━ — Bottom of the page with logo, navigation links, copyright, and optional description. This adds a description paragraph above the footer bar."
footer_text: "Optional HTML text inside the footer bar. Supports: p, a, strong, em, ul, li, br." footer_text: "Optional HTML text inside the footer bar. Supports: p, a, strong, em, ul, li, br."
footer_links: 'Footer navigation links as a JSON array. Format: [{"label":"Terms","url":"/tos"},{"label":"Privacy","url":"/privacy"}].' footer_links: 'Footer navigation links as a JSON array. Format: [{"label":"Terms","url":"/tos"},{"label":"Privacy","url":"/privacy"}].'
footer_bg_dark: "Background color for the footer bar in dark mode. Leave blank for default." footer_bg_dark: "Section background color override. Dark (left) and light (right) color pickers. Leave blank for default."
footer_bg_light: "Background color for the footer bar in light mode. Leave blank for default." footer_bg_light: "Light mode background for the footer."
footer_border_style: "Border style at the top of the footer bar." footer_border_style: "Border style at the top of the footer bar."

View File

@@ -110,12 +110,25 @@ plugins:
hero_title: hero_title:
default: "Welcome to Our Creative HeadQuarters" default: "Welcome to Our Creative HeadQuarters"
type: string type: string
hero_accent_word:
default: 0
type: integer
min: 0
max: 50
hero_subtitle: hero_subtitle:
default: "Are you ready to start your creative journey?" default: "Are you ready to start your creative journey?"
type: string type: string
hero_card_enabled: hero_card_enabled:
default: true default: true
type: bool type: bool
hero_image_first:
default: false
type: bool
hero_content_width:
default: 50
type: integer
min: 20
max: 80
hero_background_image_url: hero_background_image_url:
default: "" default: ""
type: string type: string
@@ -283,14 +296,8 @@ plugins:
about_image_url: about_image_url:
default: "" default: ""
type: string type: string
about_gradient_start: about_card_color:
default: "fdf6ec" default: ""
type: color
about_gradient_mid:
default: "fef9f0"
type: color
about_gradient_end:
default: "fdf6ec"
type: color type: color
about_background_image_url: about_background_image_url:
default: "" default: ""

View File

@@ -131,9 +131,11 @@ module CommunityLanding
def render_hero def render_hero
hero_card = @s.hero_card_enabled rescue true hero_card = @s.hero_card_enabled rescue true
hero_img_first = @s.hero_image_first rescue false
hero_bg_img = @s.hero_background_image_url.presence hero_bg_img = @s.hero_background_image_url.presence
hero_border = @s.hero_border_style rescue "none" hero_border = @s.hero_border_style rescue "none"
hero_min_h = @s.hero_min_height rescue 0 hero_min_h = @s.hero_min_height rescue 0
content_w = @s.hero_content_width rescue 50
site_name = @s.title site_name = @s.title
html = +"" html = +""
@@ -142,14 +144,29 @@ module CommunityLanding
hero_style_parts << "background-image: url('#{hero_bg_img}');" if hero_bg_img hero_style_parts << "background-image: url('#{hero_bg_img}');" if hero_bg_img
hero_style_parts << "border-bottom: 1px #{hero_border} var(--cl-border);" if hero_border.present? && hero_border != "none" hero_style_parts << "border-bottom: 1px #{hero_border} var(--cl-border);" if hero_border.present? && hero_border != "none"
hero_style_parts << "min-height: #{hero_min_h}px;" if hero_min_h.to_i > 0 hero_style_parts << "min-height: #{hero_min_h}px;" if hero_min_h.to_i > 0
hero_style_parts << "--cl-hero-content-w: #{content_w.to_i}%;" if content_w.to_i != 50
hero_attr = hero_style_parts.any? ? " style=\"#{hero_style_parts.join(' ')}\"" : "" hero_attr = hero_style_parts.any? ? " style=\"#{hero_style_parts.join(' ')}\"" : ""
html << "<section class=\"cl-hero#{hero_card ? ' cl-hero--card' : ''}\" id=\"cl-hero\"#{hero_attr}>\n" hero_classes = "cl-hero"
hero_classes << " cl-hero--card" if hero_card
hero_classes << " cl-hero--image-first" if hero_img_first
html << "<section class=\"#{hero_classes}\" id=\"cl-hero\"#{hero_attr}>\n"
html << "<div class=\"cl-hero__inner\">\n<div class=\"cl-hero__content\">\n" html << "<div class=\"cl-hero__inner\">\n<div class=\"cl-hero__content\">\n"
# Accent word: 0 = last word (default), N = Nth word (1-indexed)
title_words = @s.hero_title.to_s.split(" ") title_words = @s.hero_title.to_s.split(" ")
accent_idx = (@s.hero_accent_word rescue 0).to_i
if title_words.length > 1 if title_words.length > 1
html << "<h1 class=\"cl-hero__title\">#{e(title_words[0..-2].join(' '))} <span class=\"cl-hero__title-accent\">#{e(title_words.last)}</span></h1>\n" # Convert to 0-based index; 0 means last word
target = accent_idx > 0 ? [accent_idx - 1, title_words.length - 1].min : title_words.length - 1
before = title_words[0...target]
accent = title_words[target]
after = title_words[(target + 1)..]
parts = +""
parts << "#{e(before.join(' '))} " if before.any?
parts << "<span class=\"cl-hero__title-accent\">#{e(accent)}</span>"
parts << " #{e(after.join(' '))}" if after.any?
html << "<h1 class=\"cl-hero__title\">#{parts}</h1>\n"
else else
html << "<h1 class=\"cl-hero__title\"><span class=\"cl-hero__title-accent\">#{e(@s.hero_title)}</span></h1>\n" html << "<h1 class=\"cl-hero__title\"><span class=\"cl-hero__title-accent\">#{e(@s.hero_title)}</span></h1>\n"
end end

View File

@@ -15,9 +15,7 @@ module CommunityLanding
dark_bg = hex(@s.dark_bg_color) || "#06060f" dark_bg = hex(@s.dark_bg_color) || "#06060f"
light_bg = hex(@s.light_bg_color) || "#faf6f0" light_bg = hex(@s.light_bg_color) || "#faf6f0"
stat_icon = hex(@s.stat_icon_color) || accent stat_icon = hex(@s.stat_icon_color) || accent
about_g1 = hex(@s.about_gradient_start) || "#fdf6ec" about_card = hex(@s.about_card_color.presence) rescue nil
about_g2 = hex(@s.about_gradient_mid) || "#fef9f0"
about_g3 = hex(@s.about_gradient_end) || "#fdf6ec"
about_bg_img = @s.about_background_image_url.presence about_bg_img = @s.about_background_image_url.presence
app_g1 = hex(@s.app_cta_gradient_start) || accent app_g1 = hex(@s.app_cta_gradient_start) || accent
app_g2 = hex(@s.app_cta_gradient_mid) || accent_hover app_g2 = hex(@s.app_cta_gradient_mid) || accent_hover
@@ -45,7 +43,8 @@ module CommunityLanding
hero_card_dark_val = "rgba(#{hero_card_dark_rgb}, #{hero_card_opacity})" hero_card_dark_val = "rgba(#{hero_card_dark_rgb}, #{hero_card_opacity})"
hero_card_light_val = "rgba(#{hero_card_light_rgb}, #{hero_card_opacity})" hero_card_light_val = "rgba(#{hero_card_light_rgb}, #{hero_card_opacity})"
about_bg_extra = about_bg_img ? ", url('#{about_bg_img}') center/cover no-repeat" : "" about_card_val = about_card || "var(--cl-card)"
about_card_css = about_bg_img ? "#{about_card_val}, url('#{about_bg_img}') center/cover no-repeat" : about_card_val
video_btn_line = video_btn_bg ? "\n --cl-video-btn-bg: #{video_btn_bg};" : "" video_btn_line = video_btn_bg ? "\n --cl-video-btn-bg: #{video_btn_bg};" : ""
"<style> "<style>
@@ -65,7 +64,7 @@ module CommunityLanding
--cl-space-card-bg: #{space_card_bg_val}; --cl-space-card-bg: #{space_card_bg_val};
--cl-topic-card-bg: #{topic_card_bg_val};#{video_btn_line} --cl-topic-card-bg: #{topic_card_bg_val};#{video_btn_line}
--cl-hero-card-bg: #{hero_card_dark_val}; --cl-hero-card-bg: #{hero_card_dark_val};
--cl-about-gradient: linear-gradient(135deg, #{about_g1}, #{about_g2}, #{about_g3})#{about_bg_extra}; --cl-about-card-bg: #{about_card_css};
--cl-app-gradient: linear-gradient(135deg, #{app_g1}, #{app_g2}, #{app_g3}); --cl-app-gradient: linear-gradient(135deg, #{app_g1}, #{app_g2}, #{app_g3});
} }
[data-theme=\"light\"] { [data-theme=\"light\"] {
@@ -84,7 +83,7 @@ module CommunityLanding
--cl-space-card-bg: #{space_card_bg_val}; --cl-space-card-bg: #{space_card_bg_val};
--cl-topic-card-bg: #{topic_card_bg_val};#{video_btn_line} --cl-topic-card-bg: #{topic_card_bg_val};#{video_btn_line}
--cl-hero-card-bg: #{hero_card_light_val}; --cl-hero-card-bg: #{hero_card_light_val};
--cl-about-gradient: linear-gradient(135deg, #{about_g1}, #{about_g2}, #{about_g3})#{about_bg_extra}; --cl-about-card-bg: #{about_card_css};
--cl-app-gradient: linear-gradient(135deg, #{app_g1}, #{app_g2}, #{app_g3}); --cl-app-gradient: linear-gradient(135deg, #{app_g1}, #{app_g2}, #{app_g3});
} }
@media (prefers-color-scheme: light) { @media (prefers-color-scheme: light) {
@@ -99,7 +98,7 @@ module CommunityLanding
--cl-border-hover: rgba(#{accent_rgb}, 0.3); --cl-border-hover: rgba(#{accent_rgb}, 0.3);
--cl-orb-1: rgba(#{accent_rgb}, 0.08); --cl-orb-1: rgba(#{accent_rgb}, 0.08);
--cl-stat-icon-color: #{stat_icon}; --cl-stat-icon-color: #{stat_icon};
--cl-about-gradient: linear-gradient(135deg, #{about_g1}, #{about_g2}, #{about_g3})#{about_bg_extra}; --cl-about-card-bg: #{about_card_css};
--cl-app-gradient: linear-gradient(135deg, #{app_g1}, #{app_g2}, #{app_g3}); --cl-app-gradient: linear-gradient(135deg, #{app_g1}, #{app_g2}, #{app_g3});
} }
} }