@eox/pages-theme-eox 1.6.0 → 1.7.0

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
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ # [1.7.0](https://gitlab.eox.at/eox/hub/eoxhub-portal/compare/v1.6.0...v1.7.0) (2026-05-11)
4
+
5
+ ### Bug Fixes
6
+
7
+ - **style:** card link/border/elevation ([004611f](https://gitlab.eox.at/eox/hub/eoxhub-portal/commit/004611f20e46dd47030a6c835bd6380fd045369b))
8
+ - **style:** nav menu rounding harmonization ([a5ff2e7](https://gitlab.eox.at/eox/hub/eoxhub-portal/commit/a5ff2e7a3b63e98b44f7b763ad79c2111c748286))
9
+ - **style:** sizing adjustments for prices and plan names ([d61ef7a](https://gitlab.eox.at/eox/hub/eoxhub-portal/commit/d61ef7a37ae0a3cede844875b582965eb820e704))
10
+
3
11
  # [1.6.0](https://gitlab.eox.at/eox/hub/eoxhub-portal/compare/v1.5.1...v1.6.0) (2026-04-30)
4
12
 
5
13
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eox/pages-theme-eox",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "type": "module",
5
5
  "description": "Vitepress Theme with EOX branding",
6
6
  "main": "src/index.js",
@@ -40,7 +40,10 @@ const iconStyle = {
40
40
  };
41
41
  </script>
42
42
  <template>
43
- <article class="vertical large-padding">
43
+ <article
44
+ class="vertical large-padding no-margin"
45
+ :class="link && !link.text ? 'small-elevate' : 'no-elevate'"
46
+ >
44
47
  <div>
45
48
  <i
46
49
  v-if="typeof icon === 'string' && icon.startsWith('mdi-')"
@@ -92,10 +95,10 @@ const iconStyle = {
92
95
  <nav
93
96
  v-if="link || secondaryLink"
94
97
  class="row wrap align-center"
95
- style="gap: 1.5rem; margin-right: auto"
98
+ style="gap: 1.5rem; margin-right: auto; position: relative; z-index: 11"
96
99
  >
97
100
  <a
98
- v-if="link"
101
+ v-if="link && !!link.text"
99
102
  :href="link.href"
100
103
  :target="link.target ?? '_blank'"
101
104
  class="button transparent bold primary-text no-padding"
@@ -48,7 +48,8 @@ const cardStyle = computed(() => ({
48
48
 
49
49
  <template>
50
50
  <article
51
- class="no-padding fill small-elevate image-overlay-card"
51
+ class="no-padding no-margin fill image-overlay-card"
52
+ :class="link && !link.text ? 'small-elevate' : 'no-elevate'"
52
53
  :style="cardStyle"
53
54
  >
54
55
  <img v-if="image" :src="image" alt="" class="image-overlay-card-image" />
@@ -97,10 +98,10 @@ const cardStyle = computed(() => ({
97
98
  <nav
98
99
  v-if="link || secondaryLink"
99
100
  class="row wrap align-center"
100
- style="gap: 0.5rem"
101
+ style="gap: 0.5rem; position: relative; z-index: 11"
101
102
  >
102
103
  <a
103
- v-if="link"
104
+ v-if="link && link.text"
104
105
  class="button small white black-text"
105
106
  :href="link.href"
106
107
  :target="link.target ?? '_blank'"
@@ -179,19 +179,19 @@ section {
179
179
  }
180
180
 
181
181
  .link-card {
182
- display: block;
182
+ display: flex;
183
+ flex: 1;
183
184
  text-decoration: none;
184
- border: 0.0625rem solid transparent;
185
185
  position: relative;
186
186
  }
187
187
  .link-overlay {
188
188
  position: absolute;
189
189
  inset: 0;
190
- z-index: 1;
190
+ z-index: 10;
191
191
  }
192
192
  .link-card:hover article {
193
- box-shadow: none;
194
- border: 0.0625rem solid var(--outline-variant);
193
+ box-shadow: var(--elevate2);
194
+ transform: translateY(-2px);
195
195
  }
196
196
 
197
197
  .card-wrapper {
@@ -138,19 +138,19 @@
138
138
  <li v-for="item in theme.nav.filter((i) => !i.action)">
139
139
  <div v-if="item.items">
140
140
  <button
141
- class="button text"
141
+ class="button text no-round"
142
142
  :class="{ active: isActive(item, route.path) }"
143
143
  >
144
144
  <span>{{ t(item.text, theme.i18n) }}</span>
145
145
  <i class="mdi mdi-chevron-down"></i>
146
146
  </button>
147
- <menu class="no-wrap surface-container-lowest">
147
+ <menu class="no-wrap surface-container-lowest no-round">
148
148
  <NavDropdown :items="item.items" />
149
149
  </menu>
150
150
  </div>
151
151
  <a
152
152
  v-else
153
- class="button text"
153
+ class="button text no-round"
154
154
  :class="{ active: isActive(item, route.path) }"
155
155
  :href="withBase(item.link)"
156
156
  :target="item.target"
@@ -199,7 +199,7 @@
199
199
  <ul class="left-align no-margin" v-if="langs && langs.length > 1">
200
200
  <li>
201
201
  <div>
202
- <button class="button text">
202
+ <button class="button text no-round">
203
203
  <i class="mdi mdi-translate small"></i>
204
204
  <i class="mdi mdi-chevron-down small"></i>
205
205
  </button>
@@ -42,7 +42,9 @@
42
42
  :key="`header-${index}`"
43
43
  class="s12 m3 center-align"
44
44
  >
45
- <h6 class="primary-text bold">{{ plan.name }}</h6>
45
+ <h6 class="primary-text bold" style="word-break: break-word">
46
+ {{ plan.name }}
47
+ </h6>
46
48
  <ClientOnly>
47
49
  <a
48
50
  :href="addPlanConfig(contactLink, plan)"
@@ -72,7 +74,9 @@
72
74
  class="cell surface-container-low top-cell bold top-margin"
73
75
  :class="`orig-col-${index + 2}`"
74
76
  >
75
- <h6 class="primary-text bold top-margin">{{ plan.name }}</h6>
77
+ <h6 class="primary-text bold top-margin" style="word-break: break-word">
78
+ {{ plan.name }}
79
+ </h6>
76
80
  </div>
77
81
 
78
82
  <div v-if="showDescriptionColumn" class="cell orig-col-1 l">
@@ -88,10 +92,11 @@
88
92
  <h6
89
93
  v-if="typeof plan.basePrice === 'string'"
90
94
  class="primary-text bold"
95
+ :style="dynamicPriceStyleH6"
91
96
  >
92
97
  {{ t(plan.basePrice, theme.i18n) }}
93
98
  </h6>
94
- <h4 v-else class="primary-text bold">
99
+ <h4 v-else class="primary-text bold" :style="dynamicPriceStyleH4">
95
100
  € {{ calculatePrice(plan) }},-
96
101
  </h4>
97
102
  <span
@@ -223,8 +228,14 @@
223
228
  class="surface-container-low primary-text bold top-margin top-cell"
224
229
  :class="`cell orig-col-${detailPlanIndex + 2}`"
225
230
  >
226
- <h6 class="primary-text bold s">{{ plan.name }}</h6>
227
- <h6 v-if="plan.additionalPrice" class="primary-text bold">
231
+ <h6 class="primary-text bold s" style="word-break: break-word">
232
+ {{ plan.name }}
233
+ </h6>
234
+ <h6
235
+ v-if="plan.additionalPrice"
236
+ class="primary-text bold"
237
+ :style="dynamicPriceStyleH6"
238
+ >
228
239
  + € {{ plan.additionalPrice }},-
229
240
  </h6>
230
241
  </div>
@@ -328,6 +339,73 @@ export default {
328
339
  };
329
340
  }
330
341
  },
342
+ maxPriceLength() {
343
+ let maxLen = 0;
344
+ this.localPlans.forEach((plan) => {
345
+ let text = "";
346
+ if (typeof plan.basePrice === "string") {
347
+ text = this.t(plan.basePrice, this.theme.i18n) || "";
348
+ } else {
349
+ text = `€ ${this.calculatePrice(plan)},-`;
350
+ }
351
+ if (text.length > maxLen) maxLen = text.length;
352
+ });
353
+ this.localDetails.forEach((detail) => {
354
+ if (detail.plans) {
355
+ detail.plans.forEach((plan) => {
356
+ if (plan.additionalPrice) {
357
+ const text = `+ € ${plan.additionalPrice},-`;
358
+ if (text.length > maxLen) maxLen = text.length;
359
+ }
360
+ });
361
+ }
362
+ });
363
+ return maxLen || 1;
364
+ },
365
+ dynamicPriceStyleH4() {
366
+ let fontSize = "";
367
+ if (!this.isMobile) {
368
+ // "€ 18000,-" is 11 chars. We want container to define this perfectly without pure JS guessing.
369
+ // Wait, pure CSS container queries / fluid typography is better here.
370
+ // Instead of calculating ratios manually, we can utilize container width scaling or vw based scaling
371
+ // if it exceeds length. Let's do a more robust JS calc.
372
+
373
+ const cols =
374
+ this.localPlans.length + (this.showDescriptionColumn ? 1 : 0);
375
+
376
+ // Base max chars before scaling based on how many cols are squished together
377
+ // 2 cols: allows ~16 chars
378
+ // 3 cols: allows ~12 chars
379
+ // 4 cols: allows ~9 chars
380
+ // 5 cols: allows ~7 chars
381
+ const maxCharsAtDefault = 19 - cols * 2.5;
382
+
383
+ if (this.maxPriceLength > maxCharsAtDefault) {
384
+ const ratio = maxCharsAtDefault / this.maxPriceLength;
385
+ fontSize = `${Math.max(ratio * 2.125, 0.8)}rem`; // Scale down, min ~12px equivalent
386
+ }
387
+ }
388
+ return {
389
+ whiteSpace: "nowrap",
390
+ ...(fontSize ? { fontSize } : {}),
391
+ };
392
+ },
393
+ dynamicPriceStyleH6() {
394
+ let fontSize = "";
395
+ if (!this.isMobile) {
396
+ const cols =
397
+ this.localPlans.length + (this.showDescriptionColumn ? 1 : 0);
398
+ const maxCharsAtDefault = 24 - cols * 3;
399
+ if (this.maxPriceLength > maxCharsAtDefault) {
400
+ const ratio = maxCharsAtDefault / this.maxPriceLength;
401
+ fontSize = `${Math.max(ratio * 1.25, 0.6)}rem`;
402
+ }
403
+ }
404
+ return {
405
+ whiteSpace: "nowrap",
406
+ ...(fontSize ? { fontSize } : {}),
407
+ };
408
+ },
331
409
  },
332
410
  methods: {
333
411
  calculatePrice(plan) {