/* ============================================================
   PXICON.CSS — the pixel-mark system, in one file.

   MOVED OUT OF index.html 2026-09-18, on Phil's "add them where they belong."
   The marks, their size tokens and their two layouts all lived inline in
   index.html, which meant a mark could not be placed on any OTHER page: the
   four pages that show the same six rules had no --px-icon to size one with,
   so a mark dropped in there would silently render at the bare .ic 36px and
   break the one law the system has (below). Phil's own ruling on the nav
   settles the shape: one file, not twenty-five.

   Load it alongside navmenu.css / type.css / ground.css. It owns the tokens,
   so it must load on any page that draws the logo OR a pixel mark.
   ============================================================ */

:root{
  /* THE LOGO'S SQUARE IS THE UNIT. A mark is a 10x10 cut of Blobby's lattice
     on a 1054 viewBox, so a mark whose squares match the logo's measures that
     square times 1054/100.
     Written as arithmetic, not as a number, so the two can never drift: change
     --mark-size and the icons follow it the same afternoon. The ratio is the
     brand; the footprint is just how much of it you are looking at. */
  --mark-size:50px;
  --mark-cell:calc(var(--mark-size) * 100 / 524);
  /* MATCHING THE LOGO'S SQUARE EXACTLY PUT THE MARKS AT 100.6px AND PHIL CUT
     IT: "too big, find a middle ground." Five eighths (62.9) was still "a bit
     big", so the square is HALF the logo's and the marks land at 50.3.
     A stated fraction rather than a size, for two reasons: the marks stay cut
     from Blobby's lattice at a coarser grain instead of quietly becoming their
     own thing, and it stays ONE number, so every mark on the site moves
     together the next time he wants them somewhere else. */
  --mark-scale:.5;
  --px-icon:calc(var(--mark-cell) * var(--mark-scale) * 1054 / 100);
  /* The card's horizontal inset. The gutter beside an icon reads this too, so
     the mark cannot end up with more air on one side than the other. */
  --ucell-x:22px;
}

/* THE MARK GETS SMALLER ON A PHONE, SO EVERYTHING CUT FROM ITS LATTICE DOES.
   This lived in index.html's inline style until 2026-09-19 and had to move here
   with the token: this file loads after the page's inline <style>, so an
   override left behind there ties on specificity and loses on order. It did,
   silently, and the phone marks went from 28px back to 50 until it was
   measured. A token and its overrides belong in one file or the token is not
   doing its job.
   720 rather than 700 to match the nav's own breakpoint, which is where the
   header mark itself changes size. */
@media(max-width:720px){
  :root{--mark-size:28px}
}

/* SIZE FIRST, LAYOUT SECOND. A mark carries the logo's square wherever it sits,
   and the page it sits on does not have to know about it. Found the hard way:
   the six rules render in THREE different components across the site - .ucell
   in the fears grid, <summary> in the index rules panel, and div.rulecard in
   the Guide - so a rule keyed to any one container sized the mark on one page
   and silently left it at the bare .ic 36px on another. Measured on guide.html:
   token resolved, sheet loaded, mark still 36.
   `html` in front is not decoration. The page's own `.rule .ic{width:36px}` is
   (0,2,0) and its inline <style> loads AFTER this file, so a bare `.ic.px` ties
   and loses on order. `html .ic.px` is (0,2,1) and wins regardless of order. */
html .ic.px{width:var(--px-icon);height:var(--px-icon)}

/* A CELL CARRYING A PIXEL MARK GETS THE LOGO'S SQUARE, WHICH MEANS A BIG SLOT.
   At 36px a 10x10 mark's squares are 3.4px against the logo's 9.5, three times
   finer, and that is the whole reason the first version did not feel related to
   the header — same lattice, different material. The icon column is --px-icon
   so the squares MATCH instead of resembling. */
.ucell:has(> .ic.px){grid-template-columns:var(--px-icon) 1fr;
     grid-template-rows:auto auto;align-items:start}
