cinqcinqdev-seo 0.1.44 → 0.1.45

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.
@@ -1,11 +1,11 @@
1
1
  <template>
2
- <section :class="[sectionPad]" :style="{ backgroundColor: bgColor, color: textColor }">
3
- <div class="max-w-6xl mx-auto">
2
+ <section :class="[sectionPad]" :dir="textDirection" :style="{ backgroundColor: bgColor, color: textColor }">
3
+ <div :class="[containerClass]">
4
4
 
5
5
  <div v-if="title || description" class="mb-12" :class="['horizontal','cards'].includes(layout) ? 'text-center max-w-2xl mx-auto' : 'max-w-xl'">
6
6
  <span v-if="badge" class="inline-block text-[10px] font-bold tracking-[0.5em] uppercase px-3 py-1 rounded-full border mb-4" :style="{ borderColor: ca(textColor, '25'), color: ca(textColor, 'aa') }">{{ badge }}</span>
7
- <component :is="titleTag" class="text-3xl md:text-5xl font-black uppercase tracking-tighter leading-[0.9] mb-4">{{ title }}</component>
8
- <p v-if="description" class="text-sm leading-relaxed" :style="{ opacity: 0.55 }">{{ description }}</p>
7
+ <component :is="titleTag" class="font-black uppercase tracking-tighter leading-[0.9] mb-4" :style="{ fontSize: titleFontSize }">{{ title }}</component>
8
+ <p v-if="description" :class="[bodyClass, 'leading-relaxed']" :style="{ opacity: 0.55 }">{{ description }}</p>
9
9
  </div>
10
10
 
11
11
  <!-- STEPS (vertical) -->
@@ -92,8 +92,14 @@ const props = defineProps({
92
92
  bgColor: { type: String, default: "rgba(var(--body-bg), 1)" },
93
93
  textColor: { type: String, default: "rgba(var(--text-color), 1)" },
94
94
  spacing: { type: String, default: "normal" },
95
- radius: { type: String, default: "rounded" }
95
+ radius: { type: String, default: "rounded" },
96
+ textDirection: { type: String, default: "ltr" },
97
+ contentWidth: { type: String, default: "normal" },
98
+ textSize: { type: String, default: "md" }
96
99
  });
97
100
  const sectionPad = computed(() => ({ compact: "py-8 px-4 md:px-8", normal: "py-14 px-6 md:px-12", spacious: "py-24 px-8 md:px-16" })[props.spacing] || "py-14 px-6 md:px-12");
98
101
  const cardRound = computed(() => ({ sharp: "rounded-xl", rounded: "rounded-3xl", pill: "rounded-[40px]" })[props.radius] || "rounded-3xl");
102
+ const containerClass = computed(() => ({ narrow: "max-w-3xl mx-auto", normal: "max-w-6xl mx-auto", wide: "max-w-7xl mx-auto", full: "max-w-full" })[props.contentWidth] || "max-w-6xl mx-auto");
103
+ const titleFontSize = computed(() => ({ sm: "clamp(1.5rem,3vw,2.5rem)", md: "clamp(2rem,4vw,3.5rem)", lg: "clamp(2.5rem,6vw,5rem)" })[props.textSize] || "clamp(2rem,4vw,3.5rem)");
104
+ const bodyClass = computed(() => ({ sm: "text-xs", md: "text-sm", lg: "text-base" })[props.textSize] || "text-sm");
99
105
  </script>
@@ -1,10 +1,10 @@
1
1
  <template>
2
- <section :class="[sectionPad]" :style="{ backgroundColor: bgColor, color: textColor }">
2
+ <section :class="[sectionPad]" :dir="textDirection" :style="{ backgroundColor: bgColor, color: textColor }">
3
3
 
4
4
  <!-- CENTERED -->
5
- <div v-if="layout === 'centered'" class="max-w-3xl mx-auto text-center">
5
+ <div v-if="layout === 'centered'" :class="[containerClass, 'text-center']">
6
6
  <div class="text-6xl font-black mb-6 leading-none" :style="{ opacity: 0.15 }">"</div>
7
- <blockquote class="font-black uppercase tracking-tighter leading-[0.92] mb-8" :style="{ fontSize: 'clamp(1.6rem,4vw,3rem)' }">{{ quote }}</blockquote>
7
+ <blockquote class="font-black uppercase tracking-tighter leading-[0.92] mb-8" :style="{ fontSize: quoteFontSize }">{{ quote }}</blockquote>
8
8
  <div class="flex items-center justify-center gap-3">
