srcdev-nuxt-components 9.1.58 → 9.2.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/.claude/settings.json +4 -1
- package/.claude/skills/component-aria-landmark.md +42 -8
- package/.claude/skills/components/auto-grid.md +12 -6
- package/.claude/skills/components/page-hero-highlights.md +3 -1
- package/.claude/skills/components/page-row.md +14 -5
- package/.claude/skills/components/profile-section.md +1 -1
- package/.claude/skills/components/services-section.md +63 -7
- package/.claude/skills/components/tab-navigation.md +49 -0
- package/.claude/skills/index.md +2 -2
- package/.claude/skills/testing-add-unit-test.md +18 -0
- package/app/components/01.atoms/grids/data-grid/AutoGrid.vue +1 -2
- package/app/components/01.atoms/grids/data-grid/tests/AutoGrid.spec.ts +11 -19
- package/app/components/01.atoms/grids/data-grid/tests/__snapshots__/AutoGrid.spec.ts.snap +1 -1
- package/app/components/01.atoms/page-row/tests/PageRow.spec.ts +28 -3
- package/app/components/02.molecules/profile-section/tests/ProfileSection.spec.ts +2 -2
- package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServicesSectionGrid.spec.ts.snap +18 -18
- package/app/components/03.organisms/services/services-section/CONSUMER-STYLING.md +149 -0
- package/app/components/03.organisms/services/services-section/ServicesSection.vue +85 -60
- package/app/components/03.organisms/services/services-section/stories/ServicesSection.stories.ts +186 -32
- package/app/components/03.organisms/services/services-section/tests/ServicesSection.spec.ts +83 -0
- package/app/components/03.organisms/services/services-section/tests/__snapshots__/ServicesSection.spec.ts.snap +11 -11
- package/app/components/04.templates/page-hero-highlights/tests/PageHeroHighlights.spec.ts +2 -2
- package/app/composables/tests/useAriaLabelledById.spec.ts +7 -2
- package/app/composables/useAriaLabelledById.ts +18 -1
- package/package.json +1 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# ServicesSection — Consumer Styling Guide
|
|
2
|
+
|
|
3
|
+
## Public token API
|
|
4
|
+
|
|
5
|
+
All `--services-section-*` tokens are the stable override surface. Set them globally in a
|
|
6
|
+
theme file, scoped to a page wrapper, or per-instance via `styleClassPassthrough`.
|
|
7
|
+
|
|
8
|
+
### Layout & sizing
|
|
9
|
+
|
|
10
|
+
| Token | Default | Controls |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| `--services-section-grid-gap` | `2rem` | Gap between image and content columns below the 768px breakpoint |
|
|
13
|
+
| `--services-section-grid-gap-desktop` | `3rem` | Gap between columns at 768px and above |
|
|
14
|
+
| `--services-section-image-border-radius` | `0.8rem` | Corner rounding on the service image |
|
|
15
|
+
| `--services-section-price-duration-gap` | `3rem` | Gap between the duration and price rows |
|
|
16
|
+
| `--services-section-price-duration-item-gap` | `0.8rem` | Gap between icon and text within a single row |
|
|
17
|
+
| `--services-section-price-duration-margin-block-end` | `2rem` | Space below the price/duration row |
|
|
18
|
+
| `--services-section-decorator-size` | `2rem` | Width/height of the duration and price icons |
|
|
19
|
+
| `--services-section-faq-margin-block-end` | `2.4rem` | Space below the FAQ accordion |
|
|
20
|
+
| `--services-section-faq-answer-line-height` | `1.6` | Line height of FAQ answer text |
|
|
21
|
+
|
|
22
|
+
### Colours
|
|
23
|
+
|
|
24
|
+
| Token | Default | Controls |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| `--services-section-faq-divider-color` | `currentColor` | Border colour between FAQ accordion items |
|
|
27
|
+
| `--services-section-faq-divider-opacity` | `0.7` | Opacity of each FAQ accordion item's border |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Text content — props, not CSS
|
|
32
|
+
|
|
33
|
+
Section headings and the default CTA panel copy are **props**, not hardcoded strings, so
|
|
34
|
+
there is nothing to override in CSS for these:
|
|
35
|
+
|
|
36
|
+
| Prop | Default |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `processHeading` | `"The Process"` |
|
|
39
|
+
| `idealForHeading` | `"Ideal For"` |
|
|
40
|
+
| `maintenanceHeading` | `"Aftercare & Maintenance"` |
|
|
41
|
+
| `faqsHeading` | `"Frequently Asked Questions"` |
|
|
42
|
+
| `ctaHeading` | `"Ready to book your appointment?"` |
|
|
43
|
+
| `ctaBody` | `"Get in touch to book your appointment."` |
|
|
44
|
+
|
|
45
|
+
```vue
|
|
46
|
+
<ServicesSection
|
|
47
|
+
:service-data="service"
|
|
48
|
+
cta-heading="Ready to book your locs consultation?"
|
|
49
|
+
cta-body="Mobile service across Bath — I come to you."
|
|
50
|
+
/>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If the CTA needs a different component entirely (not just different text), replace it with
|
|
54
|
+
the `cta-panel` scoped slot instead of styling around the default `GlassPanel`:
|
|
55
|
+
|
|
56
|
+
```vue
|
|
57
|
+
<ServicesSection :service-data="service">
|
|
58
|
+
<template #cta-panel="{ serviceData, ctaHeading, ctaBody }">
|
|
59
|
+
<MyCustomPanel :heading="ctaHeading" :body="ctaBody">
|
|
60
|
+
<template #cta><button>Enquire Now</button></template>
|
|
61
|
+
</MyCustomPanel>
|
|
62
|
+
</template>
|
|
63
|
+
</ServicesSection>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Global theming — recommended approach
|
|
69
|
+
|
|
70
|
+
Create `assets/styles/setup/07.components/services-section.css` in the consuming app and
|
|
71
|
+
set tokens on `:root`. This applies to every `ServicesSection` across the site.
|
|
72
|
+
|
|
73
|
+
```css
|
|
74
|
+
/* assets/styles/setup/07.components/services-section.css */
|
|
75
|
+
:root {
|
|
76
|
+
--services-section-grid-gap: 2.4rem;
|
|
77
|
+
--services-section-grid-gap-desktop: 4rem;
|
|
78
|
+
--services-section-image-border-radius: 1.2rem;
|
|
79
|
+
--services-section-faq-divider-color: var(--brand-border);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Page-scoped overrides
|
|
86
|
+
|
|
87
|
+
Override tokens for a specific section by scoping them under the page or layout wrapper.
|
|
88
|
+
No `:deep()` is required (component styles are unscoped).
|
|
89
|
+
|
|
90
|
+
```css
|
|
91
|
+
/* In the consuming page's unscoped <style> block */
|
|
92
|
+
.our-services-page {
|
|
93
|
+
.services-section {
|
|
94
|
+
--services-section-decorator-size: 2.4rem;
|
|
95
|
+
--services-section-faq-answer-line-height: 1.8;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Per-instance overrides via styleClassPassthrough
|
|
103
|
+
|
|
104
|
+
Use sparingly — prefer global or page-scoped CSS. When a single instance needs a distinct
|
|
105
|
+
visual style, pass a modifier class:
|
|
106
|
+
|
|
107
|
+
```vue
|
|
108
|
+
<ServicesSection :style-class-passthrough="['highlight-service']" :service-data="service" />
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```css
|
|
112
|
+
.services-section.highlight-service {
|
|
113
|
+
--services-section-image-border-radius: 2rem;
|
|
114
|
+
--services-section-faq-divider-color: var(--color-accent);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## FAQ accordion styling
|
|
121
|
+
|
|
122
|
+
The `AccordianCore` inside this component receives `services-section__faq` via
|
|
123
|
+
`styleClassPassthrough`. To target the accordion's own internals (summary, icon rotation,
|
|
124
|
+
content padding), style through that class rather than reaching into `AccordianCore`
|
|
125
|
+
directly — see `.services-section__faq` in the component's own `<style>` block for the
|
|
126
|
+
selectors already scoped this way (`.accordian-item.expanding-panel`,
|
|
127
|
+
`.expanding-panel-summary`, `.services-section__faq-answer`).
|
|
128
|
+
|
|
129
|
+
```css
|
|
130
|
+
.services-section {
|
|
131
|
+
.services-section__faq {
|
|
132
|
+
.expanding-panel-details .expanding-panel-summary {
|
|
133
|
+
padding-block: 1.6rem;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Notes
|
|
142
|
+
|
|
143
|
+
- `--services-section-grid-gap-desktop` only applies at `768px` and above — the breakpoint
|
|
144
|
+
itself is not a token, since changing it would affect the grid's `minmax()` column sizing
|
|
145
|
+
too, not just spacing.
|
|
146
|
+
- The CTA panel is rendered inside a default `<slot name="cta-panel">` — passing that slot
|
|
147
|
+
bypasses `GlassPanel` and all of its tokens (`--glass-panel-*`) entirely, along with the
|
|
148
|
+
`ctaHeading`/`ctaBody` props, which are handed to the slot for reuse rather than applied
|
|
149
|
+
automatically.
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component :is="tag" class="services-section" :class="[elementClasses]" :aria-labelledby="ariaLabelledby">
|
|
3
3
|
<div class="services-section__grid" :class="{ 'services-section__grid--reverse': reverse }">
|
|
4
|
-
<div class="
|
|
5
|
-
<NuxtImg
|
|
4
|
+
<div class="services-section__image-wrapper">
|
|
5
|
+
<NuxtImg
|
|
6
|
+
:src="serviceData.image"
|
|
7
|
+
:alt="serviceData.title"
|
|
8
|
+
:loading="imageLoading"
|
|
9
|
+
:fetchpriority="imageFetchPriority"
|
|
10
|
+
class="services-section__image"
|
|
11
|
+
/>
|
|
6
12
|
</div>
|
|
7
|
-
<div class="
|
|
13
|
+
<div class="services-section__info-wrapper" :class="infoWrapperClasses">
|
|
8
14
|
<EyebrowText font-size="large" :text-content="serviceData.subtitle" />
|
|
9
15
|
<HeroText
|
|
16
|
+
:id="headingId"
|
|
10
17
|
:tag="headerTag"
|
|
11
18
|
font-size="title"
|
|
12
19
|
:text-content="[
|
|
@@ -18,13 +25,13 @@
|
|
|
18
25
|
:style-class-passthrough="['mb-20']"
|
|
19
26
|
/>
|
|
20
27
|
|
|
21
|
-
<div class="
|
|
28
|
+
<div class="services-section__price-duration">
|
|
22
29
|
<div class="flex-row">
|
|
23
|
-
<Icon :name="durationIcon" class="
|
|
30
|
+
<Icon :name="durationIcon" class="services-section__decorator" />
|
|
24
31
|
<span>{{ serviceData.duration }}</span>
|
|
25
32
|
</div>
|
|
26
33
|
<div class="flex-row">
|
|
27
|
-
<Icon :name="priceIcon" class="
|
|
34
|
+
<Icon :name="priceIcon" class="services-section__decorator" />
|
|
28
35
|
<span>{{ serviceData.price }}</span>
|
|
29
36
|
</div>
|
|
30
37
|
</div>
|
|
@@ -50,7 +57,7 @@
|
|
|
50
57
|
:tag="headerTag"
|
|
51
58
|
axis="horizontal"
|
|
52
59
|
font-size="subheading"
|
|
53
|
-
:text-content="[{ text:
|
|
60
|
+
:text-content="[{ text: processHeading, styleClass: 'normal' }]"
|
|
54
61
|
:style-class-passthrough="['mb-20']"
|
|
55
62
|
/>
|
|
56
63
|
|
|
@@ -72,7 +79,7 @@
|
|
|
72
79
|
:tag="headerTag"
|
|
73
80
|
axis="horizontal"
|
|
74
81
|
font-size="subheading"
|
|
75
|
-
:text-content="[{ text:
|
|
82
|
+
:text-content="[{ text: idealForHeading, styleClass: 'normal' }]"
|
|
76
83
|
:style-class-passthrough="['mb-20']"
|
|
77
84
|
/>
|
|
78
85
|
|
|
@@ -90,7 +97,7 @@
|
|
|
90
97
|
:tag="headerTag"
|
|
91
98
|
axis="horizontal"
|
|
92
99
|
font-size="subheading"
|
|
93
|
-
:text-content="[{ text:
|
|
100
|
+
:text-content="[{ text: maintenanceHeading, styleClass: 'normal' }]"
|
|
94
101
|
:style-class-passthrough="['mb-20']"
|
|
95
102
|
/>
|
|
96
103
|
|
|
@@ -101,7 +108,7 @@
|
|
|
101
108
|
:tag="headerTag"
|
|
102
109
|
axis="horizontal"
|
|
103
110
|
font-size="subheading"
|
|
104
|
-
:text-content="[{ text:
|
|
111
|
+
:text-content="[{ text: faqsHeading, styleClass: 'normal' }]"
|
|
105
112
|
:style-class-passthrough="['mb-20']"
|
|
106
113
|
/>
|
|
107
114
|
|
|
@@ -110,7 +117,7 @@
|
|
|
110
117
|
id="faq"
|
|
111
118
|
:item-count="serviceData.faqs.length"
|
|
112
119
|
:name="`faq-${useId()}`"
|
|
113
|
-
:style-class-passthrough="['services-
|
|
120
|
+
:style-class-passthrough="['services-section__faq']"
|
|
114
121
|
>
|
|
115
122
|
<template v-for="(_, key) in serviceData.faqs" :key="`summary-${key}`" #[`accordian-${key}-summary`]>
|
|
116
123
|
{{ serviceData.faqs[key]?.question }}
|
|
@@ -119,21 +126,29 @@
|
|
|
119
126
|
<Icon name="mdi:chevron-down" />
|
|
120
127
|
</template>
|
|
121
128
|
<template v-for="(_, key) in serviceData.faqs" :key="`content-${key}`" #[`accordian-${key}-content`]>
|
|
122
|
-
<p>{{ serviceData.faqs[key]?.answer }}</p>
|
|
129
|
+
<p class="services-section__faq-answer">{{ serviceData.faqs[key]?.answer }}</p>
|
|
123
130
|
</template>
|
|
124
131
|
</AccordianCore>
|
|
125
132
|
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
<slot
|
|
134
|
+
v-if="!isSummary"
|
|
135
|
+
name="cta-panel"
|
|
136
|
+
:service-data="serviceData"
|
|
137
|
+
:cta-heading="ctaHeading"
|
|
138
|
+
:cta-body="ctaBody"
|
|
139
|
+
>
|
|
140
|
+
<GlassPanel :style-class-passthrough="['services-section__glass-panel', 'p-24']">
|
|
141
|
+
<HeroText
|
|
142
|
+
tag="h2"
|
|
143
|
+
axis="horizontal"
|
|
144
|
+
font-size="subheading"
|
|
145
|
+
:text-content="[{ text: ctaHeading, styleClass: 'normal' }]"
|
|
146
|
+
:style-class-passthrough="['mbs-0', 'mbe-20']"
|
|
147
|
+
/>
|
|
148
|
+
<p class="page-body-normal">{{ ctaBody }}</p>
|
|
149
|
+
<slot name="cta" :service-data="serviceData"></slot>
|
|
150
|
+
</GlassPanel>
|
|
151
|
+
</slot>
|
|
137
152
|
</div>
|
|
138
153
|
</div>
|
|
139
154
|
</component>
|
|
@@ -152,6 +167,12 @@ interface Props {
|
|
|
152
167
|
reverse?: boolean;
|
|
153
168
|
durationIcon?: string;
|
|
154
169
|
priceIcon?: string;
|
|
170
|
+
processHeading?: string;
|
|
171
|
+
idealForHeading?: string;
|
|
172
|
+
maintenanceHeading?: string;
|
|
173
|
+
faqsHeading?: string;
|
|
174
|
+
ctaHeading?: string;
|
|
175
|
+
ctaBody?: string;
|
|
155
176
|
styleClassPassthrough?: string | string[];
|
|
156
177
|
}
|
|
157
178
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -162,17 +183,23 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
162
183
|
summaryAlignment: "center",
|
|
163
184
|
durationIcon: "mdi:clock-time-four-outline",
|
|
164
185
|
priceIcon: "mdi:currency-gbp",
|
|
186
|
+
processHeading: "The Process",
|
|
187
|
+
idealForHeading: "Ideal For",
|
|
188
|
+
maintenanceHeading: "Aftercare & Maintenance",
|
|
189
|
+
faqsHeading: "Frequently Asked Questions",
|
|
190
|
+
ctaHeading: "Ready to book your appointment?",
|
|
191
|
+
ctaBody: "Get in touch to book your appointment.",
|
|
165
192
|
styleClassPassthrough: () => [],
|
|
166
193
|
});
|
|
167
194
|
|
|
168
|
-
const { ariaLabelledby } = useAriaLabelledById(() => props.tag);
|
|
195
|
+
const { headingId, ariaLabelledby } = useAriaLabelledById(() => props.tag);
|
|
169
196
|
|
|
170
197
|
const infoWrapperClasses = computed(() => {
|
|
171
198
|
return {
|
|
172
|
-
"
|
|
173
|
-
"align-start": props.isSummary && props.summaryAlignment === "start",
|
|
174
|
-
"align-center": props.isSummary && props.summaryAlignment === "center",
|
|
175
|
-
"align-end": props.isSummary && props.summaryAlignment === "end",
|
|
199
|
+
"services-section__info-wrapper--summary": props.isSummary,
|
|
200
|
+
"services-section__info-wrapper--align-start": props.isSummary && props.summaryAlignment === "start",
|
|
201
|
+
"services-section__info-wrapper--align-center": props.isSummary && props.summaryAlignment === "center",
|
|
202
|
+
"services-section__info-wrapper--align-end": props.isSummary && props.summaryAlignment === "end",
|
|
176
203
|
};
|
|
177
204
|
});
|
|
178
205
|
|
|
@@ -199,44 +226,47 @@ watch(
|
|
|
199
226
|
container-name: services-section;
|
|
200
227
|
|
|
201
228
|
.services-section__grid {
|
|
229
|
+
--_grid-gap: var(--services-section-grid-gap, 2rem);
|
|
230
|
+
|
|
202
231
|
display: grid;
|
|
203
232
|
grid-template-columns: 1fr;
|
|
204
|
-
gap:
|
|
233
|
+
gap: var(--_grid-gap);
|
|
205
234
|
|
|
206
235
|
@media (width >= 768px) {
|
|
236
|
+
--_grid-gap: var(--services-section-grid-gap-desktop, 3rem);
|
|
237
|
+
|
|
207
238
|
grid-template-columns: repeat(auto-fit, minmax(446px, 1fr));
|
|
208
|
-
gap: 3rem;
|
|
209
239
|
|
|
210
240
|
&.services-section__grid--reverse {
|
|
211
|
-
.
|
|
212
|
-
/* The order: 2 on .
|
|
241
|
+
.services-section__image-wrapper {
|
|
242
|
+
/* The order: 2 on .services-section__image-wrapper pushes it after the content div, since by default both children have order: 0 and source order wins — so the content div naturally sits first. */
|
|
213
243
|
order: 2;
|
|
214
244
|
}
|
|
215
245
|
}
|
|
216
246
|
}
|
|
217
247
|
|
|
218
|
-
.
|
|
219
|
-
&.
|
|
248
|
+
.services-section__info-wrapper {
|
|
249
|
+
&.services-section__info-wrapper--summary {
|
|
220
250
|
display: grid;
|
|
221
251
|
|
|
222
|
-
&.align-start {
|
|
252
|
+
&.services-section__info-wrapper--align-start {
|
|
223
253
|
align-content: start;
|
|
224
254
|
}
|
|
225
|
-
&.align-center {
|
|
255
|
+
&.services-section__info-wrapper--align-center {
|
|
226
256
|
align-content: center;
|
|
227
257
|
}
|
|
228
|
-
&.align-end {
|
|
258
|
+
&.services-section__info-wrapper--align-end {
|
|
229
259
|
align-content: end;
|
|
230
260
|
}
|
|
231
261
|
}
|
|
232
262
|
}
|
|
233
263
|
|
|
234
|
-
.
|
|
264
|
+
.services-section__image-wrapper {
|
|
235
265
|
align-self: start;
|
|
236
|
-
border-radius:
|
|
266
|
+
border-radius: var(--services-section-image-border-radius, 0.8rem);
|
|
237
267
|
overflow: hidden;
|
|
238
268
|
|
|
239
|
-
.
|
|
269
|
+
.services-section__image {
|
|
240
270
|
display: block;
|
|
241
271
|
width: 100%;
|
|
242
272
|
height: 100%;
|
|
@@ -244,45 +274,38 @@ watch(
|
|
|
244
274
|
}
|
|
245
275
|
}
|
|
246
276
|
|
|
247
|
-
.
|
|
277
|
+
.services-section__price-duration {
|
|
248
278
|
display: flex;
|
|
249
279
|
flex-direction: row;
|
|
250
|
-
gap: 3rem;
|
|
280
|
+
gap: var(--services-section-price-duration-gap, 3rem);
|
|
251
281
|
align-items: center;
|
|
252
|
-
margin-block-end: 2rem;
|
|
282
|
+
margin-block-end: var(--services-section-price-duration-margin-block-end, 2rem);
|
|
253
283
|
|
|
254
284
|
> div {
|
|
255
285
|
display: flex;
|
|
256
286
|
flex-direction: row;
|
|
257
|
-
gap: 0.8rem;
|
|
287
|
+
gap: var(--services-section-price-duration-item-gap, 0.8rem);
|
|
258
288
|
align-items: center;
|
|
259
289
|
|
|
260
|
-
.
|
|
261
|
-
width: 2rem;
|
|
262
|
-
height: 2rem;
|
|
290
|
+
.services-section__decorator {
|
|
291
|
+
width: var(--services-section-decorator-size, 2rem);
|
|
292
|
+
height: var(--services-section-decorator-size, 2rem);
|
|
263
293
|
}
|
|
264
294
|
}
|
|
265
295
|
}
|
|
266
296
|
|
|
267
|
-
.
|
|
268
|
-
|
|
269
|
-
border-radius: 1rem;
|
|
270
|
-
backdrop-filter: blur(10px);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
.services-faq {
|
|
274
|
-
margin-block-end: 24px;
|
|
297
|
+
.services-section__faq {
|
|
298
|
+
margin-block-end: var(--services-section-faq-margin-block-end, 2.4rem);
|
|
275
299
|
|
|
276
300
|
&.display-accordian {
|
|
277
301
|
max-width: none;
|
|
278
|
-
/* margin: 0; */
|
|
279
302
|
|
|
280
303
|
.accordian-item.expanding-panel {
|
|
281
|
-
border-block-end: 1px solid currentColor;
|
|
282
|
-
opacity: 0.7;
|
|
304
|
+
border-block-end: 1px solid var(--services-section-faq-divider-color, currentColor);
|
|
305
|
+
opacity: var(--services-section-faq-divider-opacity, 0.7);
|
|
283
306
|
|
|
284
307
|
&:first-child {
|
|
285
|
-
border-block-start: 1px solid currentColor;
|
|
308
|
+
border-block-start: 1px solid var(--services-section-faq-divider-color, currentColor);
|
|
286
309
|
}
|
|
287
310
|
|
|
288
311
|
.expanding-panel-details .expanding-panel-summary {
|
|
@@ -290,7 +313,9 @@ watch(
|
|
|
290
313
|
}
|
|
291
314
|
|
|
292
315
|
.expanding-panel-content .inner {
|
|
293
|
-
|
|
316
|
+
.services-section__faq-answer {
|
|
317
|
+
line-height: var(--services-section-faq-answer-line-height, 1.6);
|
|
318
|
+
}
|
|
294
319
|
}
|
|
295
320
|
}
|
|
296
321
|
}
|