fix(noir): full-bleed hero in hero slot, drop cream vignette over hero image, caption below frame, 9-para case file
- Seed: home hero -> landing 'hero' slot (full-bleed) and cta -> 'cta' slot; reconcile_blocks on home + harbour-light so demo re-install rewrites them. - Hero: remove noir-spotlight from the image wrapper and the landing hero-slot wrapper — its radial vignette fades the photo to --background (cream in light mode) exactly where the onImg white text sits. Image + black scrim now carry legibility in both modes. - Image override: figure is column-flex so the typed caption sits under the evidence frame (was landing beside it); frames render grayscale to match the dossier persona. - Harbour Light article extended to 9 paragraphs (case-file voice) per the seed length gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
27caa1d30a
commit
345741f83f
@ -32,11 +32,12 @@
|
|||||||
"slug": "/",
|
"slug": "/",
|
||||||
"title": "The Cold File",
|
"title": "The Cold File",
|
||||||
"template_key": "landing",
|
"template_key": "landing",
|
||||||
|
"reconcile_blocks": true,
|
||||||
"blocks": [
|
"blocks": [
|
||||||
{
|
{
|
||||||
"block_key": "hero",
|
"block_key": "hero",
|
||||||
"title": "Hero",
|
"title": "Hero",
|
||||||
"slot": "main",
|
"slot": "hero",
|
||||||
"sort_order": 1,
|
"sort_order": 1,
|
||||||
"content": {
|
"content": {
|
||||||
"template": "centered",
|
"template": "centered",
|
||||||
@ -103,8 +104,8 @@
|
|||||||
{
|
{
|
||||||
"block_key": "cta",
|
"block_key": "cta",
|
||||||
"title": "Closing CTA",
|
"title": "Closing CTA",
|
||||||
"slot": "main",
|
"slot": "cta",
|
||||||
"sort_order": 5,
|
"sort_order": 1,
|
||||||
"content": {
|
"content": {
|
||||||
"background": "band",
|
"background": "band",
|
||||||
"heading": "Know something we don't?",
|
"heading": "Know something we don't?",
|
||||||
@ -144,10 +145,11 @@
|
|||||||
"title": "The Harbour Light",
|
"title": "The Harbour Light",
|
||||||
"template_key": "article",
|
"template_key": "article",
|
||||||
"parent_slug": "/blog",
|
"parent_slug": "/blog",
|
||||||
|
"reconcile_blocks": true,
|
||||||
"blocks": [
|
"blocks": [
|
||||||
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "The Harbour Light", "level": 1 } },
|
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "The Harbour Light", "level": 1 } },
|
||||||
{ "block_key": "image", "title": "The pier", "slot": "main", "sort_order": 2, "content": { "src": "7a1c0001-0000-4000-8000-000000000002", "alt": "The East Dock lost in night fog", "caption": "Pier 9, East Dock — the same hour we walked it.", "aspectRatio": "video", "size": "full", "objectFit": "cover" } },
|
{ "block_key": "image", "title": "The pier", "slot": "main", "sort_order": 2, "content": { "src": "7a1c0001-0000-4000-8000-000000000002", "alt": "The East Dock lost in night fog", "caption": "Pier 9, East Dock — the same hour we walked it.", "aspectRatio": "video", "size": "full", "objectFit": "cover" } },
|
||||||
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 3, "content": { "html": "<p>The watchman made his last radio check at four minutes past two. He was due at the gate by half past. He never signed out.</p><p>The lamp on Pier 9 was still lit at dawn. The tide had turned twice. No boat was reported missing. No body was found. The file was opened, worked for a season, and set aside.</p><p>We pulled the harbour master's log and the tide tables for that week. The two do not agree on when the water turned. One of them was written up after the fact, and we think we know which.</p><p>We walked the pier at the same hour. The lamp throws light about forty feet. The gate is ninety. For six of those steps a man is in the dark. We are still checking what stands in them.</p>" } },
|
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 3, "content": { "html": "<p>The watchman made his last radio check at four minutes past two. He was due at the gate by half past. He never signed out.</p><p>The lamp on Pier 9 was still lit at dawn. The tide had turned twice. No boat was reported missing. No body was found. The file was opened, worked for a season, and set aside.</p><p>Start with what the record holds. A duty roster with his name in the two-to-six column. A radio log with four entries in his hand, the last at 02:04, marked routine. A gate ledger that shows every man off the dock by three — every man but one.</p><p>The season it was worked, the file gathered the usual paper. Two dozen interviews. A diver's report for the water off the pier head, twice. A note from the gate man, who swore the light was burning when he cycled past at ten to three and swore just as hard that nobody stood under it.</p><p>Then the file stops. Not closed — stopped. The last page is a requisition for more diving time that nobody signed.</p><p>We pulled the harbour master's log and the tide tables for that week. The two do not agree on when the water turned. One of them was written up after the fact, and we think we know which.</p><p>We walked the pier at the same hour. The lamp throws light about forty feet. The gate is ninety. For six of those steps a man is in the dark. We are still checking what stands in them.</p><p>There is one more thing the record holds, and we set it down here exactly as it appears. The radio log's final line, in a different hand, timed 02:31: <em>checked pier, all quiet</em>. Nobody at the harbour that season would say whose hand it was.</p><p>The file is open. If you worked the East Dock in March 1998, or knew someone who did, the tip line is at the end of this page.</p>" } },
|
||||||
{ "block_key": "heading", "title": "Rail heading", "slot": "aside", "sort_order": 1, "content": { "text": "Case File", "level": 3 } },
|
{ "block_key": "heading", "title": "Rail heading", "slot": "aside", "sort_order": 1, "content": { "text": "Case File", "level": 3 } },
|
||||||
{ "block_key": "text", "title": "Case metadata", "slot": "aside", "sort_order": 2, "content": { "text": "<dl class=\"not-prose space-y-4\"><div><dt class=\"noir-label text-muted-foreground\">Case No.</dt><dd class=\"noir-mono text-sm text-foreground\">CF-0451</dd></div><div><dt class=\"noir-label text-muted-foreground\">Filed</dt><dd class=\"noir-mono text-sm text-foreground\">March 1998</dd></div><div><dt class=\"noir-label text-muted-foreground\">Location</dt><dd class=\"noir-mono text-sm text-foreground\">Pier 9, East Dock</dd></div><div><dt class=\"noir-label text-muted-foreground\">Last contact</dt><dd class=\"noir-mono text-sm text-foreground\">02:04, radio check</dd></div><div><dt class=\"noir-label text-muted-foreground\">Status</dt><dd class=\"noir-mono text-sm text-foreground\">Open, unsolved</dd></div></dl>" } }
|
{ "block_key": "text", "title": "Case metadata", "slot": "aside", "sort_order": 2, "content": { "text": "<dl class=\"not-prose space-y-4\"><div><dt class=\"noir-label text-muted-foreground\">Case No.</dt><dd class=\"noir-mono text-sm text-foreground\">CF-0451</dd></div><div><dt class=\"noir-label text-muted-foreground\">Filed</dt><dd class=\"noir-mono text-sm text-foreground\">March 1998</dd></div><div><dt class=\"noir-label text-muted-foreground\">Location</dt><dd class=\"noir-mono text-sm text-foreground\">Pier 9, East Dock</dd></div><div><dt class=\"noir-label text-muted-foreground\">Last contact</dt><dd class=\"noir-mono text-sm text-foreground\">02:04, radio check</dd></div><div><dt class=\"noir-label text-muted-foreground\">Status</dt><dd class=\"noir-mono text-sm text-foreground\">Open, unsolved</dd></div></dl>" } }
|
||||||
]
|
]
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
{{ head_html|safe }}
|
{{ head_html|safe }}
|
||||||
<body class="bg-background text-foreground antialiased min-h-screen flex flex-col noir-body">
|
<body class="bg-background text-foreground antialiased min-h-screen flex flex-col noir-body">
|
||||||
{{ admin_banner_html|safe }}
|
{{ admin_banner_html|safe }}
|
||||||
<section class="w-full relative noir-grain noir-spotlight">{{ slots.hero|safe }}</section>
|
<section class="w-full relative noir-grain">{{ slots.hero|safe }}</section>
|
||||||
<main class="flex-grow">
|
<main class="flex-grow">
|
||||||
{% if slots.main %}<div class="max-w-3xl mx-auto w-full px-4 py-10 noir-reveal">{{ slots.main|safe }}</div>{% endif %}
|
{% if slots.main %}<div class="max-w-3xl mx-auto w-full px-4 py-10 noir-reveal">{{ slots.main|safe }}</div>{% endif %}
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
{% set align = "center" %}
|
{% set align = "center" %}
|
||||||
{% if variant == "left-aligned" %}{% set align = "left" %}{% endif %}
|
{% if variant == "left-aligned" %}{% set align = "left" %}{% endif %}
|
||||||
<section data-block-override="noir:hero" class="hero relative flex flex-col overflow-hidden bg-background text-foreground noir-grain {% if minHeight == "screen" %}min-h-screen justify-center{% else %}py-16 md:py-20 lg:py-24{% endif %}{% if class %} {{ class }}{% endif %}">
|
<section data-block-override="noir:hero" class="hero relative flex flex-col overflow-hidden bg-background text-foreground noir-grain {% if minHeight == "screen" %}min-h-screen justify-center{% else %}py-16 md:py-20 lg:py-24{% endif %}{% if class %} {{ class }}{% endif %}">
|
||||||
{% if hasImage %}<div class="absolute inset-0 z-0 noir-spotlight grayscale">{% img backgroundImage alt=headlineText class="h-full w-full object-cover" layout="hero" %}{% if showOverlay %}<div class="absolute inset-0 {% if overlayColor == "light" %}bg-background/60{% elif overlayColor == "primary" %}bg-primary/50{% elif overlayOpacity <= 30 %}bg-black/30{% elif overlayOpacity <= 50 %}bg-black/50{% elif overlayOpacity <= 70 %}bg-black/70{% else %}bg-black/80{% endif %}"></div>{% endif %}</div>{% endif %}
|
{% if hasImage %}<div class="absolute inset-0 z-0 grayscale">{% img backgroundImage alt=headlineText class="h-full w-full object-cover" layout="hero" %}{% if showOverlay %}<div class="absolute inset-0 {% if overlayColor == "light" %}bg-background/60{% elif overlayColor == "primary" %}bg-primary/50{% elif overlayOpacity <= 30 %}bg-black/30{% elif overlayOpacity <= 50 %}bg-black/50{% elif overlayOpacity <= 70 %}bg-black/70{% else %}bg-black/80{% endif %}"></div>{% endif %}</div>{% endif %}
|
||||||
<div class="relative z-10 mx-auto w-full max-w-4xl px-4 sm:px-6 lg:px-8 {% if variant == "left-aligned" %}text-left{% else %}text-center{% endif %}">{{ herocontent(align, hasImage) }}</div>
|
<div class="relative z-10 mx-auto w-full max-w-4xl px-4 sm:px-6 lg:px-8 {% if variant == "left-aligned" %}text-left{% else %}text-center{% endif %}">{{ herocontent(align, hasImage) }}</div>
|
||||||
</section>
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
{# image override — square evidence frame with a typed mono caption. Fields mirror builtin: src, alt, caption, size, align, aspectRatio, objectFit. Media resolved via {% img %} (the media filter is not registered in the block render path). #}
|
{# image override — square evidence frame with a typed mono caption. Fields mirror builtin: src, alt, caption, size, align, aspectRatio, objectFit. Media resolved via {% img %} (the media filter is not registered in the block render path). #}
|
||||||
{% with size=size|default:"full" align=align|default:"center" objectFit=objectFit|default:"cover" %}
|
{% with size=size|default:"full" align=align|default:"center" objectFit=objectFit|default:"cover" %}
|
||||||
<figure data-block-override="noir:image" class="my-8 flex-1 {% if align == "left" %}flex justify-start{% elif align == "right" %}flex justify-end{% else %}flex justify-center{% endif %}{% if class %} {{ class }}{% endif %}">
|
<figure data-block-override="noir:image" class="my-8 flex-1 flex flex-col {% if align == "left" %}items-start{% elif align == "right" %}items-end{% else %}items-center{% endif %}{% if class %} {{ class }}{% endif %}">
|
||||||
<div class="noir-file p-2 {% if size == "xs" %}max-w-[200px] w-full{% elif size == "sm" %}max-w-[400px] w-full{% elif size == "md" %}max-w-[600px] w-full{% elif size == "lg" %}max-w-[800px] w-full{% else %}w-full{% endif %}">
|
<div class="noir-file p-2 {% if size == "xs" %}max-w-[200px] w-full{% elif size == "sm" %}max-w-[400px] w-full{% elif size == "md" %}max-w-[600px] w-full{% elif size == "lg" %}max-w-[800px] w-full{% else %}w-full{% endif %}">
|
||||||
<div class="relative overflow-hidden bg-muted {% if aspectRatio == "square" %}aspect-square{% elif aspectRatio == "video" %}aspect-video{% elif aspectRatio == "portrait" %}aspect-[3/4]{% elif aspectRatio == "wide" %}aspect-[21/9]{% endif %}">
|
<div class="relative overflow-hidden bg-muted grayscale {% if aspectRatio == "square" %}aspect-square{% elif aspectRatio == "video" %}aspect-video{% elif aspectRatio == "portrait" %}aspect-[3/4]{% elif aspectRatio == "wide" %}aspect-[21/9]{% endif %}">
|
||||||
{% if objectFit == "contain" %}{% img src alt=alt class="w-full h-full object-contain" layout=size %}{% elif objectFit == "fill" %}{% img src alt=alt class="w-full h-full object-fill" layout=size %}{% elif objectFit == "none" %}{% img src alt=alt class="w-full h-full object-none" layout=size %}{% else %}{% img src alt=alt class="w-full h-full object-cover" layout=size %}{% endif %}
|
{% if objectFit == "contain" %}{% img src alt=alt class="w-full h-full object-contain" layout=size %}{% elif objectFit == "fill" %}{% img src alt=alt class="w-full h-full object-fill" layout=size %}{% elif objectFit == "none" %}{% img src alt=alt class="w-full h-full object-none" layout=size %}{% else %}{% img src alt=alt class="w-full h-full object-cover" layout=size %}{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user