9
9
  <img v-if="avatar" :src="avatar" class="w-10 h-10 rounded-full object-cover" />
10
10
  <div v-else-if="author" class="w-10 h-10 rounded-full flex items-center justify-center text-xs font-black" :style="{ backgroundColor: ca(textColor, '15') }">{{ author[0] }}</div>
@@ -16,10 +16,10 @@
16
16
  </div>
17
17
 
18
18
  <!-- LEFT -->
19
- <div v-else-if="layout === 'left'" class="max-w-3xl mx-auto flex gap-8 items-start">
19
+ <div v-else-if="layout === 'left'" :class="[containerClass, 'flex gap-8 items-start']">
20
20
  <div class="text-8xl font-black leading-none shrink-0 mt-2" :style="{ opacity: 0.12 }">"</div>
21
21
  <div>
22
- <blockquote class="font-black uppercase tracking-tight leading-[0.92] mb-7" :style="{ fontSize: 'clamp(1.3rem,3vw,2.5rem)' }">{{ quote }}</blockquote>
22
+ <blockquote class="font-black uppercase tracking-tight leading-[0.92] mb-7" :style="{ fontSize: quoteFontSize }">{{ quote }}</blockquote>
23
23
  <div class="flex items-center gap-3">
24
24
  <img v-if="avatar" :src="avatar" class="w-9 h-9 rounded-full object-cover" />
25
25
  <div v-else-if="author" class="w-9 h-9 rounded-full flex items-center justify-center text-xs font-black" :style="{ backgroundColor: ca(textColor, '15') }">{{ author[0] }}</div>
@@ -32,9 +32,9 @@
32
32
  </div>
33
33
 
34
34
  <!-- LARGE (full width statement) -->
35
- <div v-else class="max-w-5xl mx-auto">
35
+ <div v-else :class="[containerClass]">
36
36
  <div class="border-t border-b py-12 md:py-16" :style="{ borderColor: ca(textColor, '20') }">
37
- <blockquote class="font-black uppercase tracking-tighter leading-[0.88] mb-10" :style="{ fontSize: 'clamp(2rem,7vw,6rem)' }">{{ quote }}</blockquote>
37
+ <blockquote class="font-black uppercase tracking-tighter leading-[0.88] mb-10" :style="{ fontSize: quoteFontSize }">{{ quote }}</blockquote>
38
38
  <div class="flex items-center gap-4">
39
39
  <div class="w-12 h-px" :style="{ backgroundColor: textColor }"></div>
40
40
  <img v-if="avatar" :src="avatar" class="w-8 h-8 rounded-full object-cover" />
@@ -72,7 +72,12 @@ const props = defineProps({
72
72
  bgColor: { type: String, default: "rgba(var(--body-bg), 1)" },
73
73
  textColor: { type: String, default: "rgba(var(--text-color), 1)" },
74
74
  spacing: { type: String, default: "normal" },
75
- radius: { type: String, default: "rounded" }
75
+ radius: { type: String, default: "rounded" },
76
+ textDirection: { type: String, default: "ltr" },
77
+ contentWidth: { type: String, default: "narrow" },
78
+ textSize: { type: String, default: "md" }
76
79
  });
77
80
  const sectionPad = computed(() => ({ compact: "py-8 px-4 md:px-8", normal: "py-14 px-6 md:px-12", spacious: "py-24 px-8 md:px-16" })[props.spacing] || "py-14 px-6 md:px-12");
81
+ const containerClass = computed(() => ({ narrow: "max-w-3xl mx-auto", normal: "max-w-5xl mx-auto", wide: "max-w-7xl mx-auto", full: "max-w-full" })[props.contentWidth] || "max-w-3xl mx-auto");
82
+ const quoteFontSize = computed(() => ({ sm: "clamp(1rem,2.5vw,1.8rem)", md: "clamp(1.6rem,4vw,3rem)", lg: "clamp(2rem,6vw,5rem)" })[props.textSize] || "clamp(1.6rem,4vw,3rem)");
78
83
  </script>
@@ -1,9 +1,9 @@
1
1
  <template>
2
- <section :class="[sectionPad]" :style="{ backgroundColor: bgColor, color: textColor }">
2
+ <section :class="[sectionPad]" :dir="textDirection" :style="{ backgroundColor: bgColor, color: textColor }">
3
3
  <div :class="maxW">
4
4
 