/* The mark spans the whole cell instead of sitting in row one. `grid-row:1/-1`
   counts against the EXPLICIT grid, so the rows above are declared for this
   line's sake; with none declared the span silently collapsed to a single row
   and changed nothing. It looked applied and wasn't. */
.ucell:has(> .ic.px) .ic.px{grid-row:1 / -1}

/* EVERY OTHER CHILD GOES TO COLUMN TWO, BY DEFAULT AND NOT BY NAME.
   Added 2026-09-21, and it is the fix for an incomplete extraction. The grid
   above came out of index.html into this file, but the PLACEMENTS did not:
   index still names `.t`, `p` and `.learn` into column 2 in its own inline
   CSS. So any other page that linked pxicon.css got the two-column grid with
   none of the placement, and every child the list did not mention fell into
   the 50px ICON GUTTER. services.html hit it the moment the service marks went
   in: the "what you get" blocks under each service wrapped one word per line.

   This is the same trap I filed a principle about on 2026-09-20 and then walked
   straight into again. IN A NAMED-PLACEMENT GRID, AN UNPLACED CHILD IS
   MISPLACED, NOT UNSTYLED - so the rule must be a default, not a list. Stated
   as *:not(.ic.px) it covers .t, p, .learn, the dl blocks and anything added
   later, and it cannot go stale the way three named selectors did.
   The same shape already existed one block down for `.rules6 summary`. It
   should have been here from the start; the asymmetry was the bug. */
.ucell:has(> .ic.px) > *:not(.ic.px){grid-column:2}
/* .ucell scope is load-bearing: the bare `.ic{width:36px}` in the page is
   (0,2,0) and sits later, so a (0,2,0) rule loses on order and the mark
   silently stays 36. */
.ucell .ic.px{width:var(--px-icon);height:var(--px-icon)}

/* A RULE CARD CARRYING A PIXEL MARK. A rule is a <summary>, not a .ucell, so
   the same arrangement is restated rather than shared, from the same two
   tokens so it cannot drift from the Unlocks grid.
   The ::after ("+ read the rule") is a grid item too and has to be put in
   column two by hand, or it slides under the mark.
   :has() puts these at (0,3,0), above the plain `.rules6 summary` block in the
   page, so they win on specificity and not on source order. */
.rules6 summary:has(> .ic.px){display:grid;
     grid-template-columns:var(--px-icon) 1fr;
     grid-template-rows:auto auto auto auto;
     column-gap:var(--ucell-x);align-items:start;align-content:start}
.rules6 summary:has(> .ic.px) > .ic.px{grid-row:1 / -1;grid-column:1;
     width:var(--px-icon);height:var(--px-icon);margin-bottom:0}
.rules6 summary:has(> .ic.px) > *:not(.ic){grid-column:2}
.rules6 summary:has(> .ic.px)::after{grid-column:2}
/* THE HOVER TINT, EXTENDED TO RULE CARDS. Phil 2026-09-18: "when i roll over
   the new icons, they don't blobbify?" He was seeing a real gap. The pointer
   feedback is keyed to `.ucell:has(> .ic)`, so the Unlocks grid and the fears
   grid both answer the pointer and the rules panel did not - a rule card is a
   <details>, not a .ucell, and nothing matched it. Same gesture, same 18%,
   read from the same place rather than a second number.
   Keyed to the card, not the summary: the whole card is the hit area, and the
   open state should stay lit while you read it. */
.rules6 .rule:has(.ic.px):hover,
.rules6 .rule:has(.ic.px):focus-within{
     background:color-mix(in srgb, var(--paper) 18%, transparent)}
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  html[data-theme="dark"] .rules6 .rule:has(.ic.px):hover{background:rgba(13,10,22,.18)}
  .rules6 .rule:has(.ic.px):hover{background:rgba(255,255,255,.18)}
}
/* The Guide's rule cards are div.rulecard - a third component again - and they
   are not interactive there, so they are deliberately left alone. */

/* The h3's top margin exists to clear a 36px icon stacked above it. With the
   mark beside the text there is nothing above to clear. */
.rules6 summary:has(> .ic.px) h3{margin-top:0}
