/* SITE TYPE ROLES — one definition, shared, so a page's title size is a ROLE and not an
   accident of which wrapper its <h1> happens to sit in.

   Phil, 2026-09-03: "The sub pages after the index page have larger text in the headers,
   consistently. Why? ... Check why this is happening."

   WHY IT WAS HAPPENING. Measured across 22 pages, three different h1 sizes were in play:
     .herogrid h1   clamp(30px,4.4vw,52px)  -> 52px  · index, about, contact, agents, p2p, security
     .pagehead h1   clamp(34px,5.4vw,58px)  -> 58px  · work + all nine case studies
     (no wrapper)   var(--t-3xl)            -> 66px  · services, assessment, guide, audit, custom-build
   The third one is the bug. Those five pages write <div class="hero"><h1>…, with no .herogrid
   inside, so the h1 misses both wrapper rules and lands on the raw display token — 27% larger
   than the homepage. Nobody chose 66px for them; they fell through to it.

   Body copy was NOT part of this. It is `.mech` at 19px on every page, already consistent —
   my first probe said otherwise because on two pages it had sampled an sr-only span.

   TWO ROLES, deliberately:
     hero title  52px — the homepage and every page built on the hero
     page title  58px — work and the case studies, a different template
   Say the word and they collapse to one. */
.hero h1,.guidehero h1,.herogrid h1{font-size:clamp(30px,4.4vw,52px)}
.pagehead h1{font-size:clamp(34px,5.4vw,58px)}

/* An illustration slot that has not been given a scene yet draws nothing and occupies nothing,
   so a page can carry its slot before its drawing exists. Naming a world switches it on. */
/* A slot with no scene named and NOTHING IN IT collapses to nothing. contact.html's slot is
   exempt by id — illo.js injects the engagement plate into it at runtime, so it is not an empty
   slot, it is a slot whose contents arrive late.
   FOUR PAGES were already reserving a blank 412x490 box before tonight — ai-agents, ai-security,
   prototype-to-production and case-valhalla each had a .heroviz with nothing in it. That gap was
   live on the site; this collapses it until each page names its drawing.

   `:empty` ADDED 2026-09-05, and it is the whole rule. Without it this asked "does this slot
   name a world" while meaning "is there anything in this slot", and the two came apart on the
   two pages where a .heroviz holds something that is not a block world: about.html's slot holds
   PHIL'S PHOTOGRAPH and case-valhalla's holds an SVG diagram. Both were being hidden outright —
   not shrunk, not misplaced, gone — on the live pages, and no check I own looks for content that
   was simply never painted. Found while wiring the about world, by asking why a photo I had not
   touched measured 0x0. The predicate now tests the thing it means. */
.heroviz:not([data-world]):not(#contactviz):empty{display:none}
