srcdev-nuxt-components 9.5.7 → 9.6.1
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/.claude/skills/component-compliance-checklist.md +8 -2
- package/.claude/skills/component-dynamic-slots.md +3 -3
- package/.claude/skills/component-export-types.md +10 -16
- package/.claude/skills/component-naming.md +1 -1
- package/.claude/skills/components/alert-content.md +9 -1
- package/.claude/skills/components/breadcrumb.md +5 -0
- package/.claude/skills/components/container-glow.md +21 -8
- package/.claude/skills/components/display-avatar.md +13 -7
- package/.claude/skills/components/display-chip.md +37 -24
- package/.claude/skills/components/display-pill.md +58 -8
- package/.claude/skills/components/display-prompt.md +8 -5
- package/.claude/skills/components/display-toast.md +21 -4
- package/.claude/skills/components/glowing-border.md +20 -2
- package/.claude/skills/components/input-button.md +3 -0
- package/.claude/skills/components/responsive-header.md +59 -0
- package/.claude/skills/components/select-menu.md +54 -5
- package/.claude/skills/components/service-detail.md +32 -0
- package/.claude/skills/components/service-summary.md +8 -0
- package/.claude/skills/components/services-card-grid.md +5 -3
- package/.claude/skills/components/services-card.md +22 -12
- package/.claude/skills/components/site-header.md +2 -2
- package/.claude/skills/components/slider-gallery.md +10 -4
- package/.claude/skills/components/tabbed-content.md +300 -0
- package/.claude/skills/composable-anchor-scroll.md +16 -15
- package/.claude/skills/index.md +4 -5
- package/.claude/skills/storybook-add-story.md +53 -0
- package/.claude/skills/theming-status-tokens.md +60 -0
- package/.vscode/srcdev-component-display-avatar.code-snippets +2 -1
- package/.vscode/srcdev-component-display-chip.code-snippets +3 -2
- package/.vscode/srcdev-component-display-pill.code-snippets +10 -0
- package/.vscode/srcdev-component-responsive-header.code-snippets +16 -0
- package/.vscode/srcdev-component-select-menu.code-snippets +28 -0
- package/.vscode/srcdev-component-service-detail.code-snippets +1 -0
- package/.vscode/srcdev-component-service-summary.code-snippets +3 -1
- package/.vscode/srcdev-component-services-card.code-snippets +38 -36
- package/.vscode/srcdev-component-services-grids.code-snippets +2 -1
- package/.vscode/{srcdev-component-tabs-core.code-snippets → srcdev-component-tabbed-content.code-snippets} +35 -16
- package/app/assets/styles/setup/03.theming/_status.css +24 -0
- package/app/assets/styles/setup/03.theming/index.css +1 -0
- package/app/components/01.atoms/animations/container-glow/CONSUMER-STYLING.md +39 -35
- package/app/components/01.atoms/animations/container-glow/ContainerGlow.vue +25 -15
- package/app/components/01.atoms/animations/container-glow/stories/ContainerGlow.stories.ts +130 -24
- package/app/components/01.atoms/animations/container-glow/tests/ContainerGlow.spec.ts +45 -0
- package/app/components/01.atoms/animations/container-glow/tests/__snapshots__/ContainerGlow.spec.ts.snap +2 -2
- package/app/components/01.atoms/animations/glowing-border/CONSUMER-STYLING.md +76 -19
- package/app/components/01.atoms/animations/glowing-border/GlowingBorder.vue +12 -10
- package/app/components/01.atoms/animations/glowing-border/stories/GlowingBorder.stories.ts +201 -42
- package/app/components/01.atoms/animations/glowing-border/tests/GlowingBorder.spec.ts +15 -4
- package/app/components/01.atoms/animations/glowing-border/tests/__snapshots__/GlowingBorder.spec.ts.snap +1 -1
- package/app/components/01.atoms/display-pill/CONSUMER-STYLING.md +78 -9
- package/app/components/01.atoms/display-pill/DisplayPill.vue +59 -23
- package/app/components/01.atoms/display-pill/stories/DisplayPill.stories.ts +240 -16
- package/app/components/01.atoms/display-pill/tests/DisplayPill.spec.ts +43 -14
- package/app/components/01.atoms/display-pill/tests/__snapshots__/DisplayPill.spec.ts.snap +3 -3
- package/app/components/01.atoms/navigation/breadcrumb/Breadcrumb.vue +16 -4
- package/app/components/01.atoms/navigation/breadcrumb/CONSUMER-STYLING.md +28 -5
- package/app/components/01.atoms/navigation/breadcrumb/stories/Breadcrumb.stories.ts +94 -0
- package/app/components/01.atoms/navigation/breadcrumb/tests/Breadcrumb.spec.ts +27 -0
- package/app/components/01.atoms/tabbed-content/CONSUMER-STYLING.md +201 -0
- package/app/components/01.atoms/tabbed-content/TabbedContent.vue +750 -0
- package/app/components/01.atoms/tabbed-content/stories/TabbedContent.stories.ts +279 -0
- package/app/components/01.atoms/tabbed-content/tests/TabbedContent.spec.ts +816 -0
- package/app/components/02.molecules/alert-content/AlertContent.vue +11 -2
- package/app/components/02.molecules/alert-content/AlertContentInner.vue +19 -0
- package/app/components/02.molecules/alert-content/CONSUMER-STYLING.md +17 -4
- package/app/components/02.molecules/alert-content/stories/AlertContent.stories.ts +200 -17
- package/app/components/02.molecules/alert-content/tests/AlertContent.spec.ts +33 -0
- package/app/components/02.molecules/display-avatar/CONSUMER-STYLING.md +7 -5
- package/app/components/02.molecules/display-avatar/DisplayAvatar.vue +6 -2
- package/app/components/02.molecules/display-avatar/stories/DisplayAvatar.stories.ts +24 -3
- package/app/components/02.molecules/display-avatar/tests/DisplayAvatar.spec.ts +19 -0
- package/app/components/02.molecules/display-avatar/tests/__snapshots__/DisplayAvatar.spec.ts.snap +2 -1
- package/app/components/02.molecules/display-chip/CONSUMER-STYLING.md +52 -19
- package/app/components/02.molecules/display-chip/DisplayChip.vue +72 -54
- package/app/components/02.molecules/display-chip/stories/DisplayChip.stories.ts +103 -6
- package/app/components/02.molecules/display-chip/tests/DisplayChip.spec.ts +98 -29
- package/app/components/02.molecules/display-chip/tests/__snapshots__/DisplayChip.spec.ts.snap +8 -4
- package/app/components/02.molecules/prompt/CONSUMER-STYLING.md +9 -1
- package/app/components/02.molecules/prompt/DisplayPrompt.vue +2 -2
- package/app/components/02.molecules/prompt/stories/DisplayPrompt.stories.ts +208 -71
- package/app/components/02.molecules/prompt/tests/DisplayPrompt.spec.ts +19 -6
- package/app/components/02.molecules/select-menu/CONSUMER-STYLING.md +66 -8
- package/app/components/02.molecules/select-menu/SelectMenu.vue +141 -18
- package/app/components/02.molecules/select-menu/stories/SelectMenu.stories.ts +232 -2
- package/app/components/02.molecules/select-menu/tests/SelectMenu.spec.ts +151 -0
- package/app/components/02.molecules/select-menu/tests/__snapshots__/SelectMenu.spec.ts.snap +6 -2
- package/app/components/02.molecules/toast/CONSUMER-STYLING.md +91 -27
- package/app/components/02.molecules/toast/DisplayToast.vue +109 -50
- package/app/components/02.molecules/toast/DisplayToastProvider.vue +109 -45
- package/app/components/02.molecules/toast/stories/DisplayToast.stories.ts +23 -0
- package/app/components/02.molecules/toast/stories/DisplayToastProvider.stories.ts +73 -0
- package/app/components/02.molecules/toast/tests/DisplayToast.spec.ts +132 -18
- package/app/components/02.molecules/toast/tests/DisplayToastProvider.spec.ts +105 -39
- package/app/components/03.organisms/image-galleries/slider-gallery/CONSUMER-STYLING.md +19 -1
- package/app/components/03.organisms/image-galleries/slider-gallery/SliderGallery.vue +65 -7
- package/app/components/03.organisms/image-galleries/slider-gallery/stories/SliderGallery.stories.ts +201 -63
- package/app/components/03.organisms/image-galleries/slider-gallery/tests/SliderGallery.spec.ts +41 -2
- package/app/components/03.organisms/image-galleries/slider-gallery/tests/__snapshots__/SliderGallery.spec.ts.snap +6 -6
- package/app/components/03.organisms/responsive-header/CONSUMER-STYLING.md +42 -11
- package/app/components/03.organisms/responsive-header/NavigationItems.vue +60 -16
- package/app/components/03.organisms/responsive-header/ResponsiveHeader.vue +86 -24
- package/app/components/03.organisms/responsive-header/stories/ResponsiveHeader.stories.ts +52 -0
- package/app/components/03.organisms/responsive-header/tests/NavigationItems.spec.ts +20 -0
- package/app/components/03.organisms/responsive-header/tests/ResponsiveHeader.spec.ts +40 -0
- package/app/components/03.organisms/services/service-detail/CONSUMER-STYLING.md +92 -41
- package/app/components/03.organisms/services/service-detail/ServiceDetail.vue +198 -73
- package/app/components/03.organisms/services/service-detail/stories/ServiceDetail.stories.ts +157 -9
- package/app/components/03.organisms/services/service-detail/tests/ServiceDetail.spec.ts +58 -0
- package/app/components/03.organisms/services/service-detail/tests/__snapshots__/ServiceDetail.spec.ts.snap +5 -4
- package/app/components/03.organisms/services/service-summary/CONSUMER-STYLING.md +30 -0
- package/app/components/03.organisms/services/service-summary/ServiceSummary.vue +32 -8
- package/app/components/03.organisms/services/service-summary/stories/ServiceSummary.stories.ts +147 -0
- package/app/components/03.organisms/services/service-summary/tests/ServiceSummary.spec.ts +26 -0
- package/app/components/03.organisms/services/service-summary/tests/__snapshots__/ServiceSummary.spec.ts.snap +2 -2
- package/app/components/03.organisms/services/services-card/CONSUMER-STYLING.md +104 -63
- package/app/components/03.organisms/services/services-card/ServicesCard.vue +92 -66
- package/app/components/03.organisms/services/services-card/stories/ServicesCard.stories.ts +194 -27
- package/app/components/03.organisms/services/services-card/tests/ServicesCard.spec.ts +34 -8
- package/app/components/03.organisms/services/services-card/tests/__snapshots__/ServicesCard.spec.ts.snap +8 -8
- package/app/components/03.organisms/services/services-grids/CONSUMER-STYLING.md +9 -0
- package/app/components/03.organisms/services/services-grids/ServicesCardGrid.vue +2 -1
- package/app/components/03.organisms/services/services-grids/stories/ServiceSummaryGrid.stories.ts +46 -6
- package/app/components/03.organisms/services/services-grids/stories/ServicesCardGrid.stories.ts +89 -11
- package/app/components/03.organisms/services/services-grids/tests/ServicesCardGrid.spec.ts +8 -0
- package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServiceSummaryGrid.spec.ts.snap +6 -6
- package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServicesCardGrid.spec.ts.snap +24 -24
- package/app/components/05.forms/input-button/CONSUMER-STYLING.md +8 -0
- package/app/components/05.forms/input-button/InputButton.vue +3 -1
- package/app/composables/tests/useAnchorScroll.spec.ts +8 -0
- package/app/composables/useAnchorScroll.ts +1 -1
- package/app/composables/useTabs.ts +148 -206
- package/app/types/components/display-chip.d.ts +8 -4
- package/app/types/components/display-toast.d.ts +2 -0
- package/app/types/components/index.ts +0 -1
- package/app/types/components/select-menu.d.ts +2 -0
- package/app/utils/pausableTimeout.ts +41 -0
- package/nuxt.config.ts +1 -1
- package/package.json +1 -1
- package/.claude/skills/components/site-navigation.md +0 -145
- package/.claude/skills/components/tab-navigation.md +0 -272
- package/.claude/skills/components/tabs-core.md +0 -187
- package/.vscode/srcdev-component-site-navigation.code-snippets +0 -38
- package/.vscode/srcdev-component-tab-navigation.code-snippets +0 -30
- package/app/components/01.atoms/navigation/tabs/CONSUMER-STYLING.md +0 -120
- package/app/components/01.atoms/navigation/tabs/TabsCore.vue +0 -272
- package/app/components/01.atoms/navigation/tabs/stories/TabsCore.stories.ts +0 -199
- package/app/components/01.atoms/navigation/tabs/tests/TabsCore.spec.ts +0 -274
- package/app/components/02.molecules/navigation/site-navigation/CONSUMER-STYLING.md +0 -109
- package/app/components/02.molecules/navigation/site-navigation/SiteNavigation.vue +0 -751
- package/app/components/02.molecules/navigation/site-navigation/stories/SiteNavigation.stories.ts +0 -356
- package/app/components/02.molecules/navigation/site-navigation/tests/SiteNavigation.spec.ts +0 -367
- package/app/components/02.molecules/navigation/site-navigation/tests/__snapshots__/SiteNavigation.spec.ts.snap +0 -30
- package/app/components/02.molecules/navigation/tab-navigation/CONSUMER-STYLING.md +0 -150
- package/app/components/02.molecules/navigation/tab-navigation/TabNavigation.vue +0 -518
- package/app/components/02.molecules/navigation/tab-navigation/stories/TabNavigation.stories.ts +0 -340
- package/app/components/02.molecules/navigation/tab-navigation/tests/TabNavigation.spec.ts +0 -339
- package/app/components/02.molecules/navigation/tab-navigation/tests/__snapshots__/TabNavigation.spec.ts.snap +0 -33
- package/app/composables/useNavCollapse.ts +0 -86
- package/app/types/components/nav-item.d.ts +0 -11
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
exports[`ServiceSummary > renders correct HTML structure 1`] = `
|
|
4
4
|
"<div class="service-summary">
|
|
5
5
|
<div class="service-summary__grid">
|
|
6
|
-
<div class="service-summary__image-wrapper"><img data-nuxt-img="" srcset="/_ipx/
|
|
6
|
+
<div class="service-summary__image-wrapper"><img width="1080" height="1080" data-nuxt-img="" srcset="/_ipx/s_1080x1080/images/test.jpg 1x, /_ipx/s_2160x2160/images/test.jpg 2x" alt="Test Service" loading="eager" fetchpriority="high" class="service-summary__image" src="/_ipx/s_1080x1080/images/test.jpg"></div>
|
|
7
7
|
<div class="service-summary__info-wrapper service-summary__info-wrapper--align-center">
|
|
8
8
|
<div class="eyebrow-text large">A subtitle</div>
|
|
9
9
|
<h2 id="v-0-0" class="hero-text mb-20 title axis-horizontal">
|
|
10
10
|
<!--v-if--><span class="text-block-0 normal">Test Service</span>
|
|
11
11
|
</h2>
|
|
12
|
-
<div class="service-summary__pills"><span class="display-pill md neutral"><!--v-if--><span class="display-pill-label">60 mins</span></span><span class="display-pill md neutral"><!--v-if--><span class="display-pill-label">From £50</span></span></div>
|
|
12
|
+
<div class="service-summary__pills"><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">60 mins</span></span><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">From £50</span></span></div>
|
|
13
13
|
<p class="page-body-normal">What this service is</p>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Every token below is consumed directly at its point of use (`var(--services-card-gap, 1rem)`,
|
|
6
6
|
etc.). The only private token is `--_scrim-colour`, which resolves
|
|
7
|
-
`--image-
|
|
7
|
+
`--services-card-image-details-scrim-colour` once so the scrim and the text colour read the same value. Set the token globally in
|
|
8
8
|
a theme file, scoped to a page wrapper, or per-instance via `styleClassPassthrough` — no
|
|
9
9
|
`:deep()` needed, component styles are unscoped.
|
|
10
10
|
|
|
@@ -16,15 +16,16 @@ i.e. `is-clickable` is on the root — since these all default to `transparent`/
|
|
|
16
16
|
|
|
17
17
|
| Token | Default | Controls |
|
|
18
18
|
|---|---|---|
|
|
19
|
-
| `--services-card-border-radius` | `0` | Root corner radius — also clips `.image-wrapper` (root has `overflow: hidden`), so set `--image-
|
|
19
|
+
| `--services-card-border-radius` | `0` | Root corner radius — also clips `.services-card-image-wrapper` (root has `overflow: hidden`), so set `--services-card-image-border-radius` to match if you want the image's own corners rounded consistently with a rounded root |
|
|
20
20
|
| `--services-card-border-width` | `1px` | Border thickness |
|
|
21
21
|
| `--services-card-border-colour` | `transparent` | Resting (non-hover) border colour |
|
|
22
22
|
| `--services-card-border-colour-hover` | resting border colour | Border colour on `:hover`/`:focus-visible` — defaults to whatever `--services-card-border-colour` resolves to, so setting only the resting colour keeps the border visible on hover instead of it vanishing |
|
|
23
23
|
| `--services-card-outline-width` | `2px` | Outline thickness |
|
|
24
24
|
| `--services-card-outline-colour` | `transparent` | Resting (non-hover) outline colour |
|
|
25
|
-
| `--services-card-outline-colour-hover` |
|
|
25
|
+
| `--services-card-outline-colour-hover` | resting outline colour | Outline colour on `:hover`/`:focus-visible` |
|
|
26
|
+
| `--services-card-outline-colour-focus` | hover outline colour, else `var(--theme-ring, currentColor)` | Keyboard focus ring colour. Never transparent by default, so the whole-card link always shows focus |
|
|
26
27
|
| `--services-card-outline-offset` | `0px` | Resting outline offset |
|
|
27
|
-
| `--services-card-outline-offset-hover` |
|
|
28
|
+
| `--services-card-outline-offset-hover` | resting outline offset | Outline offset on `:hover`/`:focus-visible` — e.g. set to a larger value than the resting offset for an outline that grows outward on hover |
|
|
28
29
|
| `--services-card-background-color-hover` | resting background colour | Background on `:hover`/`:focus-visible` |
|
|
29
30
|
| `--services-card-transform-hover` | `none` | Transform on `:hover`/`:focus-visible`, e.g. `translateY(-0.4rem)` for a lift. Transitions with the other states; skipped under `prefers-reduced-motion: reduce` |
|
|
30
31
|
|
|
@@ -43,61 +44,97 @@ i.e. `is-clickable` is on the root — since these all default to `transparent`/
|
|
|
43
44
|
|---|---|---|
|
|
44
45
|
| `--services-card-gap` | `1rem` | Gap between the image row and the details row |
|
|
45
46
|
| `--services-card-background-color` | `transparent` | Card background |
|
|
46
|
-
| `--services-card-padding-block` |
|
|
47
|
+
| `--services-card-padding-block` | `0` | Padding on the card root (block axis) |
|
|
47
48
|
| `--services-card-padding-inline` | `0` | Padding on the card root (inline axis). Leave at `0` for a flush image, and pad `--details-wrapper-padding-*` instead |
|
|
48
|
-
| `--image-
|
|
49
|
-
| `--image-
|
|
50
|
-
| `--image-
|
|
51
|
-
| `--image-
|
|
52
|
-
| `--
|
|
53
|
-
| `--
|
|
54
|
-
| `--details-
|
|
55
|
-
| `--details-
|
|
56
|
-
| `--eyebrow-
|
|
57
|
-
| `--
|
|
58
|
-
| `--description-padding-block` | `0 0` | Padding on the description text |
|
|
59
|
-
| `--description-text-colour` | `
|
|
60
|
-
| `--description-line-height` | `1.4` | Description line height |
|
|
61
|
-
| `--description-font-weight` | `inherit` | Description font weight |
|
|
62
|
-
| `--description-line-clamp` | `
|
|
63
|
-
| `--meta-padding-block` | `1.6rem 0` | Padding above/below the meta row's divider line |
|
|
64
|
-
| `--meta-border-colour` | `var(--theme-border)` | Meta row's top divider colour |
|
|
65
|
-
| `--meta-text-colour` | `inherit` | Duration/price text colour |
|
|
66
|
-
| `--meta-duration-text-colour` | meta text colour | Duration colour only |
|
|
67
|
-
| `--meta-price-text-colour` | meta text colour | Price colour only, e.g. brighter than the duration |
|
|
68
|
-
| `--meta-duration-font-weight` | `500` | Duration font weight |
|
|
69
|
-
| `--meta-price-font-weight` | `700` | Price font weight |
|
|
70
|
-
| `--meta-letter-spacing` | `inherit` | Letter-spacing on the meta row |
|
|
71
|
-
| `--meta-font-size` | `1.4rem` | Duration/price text size |
|
|
72
|
-
| `--meta-text-transform` | `uppercase` | Text transform on the duration/price meta row |
|
|
73
|
-
| `--
|
|
74
|
-
| `--footer-
|
|
49
|
+
| `--services-card-image-aspect-ratio` | `3/4` | Image aspect ratio |
|
|
50
|
+
| `--services-card-image-border-radius` | `8px` | Image corner radius |
|
|
51
|
+
| `--services-card-image-padding-block` | `0 0` | Padding inside the image wrapper (block axis) |
|
|
52
|
+
| `--services-card-image-padding-inline` | `0 0` | Padding inside the image wrapper (inline axis) |
|
|
53
|
+
| `--services-card-image-zoom-transform` | `scale(1.05)` | Transform applied to the image while the pointer is over the image. Set `none` to turn the zoom off (not `scale(0)`, which hides the image). Turning it off suits a whole-card link with its own hover effect (`--services-card-transform-hover`, border/background hover tokens): otherwise moving from the card body onto the image starts a second, separate effect |
|
|
54
|
+
| `--services-card-details-gap` | `1rem` | Gap between eyebrow/title/description/footer |
|
|
55
|
+
| `--services-card-details-padding-block` | `0` | Padding inside the details wrapper (block axis) |
|
|
56
|
+
| `--services-card-details-padding-inline` | `0` | Padding inside the details wrapper (inline axis) |
|
|
57
|
+
| `--services-card-eyebrow-padding-block` | `0.8rem 0` | Padding above/below the eyebrow |
|
|
58
|
+
| `--services-card-title-padding-block` | `2rem 1rem` | Padding above/below the title |
|
|
59
|
+
| `--services-card-description-padding-block` | `0 0` | Padding on the description text |
|
|
60
|
+
| `--services-card-description-text-colour` | `inherit` | Description paragraph colour |
|
|
61
|
+
| `--services-card-description-line-height` | `1.4` | Description line height |
|
|
62
|
+
| `--services-card-description-font-weight` | `inherit` | Description font weight |
|
|
63
|
+
| `--services-card-description-line-clamp` | `none` | Max lines of the description, with an ellipsis on the last. `1` is single-line ellipsis, `none` shows everything |
|
|
64
|
+
| `--services-card-meta-padding-block` | `1.6rem 0` | Padding above/below the meta row's divider line |
|
|
65
|
+
| `--services-card-meta-border-colour` | `var(--theme-border)` | Meta row's top divider colour |
|
|
66
|
+
| `--services-card-meta-text-colour` | `inherit` | Duration/price text colour |
|
|
67
|
+
| `--services-card-meta-duration-text-colour` | meta text colour | Duration colour only |
|
|
68
|
+
| `--services-card-meta-price-text-colour` | meta text colour | Price colour only, e.g. brighter than the duration |
|
|
69
|
+
| `--services-card-meta-duration-font-weight` | `500` | Duration font weight |
|
|
70
|
+
| `--services-card-meta-price-font-weight` | `700` | Price font weight |
|
|
71
|
+
| `--services-card-meta-letter-spacing` | `inherit` | Letter-spacing on the meta row |
|
|
72
|
+
| `--services-card-meta-font-size` | `1.4rem` | Duration/price text size |
|
|
73
|
+
| `--services-card-meta-text-transform` | `uppercase` | Text transform on the duration/price meta row |
|
|
74
|
+
| `--services-card-meta-gap` | `1rem` | Gap between the duration and price (and between rows when long values wrap) |
|
|
75
|
+
| `--services-card-footer-padding-block` | `0` | Padding on the `.services-card-footer` wrapper (meta row + actions slot) |
|
|
76
|
+
| `--services-card-footer-gap` | `1rem` | Gap between the meta row and the actions slot inside `.services-card-footer` |
|
|
75
77
|
|
|
76
78
|
### Titles over the image (`titlesWithinImageWrapper`)
|
|
77
79
|
|
|
78
80
|
| Token | Default | Controls |
|
|
79
81
|
|---|---|---|
|
|
80
|
-
| `--image-
|
|
81
|
-
| `--image-
|
|
82
|
-
| `--image-
|
|
83
|
-
| `--image-
|
|
84
|
-
| `--image-
|
|
85
|
-
| `--image-
|
|
86
|
-
| `--image-
|
|
82
|
+
| `--services-card-image-details-scrim-colour` | `#000` | Colour of the gradient scrim behind the title/eyebrow. Use an opaque colour: the default scrim fades it with `color-mix()`, and the text colour is derived from it |
|
|
83
|
+
| `--services-card-image-details-scrim` | `linear-gradient(to top, <scrim colour at 75%>, transparent 70%)` | The whole scrim `background` value — replace it for a different shape or direction, or set `none` to remove it |
|
|
84
|
+
| `--services-card-image-details-text-colour` | `contrast-color(<scrim colour>)`, `#fff` without support | Title/eyebrow text colour. Where `contrast-color()` is supported it picks black or white against the scrim colour, so a light scrim gets dark text automatically |
|
|
85
|
+
| `--services-card-image-details-eyebrow-colour` | `inherit` | Eyebrow colour. The eyebrow's gradient fill is turned off over the image so it can't clash with the photo |
|
|
86
|
+
| `--services-card-image-details-gap` | `0.5rem` | Gap between eyebrow and title |
|
|
87
|
+
| `--services-card-image-details-eyebrow-padding-block` / `-inline` | `0` / `2.2rem` | Eyebrow padding |
|
|
88
|
+
| `--services-card-image-details-title-padding-block` / `-inline` | `1.2rem 2.2rem` / `2.2rem` | Title padding |
|
|
87
89
|
|
|
88
|
-
`contrast-color()` only reads the scrim colour, not the photo. If you remove the scrim, set `--image-
|
|
90
|
+
`contrast-color()` only reads the scrim colour, not the photo. If you remove the scrim, set `--services-card-image-details-text-colour` yourself to suit the images.
|
|
89
91
|
|
|
90
92
|
```css
|
|
91
93
|
/* assets/styles/setup/07.components/services-card.css */
|
|
92
94
|
:root {
|
|
93
95
|
--services-card-gap: 1.4rem;
|
|
94
|
-
--description-line-clamp: 3;
|
|
95
|
-
--meta-text-transform: none;
|
|
96
|
+
--services-card-description-line-clamp: 3;
|
|
97
|
+
--services-card-meta-text-transform: none;
|
|
96
98
|
}
|
|
97
99
|
```
|
|
98
100
|
|
|
99
101
|
---
|
|
100
102
|
|
|
103
|
+
## State hooks
|
|
104
|
+
|
|
105
|
+
| Hook | When |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `.services-card.is-clickable` | Whole-card link mode: `href` set and no `actions` slot (root renders as `<a>` or `NuxtLink`) |
|
|
108
|
+
|
|
109
|
+
Inner classes: `.services-card-image-wrapper`, `.services-card-image`, `.services-card-image-details`
|
|
110
|
+
(titles over the image), `.services-card-details`, `.services-card-description`, `.services-card-footer`,
|
|
111
|
+
`.services-card-meta`, `.services-card-meta-duration`, `.services-card-meta-price`. The eyebrow and
|
|
112
|
+
title are `EyebrowText` (`.eyebrow-text`) and `HeroText` (`.hero-text`), so their own tokens
|
|
113
|
+
(`--eyebrow-text-*`, `--hero-text-*`) inherit down into the card.
|
|
114
|
+
|
|
115
|
+
Empty `subtitle`, `title` or `shortDescription` render no element at all, and the image overlay is
|
|
116
|
+
left out when both titles are empty.
|
|
117
|
+
|
|
118
|
+
> Changed 2026-10-06: every inner class and card-specific token is now prefixed `services-card-`.
|
|
119
|
+
> Old to new: `.image-wrapper` → `.services-card-image-wrapper`, `.image` → `.services-card-image`,
|
|
120
|
+
> `.image-wrapper-details` → `.services-card-image-details`, `.details-wrapper` → `.services-card-details`,
|
|
121
|
+
> `.description` / `.footer` / `.meta` / `.meta-duration` / `.meta-price` → `.services-card-*`;
|
|
122
|
+
> `--image-wrapper-details-*` → `--services-card-image-details-*` (with `-eyebrow-text-colour` → `-eyebrow-colour`,
|
|
123
|
+
> `-eyebrow-text-padding-*` → `-eyebrow-padding-*`, `-hero-text-padding-*` → `-title-padding-*`),
|
|
124
|
+
> `--image-wrapper-border-image-zoom-transform` → `--services-card-image-zoom-transform`,
|
|
125
|
+
> `--image-wrapper-*` → `--services-card-image-*`, `--details-wrapper-grid-gap` → `--services-card-details-gap`,
|
|
126
|
+
> `--details-wrapper-padding-*` → `--services-card-details-padding-*`,
|
|
127
|
+
> `--eyebrow-text-padding-block` → `--services-card-eyebrow-padding-block`,
|
|
128
|
+
> `--hero-text-padding-block` → `--services-card-title-padding-block`, `--description-*` / `--meta-*` →
|
|
129
|
+
> `--services-card-description-*` / `--services-card-meta-*`, `--footer-wrapper-grid-gap` →
|
|
130
|
+
> `--services-card-footer-gap`, `--footer-padding-block` → `--services-card-footer-padding-block`.
|
|
131
|
+
> Also: the description line clamp defaults to `none` (was `100`), the description colour defaults
|
|
132
|
+
> to `inherit` (its old fallback, `--colour-text-secondary`, was never defined, so nothing changes
|
|
133
|
+
> visually), the outline hover tokens fall back to the resting outline values, and keyboard focus now
|
|
134
|
+
> shows a ring by default (`--services-card-outline-colour-focus`; it was transparent).
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
101
138
|
## Text content — props/slots, not CSS
|
|
102
139
|
|
|
103
140
|
Duration and price text come from `serviceData.duration`/`serviceData.price` by default, or
|
|
@@ -107,6 +144,26 @@ the tokens above. See the component skill doc for slot/prop usage examples.
|
|
|
107
144
|
|
|
108
145
|
---
|
|
109
146
|
|
|
147
|
+
## Footer bottom-alignment (row-of-cards use)
|
|
148
|
+
|
|
149
|
+
`.services-card-footer` (the meta row + `actions` slot, grouped together) gets `margin-block-start: auto`
|
|
150
|
+
and the root uses `grid-template-rows: auto 1fr`, so when `ServicesCardGrid`'s default
|
|
151
|
+
`align-items: stretch` makes a card taller than its own content (to match a taller sibling in
|
|
152
|
+
the same row), the extra height goes to `.services-card-footer`'s top margin instead of leaving whitespace
|
|
153
|
+
below the actions slot. This keeps the meta row and actions/button aligned across a row of
|
|
154
|
+
cards regardless of each card's description length, without needing CSS subgrid.
|
|
155
|
+
|
|
156
|
+
`.services-card`, `.services-card-image-wrapper`, `.services-card-details`, and `.services-card-footer` all set
|
|
157
|
+
`min-inline-size: 0`. Without it, an unbreakable child — most commonly a long `actions` slot
|
|
158
|
+
button label, since `InputButton`'s `.button-text` is `white-space: nowrap` with no
|
|
159
|
+
ellipsis — forces its content's min-content width up through the flex/grid chain and widens
|
|
160
|
+
that one card's grid column in `ServicesCardGrid` wider than its siblings. If a card/column
|
|
161
|
+
ever looks wider than the rest with content cut off at the edge, check for a long unbreakable
|
|
162
|
+
string in a slot before assuming it's an image sizing issue — the image is just riding along
|
|
163
|
+
on the widened column, not the cause.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
110
167
|
## Local overrides
|
|
111
168
|
|
|
112
169
|
Set the tokens above on an element you own (a page or section class, or a class added with
|
|
@@ -126,38 +183,22 @@ Use sparingly — prefer global or page-scoped CSS. When a single instance needs
|
|
|
126
183
|
```css
|
|
127
184
|
.services-card.featured-service {
|
|
128
185
|
--services-card-gap: 1.6rem;
|
|
129
|
-
--meta-border-colour: var(--color-accent);
|
|
186
|
+
--services-card-meta-border-colour: var(--color-accent);
|
|
130
187
|
}
|
|
131
188
|
```
|
|
132
189
|
|
|
133
190
|
---
|
|
134
191
|
|
|
135
|
-
##
|
|
192
|
+
## Class passthrough
|
|
136
193
|
|
|
137
|
-
|
|
138
|
-
and the root uses `grid-template-rows: auto 1fr`, so when `ServicesCardGrid`'s default
|
|
139
|
-
`align-items: stretch` makes a card taller than its own content (to match a taller sibling in
|
|
140
|
-
the same row), the extra height goes to `.footer`'s top margin instead of leaving whitespace
|
|
141
|
-
below the actions slot. This keeps the meta row and actions/button aligned across a row of
|
|
142
|
-
cards regardless of each card's description length, without needing CSS subgrid.
|
|
143
|
-
|
|
144
|
-
`.services-card`, `.image-wrapper`, `.details-wrapper`, and `.footer` all set
|
|
145
|
-
`min-inline-size: 0`. Without it, an unbreakable child — most commonly a long `actions` slot
|
|
146
|
-
button label, since `InputButton`'s `.button-text` is `white-space: nowrap` with no
|
|
147
|
-
ellipsis — forces its content's min-content width up through the flex/grid chain and widens
|
|
148
|
-
that one card's grid column in `ServicesCardGrid` wider than its siblings. If a card/column
|
|
149
|
-
ever looks wider than the rest with content cut off at the edge, check for a long unbreakable
|
|
150
|
-
string in a slot before assuming it's an image sizing issue — the image is just riding along
|
|
151
|
-
on the widened column, not the cause.
|
|
194
|
+
`style-class-passthrough` adds classes to the root `.services-card`. Reactive after mount.
|
|
152
195
|
|
|
153
196
|
---
|
|
154
197
|
|
|
155
198
|
## Notes
|
|
156
199
|
|
|
157
|
-
- `--
|
|
158
|
-
(the meta row ↔ actions slot gap inside `.footer`) are separate tokens — overriding one does
|
|
200
|
+
- `--services-card-details-gap` (details-wrapper's own children) and `--services-card-footer-gap`
|
|
201
|
+
(the meta row ↔ actions slot gap inside `.services-card-footer`) are separate tokens — overriding one does
|
|
159
202
|
not affect the other.
|
|
160
|
-
- `.meta`'s internal gap (between the duration and price text) is a fixed `1rem`, not a token.
|
|
161
203
|
- Root element tag, `href`/`external` (whole-card-clickable), `eyebrowConfig`, and `heroConfig`
|
|
162
204
|
are props, not CSS — see the component skill doc.
|
|
163
|
-
|
|
@@ -5,18 +5,30 @@
|
|
|
5
5
|
class="services-card"
|
|
6
6
|
:class="[elementClasses, { 'is-clickable': isClickable() }]"
|
|
7
7
|
>
|
|
8
|
-
<GridStack tag="div" :style-class-passthrough="['image-wrapper']">
|
|
8
|
+
<GridStack tag="div" :style-class-passthrough="['services-card-image-wrapper']">
|
|
9
9
|
<template #layer-1>
|
|
10
|
-
<NuxtImg
|
|
10
|
+
<NuxtImg
|
|
11
|
+
:src="serviceData.image"
|
|
12
|
+
:alt="serviceData.title"
|
|
13
|
+
width="640"
|
|
14
|
+
height="853"
|
|
15
|
+
loading="lazy"
|
|
16
|
+
class="services-card-image"
|
|
17
|
+
/>
|
|
11
18
|
</template>
|
|
12
19
|
<template #layer-2>
|
|
13
|
-
<div
|
|
20
|
+
<div
|
|
21
|
+
v-if="props.titlesWithinImageWrapper && (serviceData.subtitle || serviceData.title)"
|
|
22
|
+
class="services-card-image-details"
|
|
23
|
+
>
|
|
14
24
|
<EyebrowText
|
|
25
|
+
v-if="serviceData.subtitle"
|
|
15
26
|
:font-size="eyebrowConfig.fontSize ?? 'medium'"
|
|
16
27
|
:tag="eyebrowConfig.tag ?? 'div'"
|
|
17
28
|
:text-content="serviceData.subtitle"
|
|
18
29
|
/>
|
|
19
30
|
<HeroText
|
|
31
|
+
v-if="serviceData.title"
|
|
20
32
|
:tag="heroConfig.tag ?? 'h2'"
|
|
21
33
|
:font-size="heroConfig.fontSize ?? 'heading'"
|
|
22
34
|
:text-content="[
|
|
@@ -30,15 +42,15 @@
|
|
|
30
42
|
</template>
|
|
31
43
|
</GridStack>
|
|
32
44
|
|
|
33
|
-
<div class="details
|
|
45
|
+
<div class="services-card-details">
|
|
34
46
|
<EyebrowText
|
|
35
|
-
v-if="!props.titlesWithinImageWrapper"
|
|
47
|
+
v-if="!props.titlesWithinImageWrapper && serviceData.subtitle"
|
|
36
48
|
:font-size="eyebrowConfig.fontSize ?? 'large'"
|
|
37
49
|
:tag="eyebrowConfig.tag ?? 'div'"
|
|
38
50
|
:text-content="serviceData.subtitle"
|
|
39
51
|
/>
|
|
40
52
|
<HeroText
|
|
41
|
-
v-if="!props.titlesWithinImageWrapper"
|
|
53
|
+
v-if="!props.titlesWithinImageWrapper && serviceData.title"
|
|
42
54
|
:tag="heroConfig.tag ?? 'h2'"
|
|
43
55
|
:font-size="heroConfig.fontSize ?? 'heading'"
|
|
44
56
|
:text-content="[
|
|
@@ -48,15 +60,15 @@
|
|
|
48
60
|
},
|
|
49
61
|
]"
|
|
50
62
|
/>
|
|
51
|
-
<div class="description">
|
|
63
|
+
<div v-if="serviceData.shortDescription" class="services-card-description">
|
|
52
64
|
{{ serviceData.shortDescription }}
|
|
53
65
|
</div>
|
|
54
|
-
<div v-if="hasFooter()" class="footer">
|
|
55
|
-
<div v-if="hasMeta()" class="meta">
|
|
56
|
-
<div class="meta-duration">
|
|
66
|
+
<div v-if="hasFooter()" class="services-card-footer">
|
|
67
|
+
<div v-if="hasMeta()" class="services-card-meta">
|
|
68
|
+
<div class="services-card-meta-duration">
|
|
57
69
|
<slot name="duration" :service-data="serviceData">{{ durationText }}</slot>
|
|
58
70
|
</div>
|
|
59
|
-
<div class="meta-price">
|
|
71
|
+
<div class="services-card-meta-price">
|
|
60
72
|
<slot name="price" :service-data="serviceData">{{ priceText }}</slot>
|
|
61
73
|
</div>
|
|
62
74
|
</div>
|
|
@@ -141,7 +153,7 @@ watch(
|
|
|
141
153
|
min-inline-size: 0;
|
|
142
154
|
|
|
143
155
|
background-color: var(--services-card-background-color, transparent);
|
|
144
|
-
padding-block: var(--services-card-padding-block,);
|
|
156
|
+
padding-block: var(--services-card-padding-block, 0);
|
|
145
157
|
padding-inline: var(--services-card-padding-inline, 0);
|
|
146
158
|
border-radius: var(--services-card-border-radius, 0);
|
|
147
159
|
border: var(--services-card-border-width, 1px) solid var(--services-card-border-colour, transparent);
|
|
@@ -170,11 +182,18 @@ watch(
|
|
|
170
182
|
var(--services-card-background-color, transparent)
|
|
171
183
|
);
|
|
172
184
|
border-color: var(--services-card-border-colour-hover, var(--services-card-border-colour, transparent));
|
|
173
|
-
outline-color: var(--services-card-outline-colour-hover, transparent);
|
|
174
|
-
outline-offset: var(--services-card-outline-offset-hover, 0px);
|
|
185
|
+
outline-color: var(--services-card-outline-colour-hover, var(--services-card-outline-colour, transparent));
|
|
186
|
+
outline-offset: var(--services-card-outline-offset-hover, var(--services-card-outline-offset, 0px));
|
|
175
187
|
transform: var(--services-card-transform-hover, none);
|
|
176
188
|
}
|
|
177
189
|
|
|
190
|
+
&:focus-visible {
|
|
191
|
+
outline-color: var(
|
|
192
|
+
--services-card-outline-colour-focus,
|
|
193
|
+
var(--services-card-outline-colour-hover, var(--theme-ring, currentColor))
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
178
197
|
@media (prefers-reduced-motion: reduce) {
|
|
179
198
|
&:hover,
|
|
180
199
|
&:focus-visible {
|
|
@@ -183,16 +202,16 @@ watch(
|
|
|
183
202
|
}
|
|
184
203
|
}
|
|
185
204
|
|
|
186
|
-
.image-wrapper {
|
|
187
|
-
aspect-ratio: var(--image-
|
|
188
|
-
border-radius: var(--image-
|
|
205
|
+
.services-card-image-wrapper {
|
|
206
|
+
aspect-ratio: var(--services-card-image-aspect-ratio, 3/4);
|
|
207
|
+
border-radius: var(--services-card-image-border-radius, 8px);
|
|
189
208
|
overflow: hidden;
|
|
190
209
|
isolation: isolate;
|
|
191
210
|
min-inline-size: 0;
|
|
192
|
-
padding-block: var(--image-
|
|
193
|
-
padding-inline: var(--image-
|
|
211
|
+
padding-block: var(--services-card-image-padding-block, 0 0);
|
|
212
|
+
padding-inline: var(--services-card-image-padding-inline, 0 0);
|
|
194
213
|
|
|
195
|
-
.image {
|
|
214
|
+
.services-card-image {
|
|
196
215
|
display: block;
|
|
197
216
|
object-fit: cover;
|
|
198
217
|
width: 100%;
|
|
@@ -200,107 +219,114 @@ watch(
|
|
|
200
219
|
transition: transform 0.3s ease-in-out;
|
|
201
220
|
}
|
|
202
221
|
|
|
203
|
-
&:hover .image {
|
|
204
|
-
transform: var(--
|
|
222
|
+
&:hover .services-card-image {
|
|
223
|
+
transform: var(--services-card-image-zoom-transform, scale(1.05));
|
|
205
224
|
}
|
|
206
225
|
|
|
207
|
-
.image-
|
|
208
|
-
--_scrim-colour: var(--image-
|
|
226
|
+
.services-card-image-details {
|
|
227
|
+
--_scrim-colour: var(--services-card-image-details-scrim-colour, #000);
|
|
209
228
|
|
|
210
229
|
position: relative;
|
|
211
230
|
z-index: 1;
|
|
212
231
|
display: grid;
|
|
213
232
|
grid-auto-flow: row;
|
|
214
233
|
align-content: end;
|
|
215
|
-
gap: var(--image-
|
|
234
|
+
gap: var(--services-card-image-details-gap, 0.5rem);
|
|
216
235
|
height: 100%;
|
|
217
|
-
|
|
218
|
-
|
|
236
|
+
overflow-wrap: anywhere;
|
|
237
|
+
color: var(--services-card-image-details-text-colour, #fff);
|
|
238
|
+
background: var(--services-card-image-details-scrim, linear-gradient(to top, rgb(0 0 0 / 0.75), transparent 70%));
|
|
219
239
|
|
|
220
240
|
@supports (color: color-mix(in oklab, red, transparent)) {
|
|
221
241
|
background: var(
|
|
222
|
-
--image-
|
|
242
|
+
--services-card-image-details-scrim,
|
|
223
243
|
linear-gradient(to top, color-mix(in oklab, var(--_scrim-colour) 75%, transparent), transparent 70%)
|
|
224
244
|
);
|
|
225
245
|
}
|
|
226
246
|
|
|
227
247
|
@supports (color: contrast-color(red)) {
|
|
228
|
-
color: var(--image-
|
|
248
|
+
color: var(--services-card-image-details-text-colour, contrast-color(var(--_scrim-colour)));
|
|
229
249
|
}
|
|
230
250
|
|
|
231
251
|
.eyebrow-text {
|
|
232
252
|
--eyebrow-text-bg-img: none;
|
|
233
|
-
color: var(--image-
|
|
234
|
-
padding-block: var(--image-
|
|
235
|
-
padding-inline: var(--image-
|
|
253
|
+
color: var(--services-card-image-details-eyebrow-colour, inherit);
|
|
254
|
+
padding-block: var(--services-card-image-details-eyebrow-padding-block, 0);
|
|
255
|
+
padding-inline: var(--services-card-image-details-eyebrow-padding-inline, 2.2rem);
|
|
236
256
|
}
|
|
237
257
|
|
|
238
258
|
.hero-text {
|
|
239
|
-
padding-block: var(--image-
|
|
240
|
-
padding-inline: var(--image-
|
|
259
|
+
padding-block: var(--services-card-image-details-title-padding-block, 1.2rem 2.2rem);
|
|
260
|
+
padding-inline: var(--services-card-image-details-title-padding-inline, 2.2rem);
|
|
241
261
|
}
|
|
242
262
|
}
|
|
243
263
|
}
|
|
244
264
|
|
|
245
|
-
.details
|
|
265
|
+
.services-card-details {
|
|
246
266
|
display: flex;
|
|
247
267
|
flex-direction: column;
|
|
248
|
-
gap: var(--
|
|
268
|
+
gap: var(--services-card-details-gap, 1rem);
|
|
249
269
|
min-inline-size: 0;
|
|
270
|
+
overflow-wrap: anywhere;
|
|
250
271
|
|
|
251
|
-
padding-block: var(--details-
|
|
252
|
-
padding-inline: var(--details-
|
|
272
|
+
padding-block: var(--services-card-details-padding-block, 0);
|
|
273
|
+
padding-inline: var(--services-card-details-padding-inline, 0);
|
|
253
274
|
|
|
254
275
|
.eyebrow-text {
|
|
255
|
-
padding-block: var(--eyebrow-
|
|
276
|
+
padding-block: var(--services-card-eyebrow-padding-block, 0.8rem 0);
|
|
256
277
|
}
|
|
257
278
|
|
|
258
279
|
.hero-text {
|
|
259
|
-
padding-block: var(--
|
|
280
|
+
padding-block: var(--services-card-title-padding-block, 1.2rem 1rem);
|
|
260
281
|
}
|
|
261
282
|
|
|
262
|
-
.description {
|
|
263
|
-
color: var(--description-text-colour,
|
|
264
|
-
font-weight: var(--description-font-weight, inherit);
|
|
265
|
-
line-height: var(--description-line-height, 1.4);
|
|
266
|
-
padding-block: var(--description-padding-block, 0 0);
|
|
283
|
+
.services-card-description {
|
|
284
|
+
color: var(--services-card-description-text-colour, inherit);
|
|
285
|
+
font-weight: var(--services-card-description-font-weight, inherit);
|
|
286
|
+
line-height: var(--services-card-description-line-height, 1.4);
|
|
287
|
+
padding-block: var(--services-card-description-padding-block, 0 0);
|
|
267
288
|
|
|
268
289
|
display: -webkit-box;
|
|
269
290
|
-webkit-box-orient: vertical;
|
|
270
291
|
overflow: hidden;
|
|
271
|
-
-webkit-line-clamp: var(--description-line-clamp,
|
|
272
|
-
line-clamp: var(--description-line-clamp,
|
|
273
|
-
text-overflow: ellipsis;
|
|
292
|
+
-webkit-line-clamp: var(--services-card-description-line-clamp, none);
|
|
293
|
+
line-clamp: var(--services-card-description-line-clamp, none);
|
|
274
294
|
}
|
|
275
295
|
|
|
276
|
-
.footer {
|
|
296
|
+
.services-card-footer {
|
|
277
297
|
display: flex;
|
|
278
298
|
flex-direction: column;
|
|
279
|
-
gap: var(--
|
|
299
|
+
gap: var(--services-card-footer-gap, 1rem);
|
|
280
300
|
margin-block-start: auto;
|
|
281
301
|
min-inline-size: 0;
|
|
282
|
-
padding-block: var(--footer-padding-block, 0);
|
|
302
|
+
padding-block: var(--services-card-footer-padding-block, 0);
|
|
283
303
|
|
|
284
|
-
.meta {
|
|
304
|
+
.services-card-meta {
|
|
285
305
|
display: flex;
|
|
306
|
+
flex-wrap: wrap;
|
|
286
307
|
align-items: center;
|
|
287
308
|
justify-content: space-between;
|
|
288
|
-
gap: 1rem;
|
|
289
|
-
padding-block: var(--meta-padding-block, 1.6rem 0);
|
|
290
|
-
border-block-start: 1px solid var(--meta-border-colour, var(--theme-border));
|
|
291
|
-
color: var(--meta-text-colour, inherit);
|
|
292
|
-
font-size: var(--meta-font-size, 1.4rem);
|
|
293
|
-
letter-spacing: var(--meta-letter-spacing, inherit);
|
|
294
|
-
text-transform: var(--meta-text-transform, uppercase);
|
|
295
|
-
|
|
296
|
-
.meta-duration
|
|
297
|
-
|
|
298
|
-
|
|
309
|
+
gap: var(--services-card-meta-gap, 1rem);
|
|
310
|
+
padding-block: var(--services-card-meta-padding-block, 1.6rem 0);
|
|
311
|
+
border-block-start: 1px solid var(--services-card-meta-border-colour, var(--theme-border));
|
|
312
|
+
color: var(--services-card-meta-text-colour, inherit);
|
|
313
|
+
font-size: var(--services-card-meta-font-size, 1.4rem);
|
|
314
|
+
letter-spacing: var(--services-card-meta-letter-spacing, inherit);
|
|
315
|
+
text-transform: var(--services-card-meta-text-transform, uppercase);
|
|
316
|
+
|
|
317
|
+
.services-card-meta-duration,
|
|
318
|
+
.services-card-meta-price {
|
|
319
|
+
min-inline-size: 0;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.services-card-meta-duration {
|
|
323
|
+
color: var(--services-card-meta-duration-text-colour, inherit);
|
|
324
|
+
font-weight: var(--services-card-meta-duration-font-weight, 500);
|
|
299
325
|
}
|
|
300
326
|
|
|
301
|
-
.meta-price {
|
|
302
|
-
color: var(--meta-price-text-colour, inherit);
|
|
303
|
-
font-weight: var(--meta-price-font-weight, 700);
|
|
327
|
+
.services-card-meta-price {
|
|
328
|
+
color: var(--services-card-meta-price-text-colour, inherit);
|
|
329
|
+
font-weight: var(--services-card-meta-price-font-weight, 700);
|
|
304
330
|
}
|
|
305
331
|
}
|
|
306
332
|
}
|