diff --git a/manifest.yaml b/manifest.yaml index 495d02e..e8f6f6b 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -338,3 +338,52 @@ css: .noir-redact { transition: none; } } } + + /* ============================================================ + Explicit responsive layout (authored CSS — NOT purged). + The host Tailwind JIT does not reliably scan a theme's override + templates, so sm:/md:/lg: grid variants declared there can be + dropped from the build (a grid then never expands on desktop + and never collapses on mobile). These media-query rules own the + column counts deterministically and always collapse to a single + column on phones. + ============================================================ */ + .noir-cols { display: grid; grid-template-columns: 1fr; gap: 1.5rem; } + @media (min-width: 640px) { + .noir-cols-2, .noir-cols-3, .noir-cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } + } + @media (min-width: 1024px) { + .noir-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } + .noir-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } + } + /* Grids that stay two-up on phones (galleries, stat rows, footer links). */ + .noir-cols-2up { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; } + @media (min-width: 768px) { + .noir-cols-2up-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } + .noir-cols-2up-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } + } + /* Media/text split — one column on phones, two from the tablet width. */ + .noir-split { display: grid; grid-template-columns: 1fr; gap: 2.5rem; } + @media (min-width: 768px) { .noir-split { grid-template-columns: repeat(2, minmax(0, 1fr)); } } + /* Gap modifiers (used alongside any grid class above). */ + .noir-gap-sm { gap: 0.75rem; } + .noir-gap-lg { gap: 2rem; } + + /* Hero vertical rhythm — replaces the unreliable min-h-[75vh] arbitrary + class so the masthead has bounded, predictable breathing room instead + of collapsing to nothing or ballooning to 75vh of empty space. */ + .noir-hero-pad { padding-top: 3.5rem; padding-bottom: 3.5rem; } + @media (min-width: 768px) { .noir-hero-pad { padding-top: 5rem; padding-bottom: 5rem; } } + @media (min-width: 1024px) { .noir-hero-pad { padding-top: 6.5rem; padding-bottom: 6.5rem; } } + + /* Empty-media graceful state — the demo seed ships no images, so any + media frame that renders an empty must not balloon into a grey + box or show broken-image chrome. Images never exceed their column. */ + .noir-file img, .bn-card img, .bn-gallery img, figure img { max-width: 100%; height: auto; } + img[src=""], img:not([src]) { display: none; } + + /* Overflow safety — long typed/mono labels wrap rather than push the + page wider than a phone viewport (uppercase + wide tracking is the risk). */ + .noir-label, .noir-mono, .noir-heading { overflow-wrap: break-word; } + /* Never let a block force a horizontal scrollbar on small screens. */ + [data-block-override], [data-block] { max-width: 100%; } diff --git a/templates/noir/default.ninjatpl b/templates/noir/default.ninjatpl index 29aceb0..db28cea 100644 --- a/templates/noir/default.ninjatpl +++ b/templates/noir/default.ninjatpl @@ -22,8 +22,11 @@ var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches; var els=document.querySelectorAll('.noir-reveal'); if(reduce||!('IntersectionObserver' in window)){els.forEach(function(el){el.classList.add('noir-in');});return;} - var io=new IntersectionObserver(function(entries){entries.forEach(function(e){if(e.isIntersecting){e.target.classList.add('noir-in');io.unobserve(e.target);}});},{threshold:0.12}); - els.forEach(function(el){io.observe(el);}); + var io=new IntersectionObserver(function(entries){entries.forEach(function(e){if(e.isIntersecting){e.target.classList.add('noir-in');io.unobserve(e.target);}});},{threshold:0,rootMargin:'0px 0px -8% 0px'}); + function showAll(){els.forEach(function(el){el.classList.add('noir-in');});} + els.forEach(function(el){var r=el.getBoundingClientRect();var h=window.innerHeight||document.documentElement.clientHeight||0;if(r.top0){el.classList.add('noir-in');}else{io.observe(el);}}); + window.addEventListener('load',showAll); + setTimeout(showAll,1600); })(); diff --git a/templates/noir/landing.ninjatpl b/templates/noir/landing.ninjatpl index cdaee02..c19feb7 100644 --- a/templates/noir/landing.ninjatpl +++ b/templates/noir/landing.ninjatpl @@ -5,7 +5,7 @@ {{ admin_banner_html|safe }}
{{ slots.hero|safe }}
- {% if slots.main %}
{{ slots.main|safe }}
{% endif %} + {% if slots.main %}
{{ slots.main|safe }}
{% endif %}
{{ slots.cta|safe }}