@xenterprises/nuxt-x-marketing 1.15.2 → 1.15.3

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 CHANGED
@@ -30,6 +30,20 @@ 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.3] - 2026-10-20
34
+
35
+ ### Added (opt-in)
36
+
37
+ - **`XMarkHero` `constrainToScrim`** (boolean, kebab `constrain-to-scrim`). With
38
+ `overlay="scrim-left"` and `align="left"`, at md and up the text column is capped so it stays
39
+ inside the 90% scrim zone: max width = effective scrim width (`scrimWidth`, or 55% when unset)
40
+ minus the container's left offset and a 2rem inner gap, never wider than the default
41
+ `max-w-3xl` and never narrower than 14rem. A `%` scrimWidth resolves against the hero width
42
+ (the section becomes an inline-size container at md+ only). Below md nothing changes,
43
+ including `scrimMobile="bottom"`. Lets a 50 to 55% scrim pass 4.5:1 at 768 to 1024px without
44
+ burying the photo. Unset: body HTML identical to 1.15.2 and 0 px difference at 1440, 1024,
45
+ 768 and 390.
46
+
33
47
  ## [1.15.2] - 2026-10-19
34
48
 
35
49
  ### 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 class="max-w-3xl pb-6 md:pb-8" :class="contentAlignmentClasses">
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 }}
@@ -260,6 +264,18 @@ const props = defineProps({
260
264
  default: "",
261
265
  validator: (v) => ["", "bottom"].includes(v),
262
266
  },
267
+ /**
268
+ * scrim-left only, opt-in (1.15.3). At md and up, caps the text column so its right
269
+ * edge stays inside the 90% scrim zone: max width = effective scrim width (scrimWidth,
270
+ * or 55% when unset) minus the container's left offset and a 2rem inner gap, never
271
+ * wider than the default max-w-3xl and never narrower than 14rem. Left-aligned
272
+ * content only (center/right alignment is unaffected). Below md nothing changes,
273
+ * including scrimMobile="bottom". Unset (default): output identical to 1.15.2.
274
+ */
275
+ constrainToScrim: {
276
+ type: Boolean,
277
+ default: false,
278
+ },
263
279
  /** Add top padding for non-transparent nav */
264
280
  includeNavPadding: {
265
281
  type: Boolean,
@@ -293,6 +309,19 @@ const mobileBottom = computed(
293
309
 
294
310
  const softScrim = computed(() => props.overlay === "scrim-left" && !!props.scrimWidth);
295
311
 
312
+ // constrainToScrim (1.15.3): only meaningful for left-aligned content over scrim-left.
313
+ const constrain = computed(
314
+ () => props.constrainToScrim && props.overlay === "scrim-left" && props.align === "left",
315
+ );
316
+
317
+ // Effective scrim width in units that resolve against the hero section (a size container
318
+ // at md+ when constrained): N% of the section becomes Ncqw; other lengths pass through.
319
+ const constrainStyle = computed(() => {
320
+ if (!constrain.value) return undefined;
321
+ const w = props.scrimWidth || "55%";
322
+ return { "--x-cts-w": w.endsWith("%") ? `${parseFloat(w)}cqw` : w };
323
+ });
324
+
296
325
  const heightClass = computed(() => {
297
326
  const heights = {
298
327
  full: "min-h-[calc(100svh-var(--ui-header-height))]",
@@ -370,6 +399,29 @@ const contentAlignmentClasses = computed(() => {
370
399
  );
371
400
  }
372
401
  }
402
+ /* constrainToScrim (1.15.3), md+ only: the section is an inline-size container so the
403
+ * text column can be capped against the section width. Column left edge = container
404
+ * offset (max(0, (100cqw - 80rem) / 2)) + container padding (md 1.5rem, lg 2rem). */
405
+ @media (min-width: 768px) {
406
+ .x-hero-cts {
407
+ container-type: inline-size;
408
+ }
409
+ .x-hero-cts-col {
410
+ --x-cts-pad: 1.5rem;
411
+ max-width: min(
412
+ 48rem,
413
+ max(
414
+ 14rem,
415
+ calc(var(--x-cts-w, 55cqw) - max(0px, (100cqw - 80rem) / 2) - var(--x-cts-pad) - 2rem)
416
+ )
417
+ );
418
+ }
419
+ }
420
+ @media (min-width: 1024px) {
421
+ .x-hero-cts-col {
422
+ --x-cts-pad: 2rem;
423
+ }
424
+ }
373
425
  /* md+: 90% up to --x-scrim-w, then a long eased fade to clear. */
374
426
  @media (min-width: 768px) {
375
427
  .x-hero-scrim-w {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@xenterprises/nuxt-x-marketing",
3
3
  "license": "SEE LICENSE IN LICENSE",
4
4
  "type": "module",
5
- "version": "1.15.2",
5
+ "version": "1.15.3",
6
6
  "main": "./nuxt.config.ts",
7
7
  "scripts": {
8
8
  "dev": "nuxi dev .playground",