/* Evidence pages reuse the site's reading measure and typography. */
/* The zero margin is deliberate for the sides and the foot; the head needs
   room when an intro precedes the list. */
.work-index { list-style: none; padding: 0; margin: 2.5rem 0 0; }
.work-index > li { padding-block: 2rem; border-top: 1px solid var(--line); }
.work-index > li:last-child { border-bottom: 1px solid var(--line); }
.work-index > li > * + * { margin-top: 0.85rem; }
.work-index h2 { font-size: clamp(1.5rem, 3vw, 2rem); line-height: 1.25; }
.work-index .eyebrow { font-size: 0.875rem; }
.work-index a, .related-work a { text-underline-offset: 0.2em; text-decoration-thickness: 1px; }
.work-index a:hover, .related-work a:hover { color: var(--accent-text); }
.work-meta { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem 1.5rem; flex-wrap: wrap; }
.work-status, .work-evidence, .work-tags span {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.72rem; letter-spacing: 0.02em;
}
.work-status { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 600; text-transform: uppercase; }
.work-status::before { content: ""; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--accent); }
.work-status--prototype::before { background: #b76512; }
.work-status--documented::before { background: #34785c; }
.work-status--archived::before { background: #737b89; }
.work-evidence { color: var(--accent-text); }
.work-tags { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.work-tags span { padding: 0.35rem 0.55rem; border-radius: 4px; background: var(--mist); color: var(--body); }
.evidence-label { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent-text); }
.work-body section + section, .related-work { margin-top: 2.5rem; }
.work-body section > * + *, .related-work > * + * { margin-top: 1.25rem; }
.work-body h2 { line-height: 1.3; }
/* Four short words that do not wrap at any width the grid allows, but the
   number is inline here too, so it is given a column for the same reason. */
/* The slash lives with the number, not before the label: when a long label
   wrapped, a trailing space in the ::before let the slash follow it onto the
   next line. */
@media (max-width: 34rem) {
  /* Four columns give each label about 80px on a phone, which is narrower than
     APPLICATION. Two rows of two keeps the sequence readable. */
}
.work-body { counter-reset: work-section; }
.work-body > section { counter-increment: work-section; }
/* The number is a ::before, so it is inline with the title and the heading is
   one continuous run of text. A title that wrapped put its second line back at
   the left margin, underneath the number rather than under the words it
   continues. Two grid columns give the number its own track and leave the
   title as a block, so every line of it starts at the same place. */
.work-body > section > h2 {
  display: grid; grid-template-columns: auto 1fr; gap: 0.5rem;
  align-items: baseline;
}
.work-body > section > h2::before {
  content: "0" counter(work-section) " / ";
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.72rem; color: var(--accent-text); letter-spacing: 0.04em;
}
/* justify-content centres the two tracks inside the box. Without it they pack
   to the start, so any width the box has beyond what the columns need collects
   at the right edge -- a centred box holding off-centre content. That is what
   1120px was doing: the tracks cap at 68ch + 3rem + 20rem, which is 66px short
   of it, and the reader saw a wider margin on the right than on the left.

   The box's own width stops mattering once the content is centred within it,
   which is why 1120 stays rather than being tuned to the columns. It is an
   upper bound, and nothing is anchored to it. */
.work-reading-wrap {
  max-width: 1120px; display: grid; grid-template-columns: minmax(0, 68ch) minmax(16rem, 20rem);
  gap: 0 3rem; align-items: start; justify-content: center;
}
.work-reading-wrap > .back-link { grid-column: 1 / -1; }
.work-reading-wrap > article { grid-column: 1; }
.work-reading-wrap > .evidence-record { grid-column: 2; }
.evidence-record { margin-top: 2rem; padding: 1.5rem; border: 1px solid var(--line); border-radius: var(--r-panel); overflow-wrap: anywhere;
  /* The ledger sticks beside the prose, and can be read to the end at any
     window height. Bounded by the viewport less the bar, it scrolls inside
     itself when it does not fit -- without that, a short window pinned the
     panel with its last lines below the fold and no amount of page scrolling
     could reach them.

     --nav-h is measured by navigation.js rather than assumed, since the bar's
     height is padding plus content and changes with the breakpoint and with
     the font swap. svh rather than dvh to match the search sheet, which solves
     the same problem a few rules up. */
  position: sticky; top: calc(var(--nav-h, 0px) + 1.5rem); bottom: 1.5rem;
  max-height: calc(100svh - var(--nav-h, 0px) - 3rem); overflow-y: auto; }
.evidence-record h2 { font-size: 1.125rem; }
.evidence-record > * + * { margin-top: 1rem; }
.evidence-record ul { padding-left: 1.25rem; }
.evidence-record li + li { margin-top: 0.65rem; }
.evidence-ledger { display: flex; flex-direction: column; gap: 0.75rem; }
.evidence-item { padding: 0.85rem 0.9rem; border-left: 3px solid var(--line); border-radius: 0 6px 6px 0; background: var(--mist); }
.evidence-item > * + * { margin-top: 0.45rem; }
.evidence-item p:last-child { font-size: 0.82rem; line-height: 1.5; }
.evidence-item--verified { border-left-color: var(--accent); background: #eef4ff; }
.evidence-item--application { border-left-color: #34785c; background: #edf7f2; }
.evidence-item--application .evidence-label { color: #286149; }
.evidence-item--open { border-left-color: #b76512; background: #fff6e9; }
.evidence-item--open .evidence-label { color: #8c4b0d; }
.source-snapshot { padding-top: 1rem; border-top: 1px solid var(--line); font-size: 0.75rem; line-height: 1.5; color: var(--body); }
.review-date { margin-top: 2.5rem; font-size: 0.9375rem; }
.post-body .system-flow { padding: 0; margin-block: 2rem; list-style: none; counter-reset: flow; }
/* Same shape as the section headings: the number is an inline ::before, so a
   step that wrapped put its later lines under the number instead of under its
   own first word. A grid column for the number keeps the text a block. */
.system-flow li {
  counter-increment: flow; padding: 1rem 1.25rem; background: var(--mist); border-radius: 12px;
  display: grid; grid-template-columns: auto 1fr; gap: 0.4rem; align-items: baseline;
}
.system-flow li::before { content: counter(flow) ". "; color: var(--accent-text); font-weight: 600; }
.system-flow li + li { margin-top: 0.75rem; }
/* The counts are provenance, not argument: they sit under the prose in the
   register of a caption so the sentence above keeps the page. */
.repo-meta { max-width: var(--measure); margin-top: .4rem; color: var(--muted);
  font-size: 0.875rem; letter-spacing: .01em; }
/* The link is one phrase and reads as one target: it moves to the next line
   whole rather than breaking across two. */
.repo-meta a { color: var(--body); white-space: nowrap; }
@media (max-width: 40rem) {
}
@media (max-width: 28rem) {
}
@media (max-width: 58rem) {
  .work-reading-wrap { max-width: 68ch; display: block; }
  /* Stacked, the ledger is just the next thing to read, so every part of the
     sticky treatment comes off -- not only the position. Leaving the bound in
     place put a scrolling panel inside a scrolling page on a phone, which is
     worse than the overflow it was added to solve. */
  .evidence-record {
    margin-top: 3rem; position: static;
    max-height: none; overflow-y: visible;
  }
}

/* An irq9 or nyfor project carries its product mark beside the title. The mark
   is the one these tools already ship with -- the same squircle that appears as
   an app icon -- so a reader who has seen the running product recognises it
   here. Flex rather than a float so the mark centres against the first line of
   a title that wraps, and shrink-0 so a long title never squashes it. */
.work-title { display: flex; align-items: center; gap: .75rem; }
.work-mark-wrap { flex: 0 0 auto; display: block; width: 40px; height: 40px; }
.work-mark { display: block; width: 100%; height: 100%; }

@media (max-width: 34rem) {
  .work-title { gap: .6rem; }
  .work-mark-wrap { width: 34px; height: 34px; }
}

/* The mark links to the identity system page. It is a badge, not body copy, so
   it takes none of the link chrome -- no underline, no colour shift -- and
   signals itself on hover the way the icon grid does. */
a.work-mark-wrap { text-decoration: none; transition: transform .18s ease-out; }
a.work-mark-wrap:hover, a.work-mark-wrap:focus-visible { transform: translateY(-1px); }


/* The hub and its three games, shown rather than described. The cards are the
   ones the games actually serve when a link is shared, so the page and the
   link preview cannot drift apart. Two up, one up on a narrow screen. */
.card-gallery { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; margin-block: 2rem 2.5rem; }
.card-gallery figure { margin: 0; }
.card-gallery img { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: 10px; background: #050505; }
.card-gallery figcaption { margin-top: .5rem; font-size: 0.875rem; color: var(--muted); }
@media (max-width: 46rem) { .card-gallery { grid-template-columns: 1fr; } }
.card-gallery a { display: block; text-decoration: none; border-radius: 10px; }
.card-gallery a:hover img, .card-gallery a:focus-visible img { border-color: var(--accent); }
.card-gallery a:hover figcaption { color: var(--accent-text); }

/* The infra entries carry the irq9 family marks from the retired identity
   page: gateway for the network, stacked nodes for compute and operations, a
   vault for identity. Same 48-unit grid and 2px line as the brand mark. */
.work-index > li:has(.entry-mark) { display: grid; grid-template-columns: 44px 1fr; column-gap: 1rem; row-gap: .5rem; align-items: start; }
.work-index > li:has(.entry-mark) > h2,
.work-index > li:has(.entry-mark) > p { grid-column: 2; }
/* The heading's own top margin sits inside its grid area, so centring the mark
   against that area put it half the margin high. The grid's row spacing is what
   separates these rows, not the margin. */
.work-index > li:has(.entry-mark) > h2 { margin-top: 0; }
/* The mark occupies the heading's row alone and centres in it. Spanning both
   rows aligned it to the top of the heading-plus-paragraph block, which put it
   about 11px above the heading it labels -- close enough to look accidental
   rather than deliberate, which is worse than an obvious offset. */
.entry-mark { grid-row: 1; align-self: center; width: 44px; height: 44px; display: block; }
