@xenterprises/nuxt-x-marketing 1.15.2 → 1.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/app/components/X/Mark/Hero/index.vue +55 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
30
30
|
section and its sample product data were dropped with them. Every other section of the
|
|
31
31
|
demo page is unchanged.
|
|
32
32
|
|
|
33
|
+
## [1.15.4] - 2026-10-21
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- **`XMarkHero` subtitle centring with `align="center"`.** The subtitle's `max-w-2xl` box sat at
|
|
38
|
+
the left of the `max-w-3xl` text column, so a centred subtitle was 48px left of centre at
|
|
39
|
+
1024px and up (24px at 768px). The subtitle now gets `mx-auto` when `align="center"` (prop or
|
|
40
|
+
`#subtitle` slot), so its box and text are centred on the column. Title and CTA were already
|
|
41
|
+
centred and are unchanged. `align="left"` (default) and `align="right"`: body HTML identical to
|
|
42
|
+
1.15.3 and 0 px difference at 1440x900, 1024x768, 768x1024, 390x844 and 375x667. Centred heroes
|
|
43
|
+
below about 720px wide are also 0 px (the box already fills the column).
|
|
44
|
+
|
|
45
|
+
## [1.15.3] - 2026-10-20
|
|
46
|
+
|
|
47
|
+
### Added (opt-in)
|
|
48
|
+
|
|
49
|
+
- **`XMarkHero` `constrainToScrim`** (boolean, kebab `constrain-to-scrim`). With
|
|
50
|
+
`overlay="scrim-left"` and `align="left"`, at md and up the text column is capped so it stays
|
|
51
|
+
inside the 90% scrim zone: max width = effective scrim width (`scrimWidth`, or 55% when unset)
|
|
52
|
+
minus the container's left offset and a 2rem inner gap, never wider than the default
|
|
53
|
+
`max-w-3xl` and never narrower than 14rem. A `%` scrimWidth resolves against the hero width
|
|
54
|
+
(the section becomes an inline-size container at md+ only). Below md nothing changes,
|
|
55
|
+
including `scrimMobile="bottom"`. Lets a 50 to 55% scrim pass 4.5:1 at 768 to 1024px without
|
|
56
|
+
burying the photo. Unset: body HTML identical to 1.15.2 and 0 px difference at 1440, 1024,
|
|
57
|
+
768 and 390.
|
|
58
|
+
|
|
33
59
|
## [1.15.2] - 2026-10-19
|
|
34
60
|
|
|
35
61
|
### Fixed
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
heightClass,
|
|
6
6
|
alignmentClasses,
|
|
7
7
|
verticalAlignClasses,
|
|
8
|
-
{ 'pt-20': includeNavPadding },
|
|
8
|
+
{ 'pt-20': includeNavPadding, 'x-hero-cts': constrain },
|
|
9
9
|
]"
|
|
10
10
|
>
|
|
11
11
|
<!-- Background -->
|
|
@@ -81,7 +81,11 @@
|
|
|
81
81
|
|
|
82
82
|
<!-- Content -->
|
|
83
83
|
<div class="relative z-10 w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
84
|
-
<div
|
|
84
|
+
<div
|
|
85
|
+
class="max-w-3xl pb-6 md:pb-8"
|
|
86
|
+
:class="[contentAlignmentClasses, { 'x-hero-cts-col': constrain }]"
|
|
87
|
+
v-bind="constrain ? { style: constrainStyle } : {}"
|
|
88
|
+
>
|
|
85
89
|
<!-- Eyebrow -->
|
|
86
90
|
<p v-if="eyebrow" class="xText-eyebrow text-white/70 mb-4">
|
|
87
91
|
{{ eyebrow }}
|
|
@@ -98,6 +102,7 @@
|
|
|
98
102
|
<p
|
|
99
103
|
v-if="subtitle || $slots.subtitle"
|
|
100
104
|
class="mt-6 text-xl text-white/80 max-w-2xl"
|
|
105
|
+
:class="{ 'mx-auto': align === 'center' }"
|
|
101
106
|
>
|
|
102
107
|
<slot name="subtitle">{{ subtitle }}</slot>
|
|
103
108
|
</p>
|
|
@@ -260,6 +265,18 @@ const props = defineProps({
|
|
|
260
265
|
default: "",
|
|
261
266
|
validator: (v) => ["", "bottom"].includes(v),
|
|
262
267
|
},
|
|
268
|
+
/**
|
|
269
|
+
* scrim-left only, opt-in (1.15.3). At md and up, caps the text column so its right
|
|
270
|
+
* edge stays inside the 90% scrim zone: max width = effective scrim width (scrimWidth,
|
|
271
|
+
* or 55% when unset) minus the container's left offset and a 2rem inner gap, never
|
|
272
|
+
* wider than the default max-w-3xl and never narrower than 14rem. Left-aligned
|
|
273
|
+
* content only (center/right alignment is unaffected). Below md nothing changes,
|
|
274
|
+
* including scrimMobile="bottom". Unset (default): output identical to 1.15.2.
|
|
275
|
+
*/
|
|
276
|
+
constrainToScrim: {
|
|
277
|
+
type: Boolean,
|
|
278
|
+
default: false,
|
|
279
|
+
},
|
|
263
280
|
/** Add top padding for non-transparent nav */
|
|
264
281
|
includeNavPadding: {
|
|
265
282
|
type: Boolean,
|
|
@@ -293,6 +310,19 @@ const mobileBottom = computed(
|
|
|
293
310
|
|
|
294
311
|
const softScrim = computed(() => props.overlay === "scrim-left" && !!props.scrimWidth);
|
|
295
312
|
|
|
313
|
+
// constrainToScrim (1.15.3): only meaningful for left-aligned content over scrim-left.
|
|
314
|
+
const constrain = computed(
|
|
315
|
+
() => props.constrainToScrim && props.overlay === "scrim-left" && props.align === "left",
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
// Effective scrim width in units that resolve against the hero section (a size container
|
|
319
|
+
// at md+ when constrained): N% of the section becomes Ncqw; other lengths pass through.
|
|
320
|
+
const constrainStyle = computed(() => {
|
|
321
|
+
if (!constrain.value) return undefined;
|
|
322
|
+
const w = props.scrimWidth || "55%";
|
|
323
|
+
return { "--x-cts-w": w.endsWith("%") ? `${parseFloat(w)}cqw` : w };
|
|
324
|
+
});
|
|
325
|
+
|
|
296
326
|
const heightClass = computed(() => {
|
|
297
327
|
const heights = {
|
|
298
328
|
full: "min-h-[calc(100svh-var(--ui-header-height))]",
|
|
@@ -370,6 +400,29 @@ const contentAlignmentClasses = computed(() => {
|
|
|
370
400
|
);
|
|
371
401
|
}
|
|
372
402
|
}
|
|
403
|
+
/* constrainToScrim (1.15.3), md+ only: the section is an inline-size container so the
|
|
404
|
+
* text column can be capped against the section width. Column left edge = container
|
|
405
|
+
* offset (max(0, (100cqw - 80rem) / 2)) + container padding (md 1.5rem, lg 2rem). */
|
|
406
|
+
@media (min-width: 768px) {
|
|
407
|
+
.x-hero-cts {
|
|
408
|
+
container-type: inline-size;
|
|
409
|
+
}
|
|
410
|
+
.x-hero-cts-col {
|
|
411
|
+
--x-cts-pad: 1.5rem;
|
|
412
|
+
max-width: min(
|
|
413
|
+
48rem,
|
|
414
|
+
max(
|
|
415
|
+
14rem,
|
|
416
|
+
calc(var(--x-cts-w, 55cqw) - max(0px, (100cqw - 80rem) / 2) - var(--x-cts-pad) - 2rem)
|
|
417
|
+
)
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
@media (min-width: 1024px) {
|
|
422
|
+
.x-hero-cts-col {
|
|
423
|
+
--x-cts-pad: 2rem;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
373
426
|
/* md+: 90% up to --x-scrim-w, then a long eased fade to clear. */
|
|
374
427
|
@media (min-width: 768px) {
|
|
375
428
|
.x-hero-scrim-w {
|