@port60/template-kit 0.3.0 → 0.4.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@port60/template-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Build Port60 site templates locally: scaffold, live-preview, validate against the platform contract, and package for studio upload. AI-agent ready — every scaffold ships AGENTS.md and validate emits machine-readable JSON.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -223,6 +223,16 @@
|
|
|
223
223
|
"required": false,
|
|
224
224
|
"description": "Background photograph for the hero (uploaded through the platform pipeline). Superseded by `images` when that carries any entry — render imageUrl only when images is absent/empty. The template must TREAT the photo (scrim/tint from its own palette variables), never place it raw, and omit for its designed no-photo state."
|
|
225
225
|
},
|
|
226
|
+
{
|
|
227
|
+
"name": "photoFraming",
|
|
228
|
+
"kind": "select",
|
|
229
|
+
"required": false,
|
|
230
|
+
"options": [
|
|
231
|
+
"fill",
|
|
232
|
+
"whole"
|
|
233
|
+
],
|
|
234
|
+
"description": "How hero photographs meet the hero. 'fill' (default): the hero keeps its designed shape and photos crop to fill it (use each photo's focus to pick the surviving slice). 'whole': the hero adapts toward the photo's own shape (height-clamped) so the FULL scene stays visible — the vista treatment for wide landscape photographs; templates overlay or stack their copy accordingly."
|
|
235
|
+
},
|
|
226
236
|
{
|
|
227
237
|
"name": "images",
|
|
228
238
|
"kind": "items",
|
package/starter/assets/theme.css
CHANGED
|
@@ -113,3 +113,42 @@ body { font-family: ' IBM Plex Sans Arabic', var(--p60s-siteFont, 'Inter'), ui-s
|
|
|
113
113
|
cursor: pointer;
|
|
114
114
|
}
|
|
115
115
|
.lq-homehero--carousel .hero-dot--active { background: var(--accent); }
|
|
116
|
+
|
|
117
|
+
/* ── Vista framing (photoFraming 'whole') — the hero adapts to the PHOTO's shape ───────────── */
|
|
118
|
+
.lq-homehero--vista { padding-top: 0; }
|
|
119
|
+
.lq-vista { position: relative; overflow: hidden; }
|
|
120
|
+
.lq-vista-sizer { display: block; width: 100%; height: auto; max-height: 74vh; object-fit: cover; }
|
|
121
|
+
.lq-vista-scrim,
|
|
122
|
+
.lq-homehero--vista .hero-slide-scrim {
|
|
123
|
+
position: absolute;
|
|
124
|
+
inset: 0;
|
|
125
|
+
pointer-events: none;
|
|
126
|
+
background: linear-gradient(
|
|
127
|
+
180deg,
|
|
128
|
+
color-mix(in srgb, var(--bg) 45%, transparent) 0%,
|
|
129
|
+
color-mix(in srgb, var(--bg) 12%, transparent) 40%,
|
|
130
|
+
color-mix(in srgb, var(--bg-tint) 60%, transparent) 100%
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
.lq-homehero--vista .lq-homehero-inner { padding-top: 2.4rem; }
|
|
134
|
+
.lq-homehero--vista .hero-carousel { position: absolute; inset: 0; z-index: 0; }
|
|
135
|
+
|
|
136
|
+
/* Vista 1.5.1: copy ON the photograph (strengthened lower scrim); the widget follows in its
|
|
137
|
+
own strip; narrow screens flow the copy back underneath. */
|
|
138
|
+
.lq-vista-copy { position: absolute; inset-inline: 0; bottom: 0; padding: 1.4rem 0 2rem; z-index: 1; }
|
|
139
|
+
.lq-homehero--vista .lq-vista-scrim,
|
|
140
|
+
.lq-homehero--vista .hero-slide-scrim {
|
|
141
|
+
background: linear-gradient(
|
|
142
|
+
180deg,
|
|
143
|
+
color-mix(in srgb, var(--bg) 38%, transparent) 0%,
|
|
144
|
+
color-mix(in srgb, var(--bg) 10%, transparent) 38%,
|
|
145
|
+
color-mix(in srgb, var(--bg-tint) 82%, transparent) 100%
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
.lq-vista-sizer { min-height: 280px; }
|
|
149
|
+
.lq-vista-widget { padding: 2.2rem 0 0; display: flex; justify-content: center; }
|
|
150
|
+
.lq-vista-widget aside { width: min(560px, 100%); }
|
|
151
|
+
@media (max-width: 720px) {
|
|
152
|
+
.lq-vista-copy { position: static; padding: 1.8rem 0 0; }
|
|
153
|
+
.lq-vista-sizer { min-height: 160px; }
|
|
154
|
+
}
|
package/starter/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "starter",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"format": "port60-liquid@1",
|
|
5
5
|
"label": "Starter",
|
|
6
6
|
"description": "The reference template for the Port60 dialect — the developer docs' worked example and the base to copy when building your own. 1.1.0 adds the layout slot: the template owns the header, navigation and footer chrome.",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
}
|
|
41
41
|
]
|
|
42
42
|
},
|
|
43
|
-
"changelog": "
|
|
43
|
+
"changelog": "Vista polish: your headline and buttons now sit ON the photograph (the treatment keeps them readable) instead of stacking below it — the hero no longer doubles in height."
|
|
44
44
|
}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
{% comment %}
|
|
2
|
-
The home opener — and the REFERENCE IMPLEMENTATION of supports.heroImagery.
|
|
2
|
+
The home opener — and the REFERENCE IMPLEMENTATION of supports.heroImagery. Rules worth
|
|
3
3
|
copying:
|
|
4
4
|
|
|
5
5
|
1. EVERY field is optional. Copy derives from brand (| default) or omits; no photos means the
|
|
6
6
|
designed gradient below — never a placeholder image.
|
|
7
|
-
2. Photos are NEVER placed raw. The
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
3.
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
2. Photos are NEVER placed raw. The treatments in theme.css lay scrims built from the palette
|
|
8
|
+
variables (color-mix over var(--bg)/var(--bg-tint)), so any uploaded photograph is toned
|
|
9
|
+
into the template. Tune the treatment, don't remove it.
|
|
10
|
+
3. Rotation is the PLATFORM's hero_carousel island (templates ship no JavaScript): with two or
|
|
11
|
+
more photos, place it and style its documented classes.
|
|
12
|
+
4. photoFraming is the charity's call, honour BOTH: 'fill' (default) covers your designed hero
|
|
13
|
+
shape (per-photo focus picks the surviving slice); 'whole' is the VISTA — the hero adapts
|
|
14
|
+
toward the photo's own shape (height-clamped) so a wide landscape stays entirely visible,
|
|
15
|
+
with your copy stacked after the band.
|
|
13
16
|
{% endcomment %}
|
|
14
17
|
{% assign heroCount = section.images | size %}
|
|
15
18
|
{% if heroCount == 1 %}
|
|
@@ -26,6 +29,37 @@
|
|
|
26
29
|
{% when 'right' %}{% assign heroFocus = 'right center' %}
|
|
27
30
|
{% endcase %}
|
|
28
31
|
{% endif %}
|
|
32
|
+
{% assign heroFraming = section.photoFraming | default: 'fill' %}
|
|
33
|
+
{% if heroCount > 0 and heroFraming == 'whole' %}
|
|
34
|
+
<section class="lq-homehero lq-homehero--vista{% if heroCount > 1 %} lq-homehero--carousel{% endif %}">
|
|
35
|
+
<div class="lq-vista">
|
|
36
|
+
<img class="lq-vista-sizer" src="{{ section.images.first.imageUrl }}" alt="{{ section.images.first.alt }}" style="object-position: {{ heroFocus }}" fetchpriority="high" decoding="async">
|
|
37
|
+
{% if heroCount > 1 %}{% island 'hero_carousel' %}{% else %}<div class="lq-vista-scrim" aria-hidden="true"></div>{% endif %}
|
|
38
|
+
<div class="lq-vista-copy">
|
|
39
|
+
<div class="container">
|
|
40
|
+
<p class="lq-kicker">{{ section.eyebrow | default: brand.name }}</p>
|
|
41
|
+
<h1>{{ section.title | default: brand.tagline | default: brand.name }}</h1>
|
|
42
|
+
{% if section.lead %}<p class="lq-homehero-lead">{{ section.lead }}</p>{% endif %}
|
|
43
|
+
<div class="lq-homehero-actions">
|
|
44
|
+
{% if section.givingStyle == 'button' %}
|
|
45
|
+
<a class="button button-primary" href="{{ section.primaryHref | default: '/donate' }}">{{ section.primaryLabel | default: 'Donate now' }}</a>
|
|
46
|
+
{% else %}
|
|
47
|
+
<a class="button button-primary" href="#donate">{{ section.primaryLabel | default: 'Donate now' }}</a>
|
|
48
|
+
{% endif %}
|
|
49
|
+
<a class="button" href="{{ section.secondaryHref | default: '/about' }}">{{ section.secondaryLabel | default: 'Our story' }}</a>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
{% unless section.givingStyle == 'button' %}
|
|
55
|
+
<div class="container lq-vista-widget">
|
|
56
|
+
<aside id="donate">
|
|
57
|
+
{% island 'donation_widget' %}
|
|
58
|
+
</aside>
|
|
59
|
+
</div>
|
|
60
|
+
{% endunless %}
|
|
61
|
+
</section>
|
|
62
|
+
{% else %}
|
|
29
63
|
<section class="lq-homehero{% if heroPhoto %} lq-homehero--photo{% endif %}{% if heroCount > 1 %} lq-homehero--carousel{% endif %}"{% if heroPhoto %} style="background-image: url('{{ heroPhoto }}'); background-position: {{ heroFocus }}"{% endif %}>
|
|
30
64
|
{% if heroCount > 1 %}{% island 'hero_carousel' %}{% endif %}
|
|
31
65
|
<div class="container lq-homehero-inner">
|
|
@@ -49,3 +83,4 @@
|
|
|
49
83
|
{% endunless %}
|
|
50
84
|
</div>
|
|
51
85
|
</section>
|
|
86
|
+
{% endif %}
|