5
5
  <!-- Optional title -->
6
- <component v-if="title" :is="titleTag" class="font-black uppercase tracking-tighter leading-[0.9] mb-10" :style="{ fontSize: 'clamp(1.6rem,4vw,3rem)' }">{{ title }}</component>
6
+ <component v-if="title" :is="titleTag" class="font-black uppercase tracking-tighter leading-[0.9] mb-10" :style="{ fontSize: titleFontSize }">{{ title }}</component>
7
7
 
8
8
  <!-- Divider above content -->
9
9
  <div v-if="title" class="mb-10 h-px w-12" :style="{ backgroundColor: textColor }"></div>
@@ -43,11 +43,18 @@ const props = defineProps({
43
43
  bgColor: { type: String, default: "rgba(var(--body-bg), 1)" },
44
44
  textColor: { type: String, default: "rgba(var(--text-color), 1)" },
45
45
  spacing: { type: String, default: "normal" },
46
- radius: { type: String, default: "rounded" }
46
+ radius: { type: String, default: "rounded" },
47
+ textDirection: { type: String, default: "ltr" },
48
+ contentWidth: { type: String, default: "normal" },
49
+ textSize: { type: String, default: "md" }
47
50
  });
48
51
  const sectionPad = computed(() => ({ compact: "py-8 px-4 md:px-8", normal: "py-14 px-6 md:px-12", spacious: "py-24 px-8 md:px-16" })[props.spacing] || "py-14 px-6 md:px-12");
49
52
  const cardRound = computed(() => ({ sharp: "rounded-lg", rounded: "rounded-xl", pill: "rounded-full" })[props.radius] || "rounded-xl");
