updates to new sections and design system page
This commit is contained in:
1
dist/assets/About--uXlb06p.js
vendored
Normal file
1
dist/assets/About--uXlb06p.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{C as e,T as t,c as n,j as r,l as i,lt as a,p as o,r as s,s as c,st as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./_plugin-vue_export-helper-BOai-rQB.js";import{t as f}from"./Badge-DcvgVKep.js";var p={id:`about`,class:`bg-cream text-ink`},m={class:`mx-auto w-full max-w-6xl px-6 py-16 sm:px-8 sm:py-20 md:px-12 md:py-24 lg:px-16 lg:py-28`},h={class:`flex flex-col items-center text-center gap-4 max-w-3xl mx-auto`},g={key:1,class:`font-display font-normal leading-[1.05] tracking-tight text-ink`,style:{"font-size":`clamp(2.25rem, 5vw, 3.75rem)`}},_={key:2,class:`text-lg leading-relaxed text-muted max-w-2xl`},v={key:0,class:`timeline-track hidden md:grid md:grid-cols-3 mt-16`,"aria-hidden":`true`},y={key:1,class:`timeline-list mt-6 md:mt-8 grid gap-0 md:gap-6 md:grid-cols-3`},b={class:`timeline-mobile-marker`},x=d({__name:`About`,props:{eyebrow:{type:String,default:``},headline:{type:String,default:``},sub:{type:String,default:``},milestones:{type:Array,default:()=>[],validator:e=>e.every(e=>e&&typeof e==`object`&&typeof e.year==`string`&&typeof e.title==`string`&&typeof e.text==`string`)}},setup(d){let x=[{card:`bg-cream border-line`,title:`text-ink`,body:`text-muted`,pill:`pill-paper`},{card:`bg-paper border-line`,title:`text-ink`,body:`text-muted`,pill:`pill-brand-soft`},{card:`bg-brand border-transparent`,title:`text-cream`,body:`text-cream/80`,pill:`pill-accent`}];return(S,C)=>(e(),u(`section`,p,[c(`div`,m,[c(`div`,h,[d.eyebrow?(e(),n(f,{key:0,variant:`brand`},{default:r(()=>[o(a(d.eyebrow),1)]),_:1})):i(``,!0),d.headline?(e(),u(`h2`,g,a(d.headline),1)):i(``,!0),d.sub?(e(),u(`p`,_,a(d.sub),1)):i(``,!0)]),d.milestones.length?(e(),u(`div`,v,[(e(!0),u(s,null,t(d.milestones.slice(0,3),(t,n)=>(e(),u(`div`,{key:`track-`+n,class:`timeline-cell`},[c(`span`,{class:l([`timeline-pill`,x[n].pill])},a(t.year),3)]))),128))])):i(``,!0),d.milestones.length?(e(),u(`ol`,y,[(e(!0),u(s,null,t(d.milestones.slice(0,3),(t,n)=>(e(),u(`li`,{key:t.year+t.title,class:`timeline-item flex flex-col`},[c(`div`,b,[c(`span`,{class:l([`timeline-pill`,x[n].pill])},a(t.year),3)]),c(`div`,{class:l([`flex flex-col gap-3 rounded-md border p-6 md:p-7`,x[n].card])},[c(`h3`,{class:l([`font-display text-2xl font-normal leading-tight`,x[n].title])},a(t.title),3),c(`p`,{class:l([`text-sm leading-relaxed`,x[n].body])},a(t.text),3)],2)]))),128))])):i(``,!0)])]))}},[[`__scopeId`,`data-v-39877af8`]]);export{x as t};
|
||||
1
dist/assets/About-C5UZrRYy.css
vendored
Normal file
1
dist/assets/About-C5UZrRYy.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.timeline-pill[data-v-39877af8]{border-radius:var(--radius-pill);font-family:var(--font-sans);letter-spacing:var(--tracking-eyebrow);text-transform:uppercase;white-space:nowrap;z-index:1;border:1px solid #0000;justify-content:center;align-items:center;padding:.375rem .875rem;font-size:.75rem;font-weight:700;display:inline-flex;position:relative}.pill-paper[data-v-39877af8]{background:var(--color-paper);color:var(--color-brand);border-color:var(--color-line-strong)}.pill-brand-soft[data-v-39877af8]{background:color-mix(in srgb, var(--color-brand) 14%, var(--color-cream));color:var(--color-brand);border-color:color-mix(in srgb, var(--color-brand) 28%, transparent)}.pill-accent[data-v-39877af8]{background:var(--color-accent);color:var(--color-brand);border-color:color-mix(in srgb, var(--color-accent) 70%, var(--color-brand))}.timeline-track[data-v-39877af8]{align-items:center;margin-bottom:.5rem;position:relative}.timeline-track[data-v-39877af8]:before{content:"";background:var(--color-line-strong);height:1px;position:absolute;top:50%;left:16.6667%;right:16.6667%;transform:translateY(-.5px)}.timeline-cell[data-v-39877af8]{justify-content:center;display:flex}@media (width<=767px){.timeline-mobile-marker[data-v-39877af8]{justify-content:center;align-items:center;padding:1.75rem 0;display:flex;position:relative}.timeline-mobile-marker[data-v-39877af8]:before{content:"";background:var(--color-line-strong);width:1px;position:absolute;top:0;bottom:50%;left:50%;transform:translate(-.5px)}.timeline-mobile-marker[data-v-39877af8]:after{content:"";background:var(--color-line-strong);width:1px;position:absolute;top:50%;bottom:0;left:50%;transform:translate(-.5px)}.timeline-item:first-child .timeline-mobile-marker[data-v-39877af8]:before{display:none}}@media (width>=768px){.timeline-mobile-marker[data-v-39877af8]{display:none}}
|
||||
1
dist/assets/About-CtiMkkHe.js
vendored
1
dist/assets/About-CtiMkkHe.js
vendored
@@ -1 +0,0 @@
|
||||
import{C as e,T as t,c as n,j as r,l as i,lt as a,p as o,r as s,s as c,st as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./Badge-DcvgVKep.js";var f={id:`about`,class:`bg-cream text-ink`},p={class:`mx-auto w-full max-w-6xl px-6 py-16 sm:px-8 sm:py-20 md:px-12 md:py-24 lg:px-16 lg:py-28`},m={class:`flex flex-col items-center text-center gap-4 max-w-3xl mx-auto`},h={key:1,class:`font-display font-normal leading-[1.05] tracking-tight text-ink`,style:{"font-size":`clamp(2.25rem, 5vw, 3.75rem)`}},g={key:2,class:`text-lg leading-relaxed text-muted max-w-2xl`},_={key:0,class:`mt-10 md:mt-16 grid gap-5 md:grid-cols-3 md:gap-6`},v={__name:`About`,props:{eyebrow:{type:String,default:``},headline:{type:String,default:``},sub:{type:String,default:``},milestones:{type:Array,default:()=>[],validator:e=>e.every(e=>e&&typeof e==`object`&&typeof e.year==`string`&&typeof e.title==`string`&&typeof e.text==`string`)}},setup(v){let y=[{card:`bg-cream border-line`,year:`text-muted`,title:`text-ink`,body:`text-muted`},{card:`bg-paper border-line`,year:`text-muted`,title:`text-ink`,body:`text-muted`},{card:`bg-brand border-transparent`,year:`text-accent`,title:`text-cream`,body:`text-cream/80`}];return(b,x)=>(e(),u(`section`,f,[c(`div`,p,[c(`div`,m,[v.eyebrow?(e(),n(d,{key:0,variant:`brand`},{default:r(()=>[o(a(v.eyebrow),1)]),_:1})):i(``,!0),v.headline?(e(),u(`h2`,h,a(v.headline),1)):i(``,!0),v.sub?(e(),u(`p`,g,a(v.sub),1)):i(``,!0)]),v.milestones.length?(e(),u(`ol`,_,[(e(!0),u(s,null,t(v.milestones.slice(0,3),(t,n)=>(e(),u(`li`,{key:t.year+t.title,class:l([`flex flex-col gap-3 rounded-md border p-6 md:p-7`,y[n].card])},[c(`span`,{class:l([`text-xs tracking-label uppercase`,y[n].year])},a(t.year),3),c(`h3`,{class:l([`font-display text-2xl font-normal leading-tight`,y[n].title])},a(t.title),3),c(`p`,{class:l([`text-sm leading-relaxed`,y[n].body])},a(t.text),3)],2))),128))])):i(``,!0)])]))}};export{v as t};
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as a}from"./i18n-DrTQks20.js";import{t as o}from"./About-CtiMkkHe.js";var s={class:`min-h-screen bg-cream`},c={__name:`AboutPreview`,setup(c){let{t:l}=a(),u=r(()=>[1,2,3].map(e=>({year:l(`about.milestone.${e}.year`),title:l(`about.milestone.${e}.title`),text:l(`about.milestone.${e}.text`)})));return(r,a)=>(e(),i(`div`,s,[n(o,{eyebrow:t(l)(`about.eyebrow`),headline:t(l)(`about.headline`),sub:t(l)(`about.sub`),milestones:u.value},null,8,[`eyebrow`,`headline`,`sub`,`milestones`])]))}};export{c as default};
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as a}from"./i18n-DrTQks20.js";import{t as o}from"./About--uXlb06p.js";var s={class:`min-h-screen bg-cream`},c={__name:`AboutPreview`,setup(c){let{t:l}=a(),u=r(()=>[1,2,3].map(e=>({year:l(`about.milestone.${e}.year`),title:l(`about.milestone.${e}.title`),text:l(`about.milestone.${e}.text`)})));return(r,a)=>(e(),i(`div`,s,[n(o,{eyebrow:t(l)(`about.eyebrow`),headline:t(l)(`about.headline`),sub:t(l)(`about.sub`),milestones:u.value},null,8,[`eyebrow`,`headline`,`sub`,`milestones`])]))}};export{c as default};
|
||||
1
dist/assets/HomePage-0lVLpvRJ.js
vendored
1
dist/assets/HomePage-0lVLpvRJ.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/HomePage-B6MK_toM.js
vendored
Normal file
1
dist/assets/HomePage-B6MK_toM.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as a}from"./i18n-DrTQks20.js";import{t as o}from"./Revitalization-Dbf9J8TA.js";var s={class:`min-h-screen bg-brand`},c={__name:`RevitalizationPreview`,setup(c){let{t:l}=a(),u=r(()=>[l(`revit.feature.1.title`),l(`revit.feature.2.title`),l(`revit.feature.3.title`)]);return(r,a)=>(e(),i(`div`,s,[n(o,{eyebrow:t(l)(`revit.eyebrow`),headline:t(l)(`revit.headline.a`),"headline-em":t(l)(`revit.headline.em`),sub:t(l)(`revit.sub`),features:u.value,"notify-cta":t(l)(`revit.notifyCta`)},null,8,[`eyebrow`,`headline`,`headline-em`,`sub`,`features`,`notify-cta`])]))}};export{c as default};
|
||||
1
dist/assets/RevitalizationPreview-Cg7aOLyy.js
vendored
Normal file
1
dist/assets/RevitalizationPreview-Cg7aOLyy.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as a}from"./i18n-DrTQks20.js";import{t as o}from"./Revitalization-Dbf9J8TA.js";var s={class:`min-h-screen bg-brand`},c={__name:`RevitalizationPreview`,setup(c){let{t:l}=a(),u=r(()=>[{title:l(`revit.feature.1.title`),icon:`⚗️`},{title:l(`revit.feature.2.title`),icon:`💊`},{title:l(`revit.feature.3.title`),icon:`🌿`}]);return(r,a)=>(e(),i(`div`,s,[n(o,{eyebrow:t(l)(`revit.eyebrow`),headline:t(l)(`revit.headline.a`),"headline-em":t(l)(`revit.headline.em`),sub:t(l)(`revit.sub`),features:u.value,"notify-cta":t(l)(`revit.notifyCta`)},null,8,[`eyebrow`,`headline`,`headline-em`,`sub`,`features`,`notify-cta`])]))}};export{c as default};
|
||||
@@ -4,9 +4,9 @@ import{C as e,G as t,c as n,j as r,lt as i,m as a,s as o}from"./runtime-core.esm
|
||||
:headline-em="t('revit.headline.em')"
|
||||
:sub="t('revit.sub')"
|
||||
:features="[
|
||||
t('revit.feature.1.title'),
|
||||
t('revit.feature.2.title'),
|
||||
t('revit.feature.3.title'),
|
||||
{ title: t('revit.feature.1.title'), icon: '⚗️' },
|
||||
{ title: t('revit.feature.2.title'), icon: '💊' },
|
||||
{ title: t('revit.feature.3.title'), icon: '🌿' },
|
||||
]"
|
||||
:notify-cta="t('revit.notifyCta')"
|
||||
@notify="captureEmail()"
|
||||
1
dist/assets/index-C8HKZcXS.css
vendored
1
dist/assets/index-C8HKZcXS.css
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/index-CMSTRSqf.css
vendored
Normal file
1
dist/assets/index-CMSTRSqf.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
dist/index.html
vendored
4
dist/index.html
vendored
@@ -12,13 +12,13 @@
|
||||
href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,200;0,9..144,400;0,9..144,600;0,9..144,700;1,9..144,200;1,9..144,400;1,9..144,600&family=DM+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script type="module" crossorigin src="/assets/index-CClpXQy1.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-x_BEHWZf.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-BOai-rQB.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/runtime-core.esm-bundler-BD0e4RlP.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/runtime-dom.esm-bundler-CcSFQHoC.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pinia-DQoUg3qR.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-router-QRVDVSxc.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-C8HKZcXS.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CMSTRSqf.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -24,9 +24,16 @@ body {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Room above anchor targets when scrolling */
|
||||
/* Room above anchor targets when scrolling — must clear the sticky
|
||||
navbar. The navbar is taller on md+ (logo scales up), so the value
|
||||
bumps up at the md breakpoint. */
|
||||
[id] {
|
||||
scroll-margin-top: 2rem;
|
||||
scroll-margin-top: 5.5rem;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
[id] {
|
||||
scroll-margin-top: 7rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Typography helpers */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import Badge from './Badge.vue'
|
||||
|
||||
/**
|
||||
* About — a centered intro + three-up milestone gallery.
|
||||
* About — a centered intro + milestone timeline.
|
||||
*
|
||||
* Content is supplied entirely via props. Milestones are expected as an
|
||||
* array of `{ year, title, text }` entries; extras past the third are
|
||||
@@ -11,6 +11,11 @@ import Badge from './Badge.vue'
|
||||
* The three cards cycle the Card primitive's tones left-to-right —
|
||||
* paper / cream / brand — so the row echoes the design system's three
|
||||
* canonical surfaces rather than repeating a single tone.
|
||||
*
|
||||
* Timeline shape: pill-line-pill-line-pill. Horizontal above the cards
|
||||
* on md+ (each pill centered above its card, connected by a hairline),
|
||||
* vertical between pills on mobile (short line segments above every
|
||||
* non-first pill so the column reads as one continuous track).
|
||||
*/
|
||||
defineProps({
|
||||
eyebrow: { type: String, default: '' },
|
||||
@@ -38,21 +43,28 @@ defineProps({
|
||||
const CARD_TONES = [
|
||||
{
|
||||
card: 'bg-cream border-line',
|
||||
year: 'text-muted',
|
||||
title: 'text-ink',
|
||||
body: 'text-muted',
|
||||
// Milestone-1 pill: cream card is the section's baseline tone, so
|
||||
// the pill uses the paper surface + brand ink to punch against it.
|
||||
pill: 'pill-paper',
|
||||
},
|
||||
{
|
||||
card: 'bg-paper border-line',
|
||||
year: 'text-muted',
|
||||
title: 'text-ink',
|
||||
body: 'text-muted',
|
||||
// Milestone-2 pill: paper card is bright, so the pill inverts to
|
||||
// the brand-soft wash with brand ink for a calmer contrast.
|
||||
pill: 'pill-brand-soft',
|
||||
},
|
||||
{
|
||||
card: 'bg-brand border-transparent',
|
||||
year: 'text-accent',
|
||||
title: 'text-cream',
|
||||
body: 'text-cream/80',
|
||||
// Milestone-3 pill: brand card is dark green, so the pill lifts
|
||||
// to accent (warm yellow) on brand ink — the strongest stop on
|
||||
// the timeline, matching the climactic "Heute" milestone.
|
||||
pill: 'pill-accent',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
@@ -74,35 +86,178 @@ const CARD_TONES = [
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Three timeline milestones. Stacks on mobile; three columns from
|
||||
md up, each rendered as a paper card so the cream section reads
|
||||
as a gallery rather than a flat list. -->
|
||||
<!-- Desktop-only horizontal timeline track. Rendered as its own row
|
||||
above the cards (hidden on mobile), so the pill ↔ card vertical
|
||||
pairing stays clean and we don't have to juggle two layouts in
|
||||
one grid. Track line is a pseudo-element inset from both edges
|
||||
so it terminates at the outer pills. -->
|
||||
<div
|
||||
v-if="milestones.length"
|
||||
class="timeline-track hidden md:grid md:grid-cols-3 mt-16"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div
|
||||
v-for="(milestone, i) in milestones.slice(0, 3)"
|
||||
:key="'track-' + i"
|
||||
class="timeline-cell"
|
||||
>
|
||||
<span :class="['timeline-pill', CARD_TONES[i].pill]">{{ milestone.year }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Three timeline milestones. On mobile each card is preceded by
|
||||
its own pill (with a short connecting line above every
|
||||
non-first pill) so the column reads as one continuous
|
||||
timeline. On md+ the pill is hidden here because the
|
||||
horizontal track above already covers it. -->
|
||||
<ol
|
||||
v-if="milestones.length"
|
||||
class="mt-10 md:mt-16 grid gap-5 md:grid-cols-3 md:gap-6"
|
||||
class="timeline-list mt-6 md:mt-8 grid gap-0 md:gap-6 md:grid-cols-3"
|
||||
>
|
||||
<li
|
||||
v-for="(milestone, i) in milestones.slice(0, 3)"
|
||||
:key="milestone.year + milestone.title"
|
||||
:class="[
|
||||
'flex flex-col gap-3 rounded-md border p-6 md:p-7',
|
||||
CARD_TONES[i].card,
|
||||
]"
|
||||
class="timeline-item flex flex-col"
|
||||
>
|
||||
<span :class="['text-xs tracking-label uppercase', CARD_TONES[i].year]">
|
||||
{{ milestone.year }}
|
||||
</span>
|
||||
<h3
|
||||
<div class="timeline-mobile-marker">
|
||||
<span :class="['timeline-pill', CARD_TONES[i].pill]">{{ milestone.year }}</span>
|
||||
</div>
|
||||
<div
|
||||
:class="[
|
||||
'font-display text-2xl font-normal leading-tight',
|
||||
CARD_TONES[i].title,
|
||||
'flex flex-col gap-3 rounded-md border p-6 md:p-7',
|
||||
CARD_TONES[i].card,
|
||||
]"
|
||||
>{{ milestone.title }}</h3>
|
||||
<p :class="['text-sm leading-relaxed', CARD_TONES[i].body]">
|
||||
{{ milestone.text }}
|
||||
</p>
|
||||
>
|
||||
<h3
|
||||
:class="[
|
||||
'font-display text-2xl font-normal leading-tight',
|
||||
CARD_TONES[i].title,
|
||||
]"
|
||||
>{{ milestone.title }}</h3>
|
||||
<p :class="['text-sm leading-relaxed', CARD_TONES[i].body]">
|
||||
{{ milestone.text }}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Shared pill — typography and shape are constant across viewports
|
||||
so the horizontal and vertical renders read as one component.
|
||||
Per-card tones below paint the surface, ink, and border so each
|
||||
pill complements its sibling card. `position: relative; z-index:1`
|
||||
lifts the pill above the connecting line so the pill's background
|
||||
visually punches a hole in the timeline. */
|
||||
.timeline-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.375rem 0.875rem;
|
||||
border-radius: var(--radius-pill);
|
||||
border: 1px solid transparent;
|
||||
font-family: var(--font-sans);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: var(--tracking-eyebrow);
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Per-card pill tones. Background must be opaque so the pill masks
|
||||
the connecting line behind it. */
|
||||
.pill-paper {
|
||||
background: var(--color-paper);
|
||||
color: var(--color-brand);
|
||||
border-color: var(--color-line-strong);
|
||||
}
|
||||
.pill-brand-soft {
|
||||
background: color-mix(in srgb, var(--color-brand) 14%, var(--color-cream));
|
||||
color: var(--color-brand);
|
||||
border-color: color-mix(in srgb, var(--color-brand) 28%, transparent);
|
||||
}
|
||||
.pill-accent {
|
||||
background: var(--color-accent);
|
||||
color: var(--color-brand);
|
||||
border-color: color-mix(in srgb, var(--color-accent) 70%, var(--color-brand));
|
||||
}
|
||||
|
||||
/* ——— Desktop: horizontal pill-line-pill track ———————————— */
|
||||
/* Layout (display: grid) lives on the Tailwind utilities (`hidden
|
||||
md:grid md:grid-cols-3`) so we never set `display` here — that
|
||||
would beat the responsive `hidden` utility on mobile. */
|
||||
.timeline-track {
|
||||
position: relative;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
/* Hairline that runs under the pills. Inset to the column centers
|
||||
so the line terminates at the outer pills rather than bleeding
|
||||
past the grid. Percentages assume three equal columns. */
|
||||
.timeline-track::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 16.6667%;
|
||||
right: 16.6667%;
|
||||
top: 50%;
|
||||
height: 1px;
|
||||
background: var(--color-line-strong);
|
||||
transform: translateY(-0.5px);
|
||||
}
|
||||
.timeline-cell {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ——— Mobile: vertical pill-line-pill with cards interleaved ———
|
||||
Wrapped in a max-width media query so the mobile marker is fully
|
||||
removed from the layout on md+. (Scoped-style specificity beats
|
||||
Tailwind utilities here, so a `md:hidden` class would not be
|
||||
enough on its own.) */
|
||||
@media (max-width: 767px) {
|
||||
.timeline-mobile-marker {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1.75rem 0;
|
||||
position: relative;
|
||||
}
|
||||
/* Line above pill — spans the full top padding so it visually
|
||||
meets the card above. Suppressed on the first marker (start
|
||||
of the track). */
|
||||
.timeline-mobile-marker::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 50%;
|
||||
left: 50%;
|
||||
width: 1px;
|
||||
transform: translateX(-0.5px);
|
||||
background: var(--color-line-strong);
|
||||
}
|
||||
/* Line below pill — spans the bottom padding down to the next
|
||||
card so the pill feels threaded onto a continuous track. */
|
||||
.timeline-mobile-marker::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
width: 1px;
|
||||
transform: translateX(-0.5px);
|
||||
background: var(--color-line-strong);
|
||||
}
|
||||
.timeline-item:first-child .timeline-mobile-marker::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.timeline-mobile-marker {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -187,24 +187,24 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- First fold — on md+ the wrapper is exactly one viewport tall and the
|
||||
centering row below the navbar vertically centres the hero inside
|
||||
the remaining space. On mobile the Hero's stacked split layout
|
||||
(image + copy + CTAs) is taller than a phone viewport, so we drop
|
||||
the height cap and let the section flow at its natural height;
|
||||
otherwise `overflow-hidden` clips the CTAs, which is what the
|
||||
mobile screenshot showed. -->
|
||||
<div class="flex flex-col bg-brand md:h-svh md:overflow-hidden">
|
||||
<Navbar
|
||||
variant="brand"
|
||||
layout="standard"
|
||||
:items="navItems"
|
||||
:cart-count="cart.count"
|
||||
:products="products"
|
||||
@cart="cartOpen = true"
|
||||
@search="onSearchSelect"
|
||||
/>
|
||||
|
||||
<!-- First fold — the navbar lives OUTSIDE the fold wrapper so its
|
||||
`position: sticky` escapes the wrapper's containing block and
|
||||
sticks to the document scroll instead. Previously the wrapper
|
||||
had `md:overflow-hidden`, which made the browser treat the
|
||||
wrapper as sticky's scrollport — the navbar scrolled away with
|
||||
it. The wrapper is now `md:min-h-svh` (no overflow clip), so
|
||||
the hero still fills the viewport on md+ without trapping
|
||||
sticky. -->
|
||||
<Navbar
|
||||
variant="brand"
|
||||
layout="standard"
|
||||
:items="navItems"
|
||||
:cart-count="cart.count"
|
||||
:products="products"
|
||||
@cart="cartOpen = true"
|
||||
@search="onSearchSelect"
|
||||
/>
|
||||
<div class="flex flex-col bg-brand md:min-h-svh">
|
||||
<div class="md:flex-1 md:flex md:items-center">
|
||||
<Hero
|
||||
class="w-full"
|
||||
|
||||
@@ -27,9 +27,9 @@ const src = '/design/preview/revitalization'
|
||||
:headline-em="t('revit.headline.em')"
|
||||
:sub="t('revit.sub')"
|
||||
:features="[
|
||||
t('revit.feature.1.title'),
|
||||
t('revit.feature.2.title'),
|
||||
t('revit.feature.3.title'),
|
||||
{ title: t('revit.feature.1.title'), icon: '⚗️' },
|
||||
{ title: t('revit.feature.2.title'), icon: '💊' },
|
||||
{ title: t('revit.feature.3.title'), icon: '🌿' },
|
||||
]"
|
||||
:notify-cta="t('revit.notifyCta')"
|
||||
@notify="captureEmail()"
|
||||
|
||||
@@ -6,9 +6,9 @@ import { useI18n } from '@/i18n/index.js'
|
||||
const { t } = useI18n()
|
||||
|
||||
const features = computed(() => [
|
||||
t('revit.feature.1.title'),
|
||||
t('revit.feature.2.title'),
|
||||
t('revit.feature.3.title'),
|
||||
{ title: t('revit.feature.1.title'), icon: '⚗️' },
|
||||
{ title: t('revit.feature.2.title'), icon: '💊' },
|
||||
{ title: t('revit.feature.3.title'), icon: '🌿' },
|
||||
])
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user