@port60/template-kit 0.8.0 → 0.10.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/README.md +10 -3
- package/bin/cli.mjs +26 -4
- package/package.json +1 -1
- package/src/commands/content.mjs +42 -0
- package/src/commands/create.mjs +10 -7
- package/src/commands/dev.mjs +134 -8
- package/src/commands/model.mjs +34 -0
- package/src/commands/packageCmd.mjs +3 -3
- package/src/commands/refresh.mjs +48 -0
- package/src/commands/upgrade.mjs +44 -0
- package/src/commands/validate.mjs +2 -3
- package/src/lib/agentsMd.mjs +78 -21
- package/src/vendor/contract/v1/behaviours.json +129 -0
- package/src/vendor/contract/v1/content-bounds.json +3 -3
- package/src/vendor/contract/v1/content-model.json +193 -0
- package/src/vendor/contract/v1/context.json +1985 -141
- package/src/vendor/contract/v1/dialect.json +3 -3
- package/src/vendor/contract/v1/fonts.json +1 -1
- package/src/vendor/contract/v1/imagery.json +4 -4
- package/src/vendor/contract/v1/islands.json +256 -110
- package/src/vendor/contract/v1/layout.json +25 -0
- package/src/vendor/contract/v1/manifest.schema.json +60 -14
- package/src/vendor/contract/v1/sections.json +330 -61
- package/src/vendor/contract/v1/tokens.json +1 -1
- package/src/vendor/contract/v1.lock.json +1 -1
- package/src/vendor/engine/content-footprint.mjs +79 -0
- package/src/vendor/validator/behaviors-runtime.js +2 -0
- package/src/vendor/validator/fixture-art.mjs +109 -0
- package/src/vendor/validator/model-reference.mjs +92 -0
- package/src/vendor/validator/platform-base.css +4250 -0
- package/src/vendor/validator/preview.mjs +497 -23
- package/src/vendor/validator/site-context.mjs +97 -0
- package/src/vendor/validator/validate.mjs +214 -14
- package/starter/assets/theme.css +54 -8
- package/starter/layout.liquid +15 -16
- package/starter/manifest.json +10 -5
- package/starter/sections/campaigns.liquid +23 -0
- package/starter/sections/homeHero.liquid +26 -11
- package/starter/sections/people.liquid +1 -1
- package/starter/sections/values.liquid +6 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{% comment %}
|
|
2
|
+
Live site.content.campaigns, the starter's plain rendering of the `site.content.campaigns` context, kept simple on
|
|
3
|
+
purpose: this template is the worked example template authors copy from. The context is the
|
|
4
|
+
platform's published site.content.campaigns; hrefs are platform-derived, always link via campaign.href.
|
|
5
|
+
Derive or omit: nothing renders when no campaign is live.
|
|
6
|
+
{% endcomment %}
|
|
7
|
+
{% if site.content.campaigns.size > 0 %}
|
|
8
|
+
<section class="lq-site.content.campaigns">
|
|
9
|
+
<div class="container">
|
|
10
|
+
<h2>{{ section.heading | default: campaignsLabel }}</h2>
|
|
11
|
+
{% if section.text %}<p>{{ section.text }}</p>{% endif %}
|
|
12
|
+
<ul class="lq-campaign-list">
|
|
13
|
+
{% for campaign in site.content.campaigns %}
|
|
14
|
+
<li class="lq-campaign">
|
|
15
|
+
<h3>{{ campaign.title }}</h3>
|
|
16
|
+
{% if campaign.summary %}<p>{{ campaign.summary }}</p>{% endif %}
|
|
17
|
+
<a class="button button-primary" href="{{ campaign.href }}">View campaign</a>
|
|
18
|
+
</li>
|
|
19
|
+
{% endfor %}
|
|
20
|
+
</ul>
|
|
21
|
+
</div>
|
|
22
|
+
</section>
|
|
23
|
+
{% endif %}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{% comment %}
|
|
2
|
-
The home opener
|
|
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
|
-
designed gradient below
|
|
6
|
+
designed gradient below, never a placeholder image.
|
|
7
7
|
2. Photos are NEVER placed raw. The treatments in theme.css lay scrims built from the palette
|
|
8
8
|
variables (color-mix over var(--bg)/var(--bg-tint)), so any uploaded photograph is toned
|
|
9
9
|
into the template. Tune the treatment, don't remove it.
|
|
10
10
|
3. Rotation is the PLATFORM's hero_carousel island (templates ship no JavaScript): with two or
|
|
11
11
|
more photos, place it and style its documented classes.
|
|
12
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
|
|
13
|
+
shape (per-photo focus picks the surviving slice); 'whole' is the VISTA, the hero adapts
|
|
14
14
|
toward the photo's own shape (height-clamped) so a wide landscape stays entirely visible,
|
|
15
15
|
with your copy stacked after the band.
|
|
16
16
|
{% endcomment %}
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
{% if heroCount > 1 %}{% island 'hero_carousel' %}{% else %}<div class="lq-vista-scrim" aria-hidden="true"></div>{% endif %}
|
|
39
39
|
<div class="lq-vista-copy">
|
|
40
40
|
<div class="container">
|
|
41
|
-
<p class="lq-kicker">{{ section.eyebrow | default: brand.name }}</p>
|
|
42
|
-
<h1>{{ section.title | default: brand.tagline | default: brand.name }}</h1>
|
|
41
|
+
<p class="lq-kicker">{{ section.eyebrow | default: site.brand.name }}</p>
|
|
42
|
+
<h1>{{ section.title | default: site.brand.tagline | default: site.brand.name }}</h1>
|
|
43
43
|
{% if section.lead %}<p class="lq-homehero-lead">{{ section.lead }}</p>{% endif %}
|
|
44
44
|
<div class="lq-homehero-actions">
|
|
45
45
|
<a class="button button-primary" href="{{ section.primaryHref | default: '/donate' }}">{{ section.primaryLabel | default: 'Donate now' }}</a>
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
</div>
|
|
51
51
|
</section>
|
|
52
52
|
{% else %}
|
|
53
|
-
{% comment %} Form mode: the grid pulls up over the band
|
|
53
|
+
{% comment %} Form mode: the grid pulls up over the band, copy on the photo, the widget riding
|
|
54
54
|
the seam onto the gradient below (never a stacked strip). {% endcomment %}
|
|
55
55
|
<section class="lq-homehero lq-homehero--vista lq-homehero--vista-form{% if heroCount > 1 %} lq-homehero--carousel{% endif %}">
|
|
56
56
|
<div class="lq-vista">
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
</div>
|
|
60
60
|
<div class="container lq-homehero-inner lq-vista-overlap">
|
|
61
61
|
<div>
|
|
62
|
-
<p class="lq-kicker">{{ section.eyebrow | default: brand.name }}</p>
|
|
63
|
-
<h1>{{ section.title | default: brand.tagline | default: brand.name }}</h1>
|
|
62
|
+
<p class="lq-kicker">{{ section.eyebrow | default: site.brand.name }}</p>
|
|
63
|
+
<h1>{{ section.title | default: site.brand.tagline | default: site.brand.name }}</h1>
|
|
64
64
|
{% if section.lead %}<p class="lq-homehero-lead">{{ section.lead }}</p>{% endif %}
|
|
65
65
|
<div class="lq-homehero-actions">
|
|
66
66
|
<a class="button button-primary" href="#donate">{{ section.primaryLabel | default: 'Donate now' }}</a>
|
|
@@ -75,11 +75,26 @@
|
|
|
75
75
|
{% endif %}
|
|
76
76
|
{% else %}
|
|
77
77
|
<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 %}>
|
|
78
|
-
{%
|
|
78
|
+
{% comment %}
|
|
79
|
+
Several photos → the BEHAVIOUR carousel (data-p60-carousel, engine-wired, the template ships
|
|
80
|
+
no JavaScript): complete static markup, one data-p60-slide per photo, auto-advance opt-in.
|
|
81
|
+
Hiding non-active slides is .p60-js-scoped in theme.css so a no-JS visitor sees the photos
|
|
82
|
+
stacked, never a blank hero. The vista framings above show the other route: the ready-made
|
|
83
|
+
hero_carousel island. A template chooses either.
|
|
84
|
+
{% endcomment %}
|
|
85
|
+
{% if heroCount > 1 %}
|
|
86
|
+
<div class="lq-hero-slides" data-p60-carousel="auto" aria-label="Hero photographs">
|
|
87
|
+
{% for image in section.images %}
|
|
88
|
+
<img class="lq-hero-slide{% if forloop.first %} is-active{% endif %}" data-p60-slide
|
|
89
|
+
src="{{ image.imageUrl }}" alt="{{ image.alt }}" style="object-position: {{ heroFocus }}"
|
|
90
|
+
{% if forloop.first %}fetchpriority="high"{% else %}loading="lazy"{% endif %} decoding="async">
|
|
91
|
+
{% endfor %}
|
|
92
|
+
</div>
|
|
93
|
+
{% endif %}
|
|
79
94
|
<div class="container lq-homehero-inner">
|
|
80
95
|
<div>
|
|
81
|
-
<p class="lq-kicker">{{ section.eyebrow | default: brand.name }}</p>
|
|
82
|
-
<h1>{{ section.title | default: brand.tagline | default: brand.name }}</h1>
|
|
96
|
+
<p class="lq-kicker">{{ section.eyebrow | default: site.brand.name }}</p>
|
|
97
|
+
<h1>{{ section.title | default: site.brand.tagline | default: site.brand.name }}</h1>
|
|
83
98
|
{% if section.lead %}<p class="lq-homehero-lead">{{ section.lead }}</p>{% endif %}
|
|
84
99
|
<div class="lq-homehero-actions">
|
|
85
100
|
{% if section.givingStyle == 'button' %}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %}
|
|
2
|
-
People / team
|
|
2
|
+
People / team, the reference implementation: simple cards (name, role, optional photo and
|
|
3
3
|
one-line statement), a grid that collapses to one column on phones. No placeholder faces:
|
|
4
4
|
a person without a photo just renders text (derive or omit, never fabricate).
|
|
5
5
|
{% endcomment %}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
<section class="lq-values">
|
|
2
2
|
<div class="container">
|
|
3
3
|
<h2>{{ section.heading | default: "What guides us" }}</h2>
|
|
4
|
-
|
|
4
|
+
{% comment %}
|
|
5
|
+
data-p60-reveal-group: the engine stamps --p60-reveal-index on each child and adds
|
|
6
|
+
is-revealed when the rail scrolls into view, the stagger and motion are OURS, in theme.css,
|
|
7
|
+
and .p60-js-scoped so a no-JS visitor sees the rail complete and still.
|
|
8
|
+
{% endcomment %}
|
|
9
|
+
<ol class="lq-value-rail" data-p60-reveal-group>
|
|
5
10
|
{% for item in section.items %}
|
|
6
11
|
<li>
|
|
7
12
|
<span class="lq-value-dot"></span>
|