50
- const maxW = computed(() => ({ article: "max-w-2xl mx-auto", wide: "max-w-4xl mx-auto", full: "w-full" })[props.layout] || "max-w-2xl mx-auto");
53
+ const titleFontSize = computed(() => ({ sm: "clamp(1rem,2vw,1.5rem)", md: "clamp(1.6rem,4vw,3rem)", lg: "clamp(2rem,5vw,4rem)" })[props.textSize] || "clamp(1.6rem,4vw,3rem)");
54
+ const maxW = computed(() => {
55
+ if (props.contentWidth !== "normal") return { narrow: "max-w-2xl mx-auto", normal: "max-w-4xl mx-auto", wide: "max-w-6xl mx-auto", full: "max-w-full" }[props.contentWidth] || "max-w-4xl mx-auto";
56
+ return { article: "max-w-2xl mx-auto", wide: "max-w-4xl mx-auto", full: "w-full" }[props.layout] || "max-w-2xl mx-auto";
57
+ });
51
58
  const rendered = computed(() => {
52
59
  if (!props.content) return "";
53
60
  if (typeof props.content === "object") return props.content.fr || "";
@@ -1,11 +1,11 @@
1
1
  <template>
2
- <section :class="[sectionPad]" :style="{ backgroundColor: bgColor, color: textColor }">
3
- <div class="max-w-6xl mx-auto">
2
+ <section :class="[sectionPad]" :dir="textDirection" :style="{ backgroundColor: bgColor, color: textColor }">
3
+ <div :class="[containerClass]">
4
4
 
5
5
  <div v-if="title || description" class="mb-12" :class="headerAlign === 'center' ? 'text-center max-w-2xl mx-auto' : 'max-w-xl'">
6
6
  <span v-if="badge" class="inline-block text-[10px] font-bold tracking-[0.5em] uppercase px-3 py-1 rounded-full border mb-4" :style="{ borderColor: ca(textColor, '25'), color: ca(textColor, 'aa') }">{{ badge }}</span>
7
- <component :is="titleTag" class="text-3xl md:text-5xl font-black uppercase tracking-tighter leading-[0.9] mb-4">{{ title }}</component>
8
- <p v-if="description" class="text-sm leading-relaxed mb-6" :style="{ opacity: 0.55 }">{{ description }}</p>
7
+ <component :is="titleTag" class="font-black uppercase tracking-tighter leading-[0.9] mb-4" :style="{ fontSize: titleFontSize }">{{ title }}</component>
8
+ <p v-if="description" :class="[bodyClass, 'leading-relaxed mb-6']" :style="{ opacity: 0.55 }">{{ description }}</p>
9
9
  <div v-if="ctas && ctas.length" class="flex flex-wrap gap-3">
10
10
  <NuxtLink v-for="(cta, i) in ctas" :key="i" :to="cta.link || '#'"
11
11
  class="inline-flex items-center gap-2.5 px-6 py-3 rounded-full text-[11px] font-black uppercase tracking-widest transition-all hover:gap-5"
@@ -94,8 +94,14 @@ const props = defineProps({
94
94
  bgColor: { type: String, default: "rgba(var(--body-bg), 1)" },
95
95
  textColor: { type: String, default: "rgba(var(--text-color), 1)" },
96
96
  spacing: { type: String, default: "normal" },
97
- radius: { type: String, default: "rounded" }
97
+ radius: { type: String, default: "rounded" },
98
+ textDirection: { type: String, default: "ltr" },
99
+ contentWidth: { type: String, default: "normal" },
100
+ textSize: { type: String, default: "md" }
98
101
  });
99
102
  const sectionPad = computed(() => ({ compact: "py-8 px-4 md:px-8", normal: "py-14 px-6 md:px-12", spacious: "py-24 px-8 md:px-16" })[props.spacing] || "py-14 px-6 md:px-12");
100
103
  const cardRound = computed(() => ({ sharp: "rounded-xl", rounded: "rounded-3xl", pill: "rounded-[40px]" })[props.radius] || "rounded-3xl");
104
+ const containerClass = computed(() => ({ narrow: "max-w-3xl mx-auto", normal: "max-w-6xl mx-auto", wide: "max-w-7xl mx-auto", full: "max-w-full" })[props.contentWidth] || "max-w-6xl mx-auto");
105
+ const titleFontSize = computed(() => ({ sm: "clamp(1.5rem,3vw,2.5rem)", md: "clamp(2rem,4vw,3.5rem)", lg: "clamp(2.5rem,6vw,5rem)" })[props.textSize] || "clamp(2rem,4vw,3.5rem)");
106
+ const bodyClass = computed(() => ({ sm: "text-xs", md: "text-sm", lg: "text-base" })[props.textSize] || "text-sm");
101
107
  </script>
@@ -1,11 +1,11 @@
1
1
  <template>
2
- <section :class="[sectionPad]" :style="{ backgroundColor: bgColor, color: textColor }">
3
- <div class="max-w-6xl mx-auto">
2
+ <section :class="[sectionPad]" :dir="textDirection" :style="{ backgroundColor: bgColor, color: textColor }">
3
+ <div :class="[containerClass]">
4
4
 
5
5
  <div v-if="title || description" class="mb-12 max-w-xl">
6
6
  <span v-if="badge" class="inline-block text-[10px] font-bold tracking-[0.5em] uppercase px-3 py-1 rounded-full border mb-4" :style="{ borderColor: ca(textColor, '25'), color: ca(textColor, 'aa') }">{{ badge }}</span>
7
- <component :is="titleTag" class="text-3xl md:text-5xl font-black uppercase tracking-tighter leading-[0.9] mb-3">{{ title }}</component>
8
- <p v-if="description" class="text-sm leading-relaxed" :style="{ opacity: 0.55 }">{{ description }}</p>
7
+ <component :is="titleTag" class="font-black uppercase tracking-tighter leading-[0.9] mb-3" :style="{ fontSize: titleFontSize }">{{ title }}</component>
8
+ <p v-if="description" :class="[bodyClass, 'leading-relaxed']" :style="{ opacity: 0.55 }">{{ description }}</p>
9
9
  </div>
10
10
 
11
11
  <!-- GRID -->
@@ -92,8 +92,14 @@ const props = defineProps({
92
92
  bgColor: { type: String, default: "rgba(var(--body-bg), 1)" },
93
93
  textColor: { type: String, default: "rgba(var(--text-color), 1)" },
94
94
  spacing: { type: String, default: "normal" },
95
- radius: { type: String, default: "rounded" }
95
+ radius: { type: String, default: "rounded" },
96
+ textDirection: { type: String, default: "ltr" },
97
+ contentWidth: { type: String, default: "normal" },
98
+ textSize: { type: String, default: "md" }
96
99
  });
97
100
  const sectionPad = computed(() => ({ compact: "py-8 px-4 md:px-8", normal: "py-14 px-6 md:px-12", spacious: "py-24 px-8 md:px-16" })[props.spacing] || "py-14 px-6 md:px-12");
98
101
  const cardRound = computed(() => ({ sharp: "rounded-xl", rounded: "rounded-3xl", pill: "rounded-[40px]" })[props.radius] || "rounded-3xl");
102
+ const containerClass = computed(() => ({ narrow: "max-w-3xl mx-auto", normal: "max-w-6xl mx-auto", wide: "max-w-7xl mx-auto", full: "max-w-full" })[props.contentWidth] || "max-w-6xl mx-auto");
103
+ const titleFontSize = computed(() => ({ sm: "clamp(1.5rem,3vw,2.5rem)", md: "clamp(2rem,4vw,3.5rem)", lg: "clamp(2.5rem,6vw,5rem)" })[props.textSize] || "clamp(2rem,4vw,3.5rem)");
104
+ const bodyClass = computed(() => ({ sm: "text-xs", md: "text-sm", lg: "text-base" })[props.textSize] || "text-sm");
99
105
  </script>
@@ -1,12 +1,12 @@
1
1
  <template>
2
- <section :class="[sectionPad]" :style="{ backgroundColor: bgColor, color: textColor }">
2
+ <section :class="[sectionPad]" :dir="textDirection" :style="{ backgroundColor: bgColor, color: textColor }">
3
3
 
4
4
  <!-- SPLIT -->
5
- <div v-if="layout === 'split'" :class="['max-w-6xl mx-auto flex flex-col md:flex-row gap-12 items-center', reverse ? 'md:flex-row-reverse' : '']">
5
+ <div v-if="layout === 'split'" :class="[containerClass, 'flex flex-col md:flex-row gap-12 items-center', reverse ? 'md:flex-row-reverse' : '']">
6
6
  <div class="flex-1 space-y-6">
7
7
  <span v-if="badge" class="inline-block text-[10px] font-bold tracking-[0.5em] uppercase px-3 py-1 rounded-full border" :style="{ borderColor: ca(textColor, '25'), color: ca(textColor, 'aa') }">{{ badge }}</span>
8
- <component :is="titleTag" class="text-3xl md:text-4xl font-black uppercase tracking-tighter leading-[0.9]">{{ title }}</component>
9
- <p class="leading-relaxed text-sm max-w-md" :style="{ opacity: 0.55 }">{{ content }}</p>
8
+ <component :is="titleTag" class="font-black uppercase tracking-tighter leading-[0.9]" :style="{ fontSize: titleFontSize }">{{ title }}</component>
9
+ <p :class="[bodyClass, 'leading-relaxed max-w-md']" :style="{ opacity: 0.55 }">{{ content }}</p>
10
10
  <div v-if="ctas && ctas.length" class="flex flex-wrap gap-3 pt-1">
11
11
  <NuxtLink v-for="(cta, i) in ctas" :key="i" :to="cta.link || '#'"
12
12
  class="inline-flex items-center gap-2.5 px-6 py-3 rounded-full text-[11px] font-black uppercase tracking-widest transition-all hover:gap-5"
@@ -22,15 +22,15 @@
22
22
  </div>
23
23
 
24
24
  <!-- STACKED -->
25
- <div v-else-if="layout === 'stacked'" class="max-w-3xl mx-auto space-y-8">
25
+ <div v-else-if="layout === 'stacked'" :class="[containerClass, 'space-y-8']">
26
26
  <div :class="['w-full overflow-hidden relative', imageContainerClass]">
27
27
  <img v-if="image" :src="image" class="w-full h-full object-cover" />
28
28
  <div v-else class="w-full h-full" :style="{ backgroundColor: ca(textColor, '08') }"></div>
29
29
  </div>
30
30
  <div class="space-y-5">
31
31
  <span v-if="badge" class="inline-block text-[10px] font-bold tracking-[0.5em] uppercase px-3 py-1 rounded-full border" :style="{ borderColor: ca(textColor, '25'), color: ca(textColor, 'aa') }">{{ badge }}</span>
32
- <component :is="titleTag" class="text-3xl md:text-4xl font-black uppercase tracking-tighter leading-[0.9]">{{ title }}</component>
33
- <p class="leading-relaxed text-sm" :style="{ opacity: 0.55 }">{{ content }}</p>
32
+ <component :is="titleTag" class="font-black uppercase tracking-tighter leading-[0.9]" :style="{ fontSize: titleFontSize }">{{ title }}</component>
33
+ <p :class="[bodyClass, 'leading-relaxed']" :style="{ opacity: 0.55 }">{{ content }}</p>
34
34
  <div v-if="ctas && ctas.length" class="flex flex-wrap gap-3 pt-1">
35
35
  <NuxtLink v-for="(cta, i) in ctas" :key="i" :to="cta.link || '#'"
36
36
  class="inline-flex items-center gap-2.5 px-6 py-3 rounded-full text-[11px] font-black uppercase tracking-widest transition-all hover:gap-5"
@@ -42,15 +42,15 @@
42
42
  </div>
43
43
 
44
44
  <!-- WIDE -->
45
- <div v-else :class="['max-w-6xl mx-auto flex flex-col md:flex-row gap-10 items-center', reverse ? 'md:flex-row-reverse' : '']">
45
+ <div v-else :class="[containerClass, 'flex flex-col md:flex-row gap-10 items-center', reverse ? 'md:flex-row-reverse' : '']">
46
46
  <div :class="['md:w-2/3 w-full overflow-hidden relative', imageContainerClass]">
47
47
  <img v-if="image" :src="image" class="w-full h-full object-cover transition-transform duration-700 hover:scale-105" />
48
48
  <div v-else class="w-full h-full" :style="{ backgroundColor: ca(textColor, '08') }"></div>
49
49
  </div>
50
50
  <div class="md:w-1/3 space-y-5">
51
51
  <span v-if="badge" class="inline-block text-[10px] font-bold tracking-[0.5em] uppercase px-3 py-1 rounded-full border" :style="{ borderColor: ca(textColor, '25'), color: ca(textColor, 'aa') }">{{ badge }}</span>
52
- <component :is="titleTag" class="text-2xl md:text-3xl font-black uppercase tracking-tighter leading-[0.9]">{{ title }}</component>
53
- <p class="leading-relaxed text-sm" :style="{ opacity: 0.55 }">{{ content }}</p>
52
+ <component :is="titleTag" class="font-black uppercase tracking-tighter leading-[0.9]" :style="{ fontSize: titleFontSize }">{{ title }}</component>
53
+ <p :class="[bodyClass, 'leading-relaxed']" :style="{ opacity: 0.55 }">{{ content }}</p>
54
54
  <div v-if="ctas && ctas.length" class="flex flex-wrap gap-3 pt-1">
55
55
  <NuxtLink v-for="(cta, i) in ctas" :key="i" :to="cta.link || '#'"
56
56
  class="inline-flex items-center gap-2.5 px-6 py-3 rounded-full text-[11px] font-black uppercase tracking-widest transition-all hover:gap-5"
@@ -86,10 +86,16 @@ const props = defineProps({
86
86
  textColor: { type: String, default: "rgba(var(--text-color), 1)" },
87
87
  ctas: { type: Array, default: () => [] },
88
88
  spacing: { type: String, default: "normal" },
89
- radius: { type: String, default: "rounded" }
89
+ radius: { type: String, default: "rounded" },
90
+ textDirection: { type: String, default: "ltr" },
91
+ contentWidth: { type: String, default: "normal" },
92
+ textSize: { type: String, default: "md" }
90
93
  });
91
94
  const sectionPad = computed(() => ({ compact: "py-8 px-4 md:px-8", normal: "py-14 px-6 md:px-12", spacious: "py-24 px-8 md:px-16" })[props.spacing] || "py-14 px-6 md:px-12");
92
95
  const cardRound = computed(() => ({ sharp: "rounded-xl", rounded: "rounded-3xl", pill: "rounded-[40px]" })[props.radius] || "rounded-3xl");
96
+ const containerClass = computed(() => ({ narrow: "max-w-3xl mx-auto", normal: "max-w-6xl mx-auto", wide: "max-w-7xl mx-auto", full: "max-w-full" })[props.contentWidth] || "max-w-6xl mx-auto");
97
+ const titleFontSize = computed(() => ({ sm: "clamp(1.2rem,2.5vw,2rem)", md: "clamp(1.5rem,3.5vw,2.8rem)", lg: "clamp(2rem,5vw,4rem)" })[props.textSize] || "clamp(1.5rem,3.5vw,2.8rem)");
98
+ const bodyClass = computed(() => ({ sm: "text-xs", md: "text-sm", lg: "text-base" })[props.textSize] || "text-sm");
93
99
  const imageContainerClass = computed(() => {
94
100
  const r = cardRound.value;
95
101
  const styles = { rounded: `aspect-[4/3] ${r}`, square: "aspect-square rounded-xl", circle: "aspect-square rounded-full max-w-[360px] mx-auto", portrait: `aspect-[3/4] ${r} max-w-sm mx-auto` };