/* ==========================================================================
   p-jsonparser.css — v10, scoped to TWO pages only:
     jsonparser.html      (body[data-page="jsonparser"])
     case-jsonparser.html (body[data-page="case-jsonparser"])

   Loads LAST in both heads, after p-proof.css / p-case.css. Every rule is
   scoped with body[data-page] so nothing here can reach another page.
   Colour is token-only; no new palette entries.

   WHY A NEW SHEET. Neither page owns a page-specific stylesheet of its own.
   jsonparser.html loads p-proof.css, whose header binds it to public-proof
   and rsync; case-jsonparser.html loads p-case.css, whose header binds it to
   life-after. Appending jsonparser rules to either would break that sheet's
   own scope contract, so the two pages get one sheet between them.

   Contents
     1. The provenance badge, fourth state  — .pp-chip.is-illus, plus the
        .pp-chip base for case-jsonparser (which does not load p35-pubproof)
     2. The sticky section rail             — .jp-rail (jsonparser only)
     3. The fast path                       — .jp-fast
     4. The accounting strip                — .jp-acct
     5. The two project identities          — .jp-ident
     6. Responsive

   GREEN LAW. Green is machine state. Nothing in this sheet paints a
   provenance badge, a rail cell or an accounting row with --pass.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. THE PROVENANCE BADGE

   p35-pubproof.css §12 defines three of the four badge states on .pp-chip:
     .is-seeded  dashed --stale border + a 6px filled --stale dot
     .is-real    solid border, --ink, no dot
   This sheet adds the fourth:
     .is-illus   solid --label-text border + a 6px HOLLOW dot

   The dot is what separates the three at a glance without colour: filled =
   seeded, hollow = illustrative, absent = real. No state hue is borrowed;
   --pass and --fail stay with verification, per the colour law on both pages.
   -------------------------------------------------------------------------- */

/* case-jsonparser.html does not load p35-pubproof.css, so the base component
   is restated here for that page only, at the same metrics. --stale ships from
   that same sheet's :root, so the token is re-declared on the body element
   (custom properties inherit) rather than reaching for a literal at the chip.
   Same value as p35-pubproof.css §1 and p35-product.css: amber, 4.9:1 on the
   terminal card. */
body[data-page="case-jsonparser"]{ --stale:#AF7317; }
body[data-page="case-jsonparser"] .pp-chip{
  display:inline-flex;align-items:center;gap:.4em;
  padding:.14rem .42rem;border-radius:0;
  font-family:var(--mono);font-size:max(12px,.68rem);font-weight:600;letter-spacing:.12em;
  color:inherit;border:1px solid currentColor;
  vertical-align:.06em;
}
body[data-page="case-jsonparser"] .pp-chip.is-seeded{
  color:var(--stale,var(--muted));border-color:var(--stale,var(--muted));border-style:dashed;
}
body[data-page="case-jsonparser"] .pp-chip.is-seeded::before{
  content:"";flex:0 0 auto;width:6px;height:6px;border-radius:50%;
  background:var(--stale,var(--muted));
}
body[data-page="case-jsonparser"] .pp-chip.is-real{color:var(--ink);}

/* The fourth state, on both pages. */
body[data-page="jsonparser"] .pp-chip.is-illus,
body[data-page="case-jsonparser"] .pp-chip.is-illus{
  color:var(--label-text,var(--muted));
  border-color:var(--label-text,var(--muted));
  border-style:solid;
}
body[data-page="jsonparser"] .pp-chip.is-illus::before,
body[data-page="case-jsonparser"] .pp-chip.is-illus::before{
  content:"";flex:0 0 auto;width:6px;height:6px;border-radius:50%;
  background:none;border:1px solid currentColor;
}

/* Terminal flattens every corner (DESIGN.md); p-proof.css already does this
   for public-proof. Same flattening for the chips these two pages render. */
body[data-page="jsonparser"] .pp-chip{border-radius:0;}

/* A badge that sits at the head of a caption or a card needs air after it. */
body[data-page="jsonparser"] .frame-cap .pp-chip,
body[data-page="jsonparser"] .fig-cap .pp-chip,
body[data-page="case-jsonparser"] .fig-cap .pp-chip{margin-right:.45rem;}

/* Badge line above a figure, a card or a tile list: the chip on its own row,
   so provenance is read before the artefact rather than after it. */
/* Normal block flow, NOT flex: in a flex container the run of text after the
   chip becomes one anonymous item and its leading separator lands alone at the
   start of the wrapped line. Inline flow keeps the separator with its clause. */
body[data-page="jsonparser"] .jp-badge,
body[data-page="case-jsonparser"] .jp-badge{
  display:block;
  margin:0 0 .7rem;
  font-family:var(--mono);font-size:max(12px,.74rem);line-height:1.9;
  color:var(--muted);text-wrap:pretty;
}
body[data-page="jsonparser"] .jp-badge .pp-chip,
body[data-page="case-jsonparser"] .jp-badge .pp-chip{margin-right:.4rem;}
body[data-page="jsonparser"] .jp-badge b,
body[data-page="case-jsonparser"] .jp-badge b{font-weight:500;color:var(--ink-60);}

/* --------------------------------------------------------------------------
   2. THE STICKY SECTION RAIL (jsonparser.html only)

   Same chassis as p35-method.css's .mp-rail and p-practice.css's .tr-route:
   mono cells, an <i> index and a <span> label, hairline separators, --signal
   on hover. Copied rather than imported because neither sheet is loaded here
   and both carry a page's worth of unrelated rules.

   It sticks BELOW the floating pill nav, at exactly the header block's height
   (--nav-top + --header-h), and under it in z-order (the header is z-20), so
   the two can never draw over each other. The pill is transparent-backed, so
   the rail carries the same --wash + blur the pill does.

   One scrollable row at every width. A wrapping grid would be two or three
   rows tall when stuck, which is what makes a sticky index eat a phone
   viewport; a single 38px row cannot. The row scrolls inside its own
   container, so the document never gains horizontal scroll.
   -------------------------------------------------------------------------- */
body[data-page="jsonparser"] .jp-rail{
  position:sticky;
  top:calc(var(--nav-top) + var(--header-h));
  z-index:15;
  background:var(--wash);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);
          backdrop-filter:blur(14px) saturate(1.4);
  border-top:1px solid var(--hair);
  border-bottom:1px solid var(--hair-strong);
}
body[data-page="jsonparser"] .jp-rail-in{
  display:flex;align-items:baseline;gap:0;
  width:100%;max-width:calc(var(--maxw) + 2 * var(--gutter));
  margin:0 auto;padding:0 var(--gutter);
  overflow-x:auto;overscroll-behavior-x:contain;
  scrollbar-width:none;-ms-overflow-style:none;
}
body[data-page="jsonparser"] .jp-rail-in::-webkit-scrollbar{width:0;height:0;display:none;}
body[data-page="jsonparser"] .jp-rail a{
  flex:0 0 auto;
  display:flex;align-items:baseline;gap:.5em;
  padding:.62rem .85rem;text-decoration:none;white-space:nowrap;
  font-family:var(--mono);font-size:max(12px,.72rem);line-height:1.45;letter-spacing:.01em;
  color:var(--ink-60);transition:color .18s ease,background .18s ease;
}
body[data-page="jsonparser"] .jp-rail a + a{border-left:1px solid var(--hair);}
/* --unknown is a stroke token and fails the label contrast floor in several
   theme forks; small text a human reads takes --label-text, as .mp-rail does. */
body[data-page="jsonparser"] .jp-rail a i{
  flex:0 0 auto;font-style:normal;font-weight:600;letter-spacing:.08em;
  color:var(--label-text,var(--muted));
}
body[data-page="jsonparser"] .jp-rail a:hover{color:var(--signal);background:var(--card);}
body[data-page="jsonparser"] .jp-rail a:hover i{color:var(--signal);}

/* site.css sets scroll-padding-top for the pill nav alone. The rail adds its
   own height on top of that, or a jumped-to heading lands underneath it. */
body[data-page="jsonparser"] main [id]{
  scroll-margin-top:calc(var(--nav-top) + var(--header-h) + 3.6rem);
}

/* --------------------------------------------------------------------------
   3. THE FAST PATH
   Three destinations, same cell chassis as the rail, one size larger. It is
   NOT sticky: it is a one-time offer at the top of the page.
   -------------------------------------------------------------------------- */
body[data-page="jsonparser"] .jp-lab{
  margin:0 0 .8rem;
  font-family:var(--mono);font-size:max(12px,.72rem);font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--label-text,var(--muted));
}
body[data-page="jsonparser"] .jp-lab + *{margin-top:0;}
body[data-page="jsonparser"] .jp-fast{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0;
  margin:0 0 clamp(2.4rem,4vw,3.4rem);
  border-top:1px solid var(--hair-strong);border-left:1px solid var(--hair);
}
body[data-page="jsonparser"] .jp-fast a{
  display:flex;flex-direction:column;gap:.3rem;min-width:0;
  padding:.95rem 1rem;text-decoration:none;
  border-right:1px solid var(--hair);border-bottom:1px solid var(--hair);
  transition:color .18s ease,background .18s ease;
}
body[data-page="jsonparser"] .jp-fast a i{
  font-style:normal;font-family:var(--mono);font-weight:600;
  font-size:max(12px,.72rem);letter-spacing:.14em;text-transform:uppercase;
  color:var(--label-text,var(--muted));
}
body[data-page="jsonparser"] .jp-fast a span{
  min-width:0;font-family:var(--prose,var(--sans));font-size:1rem;line-height:1.4;
  color:var(--ink-60);text-wrap:pretty;
}
body[data-page="jsonparser"] .jp-fast a:hover{background:var(--card);}
body[data-page="jsonparser"] .jp-fast a:hover i,
body[data-page="jsonparser"] .jp-fast a:hover span{color:var(--signal);}

/* --------------------------------------------------------------------------
   4. THE ACCOUNTING STRIP
   Every row is a count, the object type it counts, and where you count it.
   The count is mono and large; the population is the heading a reader needs
   before the number means anything, so it is set brighter than the source.
   -------------------------------------------------------------------------- */
body[data-page="jsonparser"] .jp-acct{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0;
  margin:0;
  border-top:1px solid var(--hair-strong);border-left:1px solid var(--hair);
}
/* The count column is a FIXED width, not auto: "123" and "2" must hang on the
   same rail or the six populations stop reading as one table. 4.4rem clears
   three digits at the clamp ceiling. */
body[data-page="jsonparser"] .jp-acct > div{
  display:grid;grid-template-columns:4.4rem minmax(0,1fr);
  gap:.1rem .9rem;align-items:baseline;
  padding:1rem 1.1rem 1.05rem;
  border-right:1px solid var(--hair);border-bottom:1px solid var(--hair);
}
body[data-page="jsonparser"] .jp-acct dt{
  grid-row:1 / span 2;
  font-family:var(--mono);font-weight:500;
  font-size:clamp(1.7rem,1.1rem + 1.3vw,2.3rem);line-height:1;
  letter-spacing:-.02em;color:var(--ink);
  font-variant-numeric:tabular-nums;
}
body[data-page="jsonparser"] .jp-acct dd{margin:0;min-width:0;}
body[data-page="jsonparser"] .jp-acct dd b{
  display:block;font-family:var(--mono);font-weight:600;
  font-size:max(12px,.72rem);letter-spacing:.11em;text-transform:uppercase;
  line-height:1.4;color:var(--ink-60);
}
body[data-page="jsonparser"] .jp-acct dd span{
  display:block;margin-top:.32rem;
  font-family:var(--prose,var(--sans));font-size:.92rem;line-height:1.5;
  color:var(--muted);text-wrap:pretty;
}
body[data-page="jsonparser"] .jp-acct dd code{font-size:.86em;overflow-wrap:anywhere;}
body[data-page="jsonparser"] .jp-acct-src{
  margin:.9rem 0 clamp(2.4rem,4vw,3.4rem);max-width:74ch;
}
body[data-page="jsonparser"] .jp-acct-src code{overflow-wrap:anywhere;}

/* --------------------------------------------------------------------------
   5. THE TWO PROJECT IDENTITIES
   The page's hardest fact: one name, two things. Two rows, each carrying its
   own badge, so a reader never has to remember which is which.
   -------------------------------------------------------------------------- */
body[data-page="jsonparser"] .jp-ident{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0;
  margin:0;
  border-top:1px solid var(--hair-strong);border-left:1px solid var(--hair);
}
body[data-page="jsonparser"] .jp-ident > div{
  padding:1.15rem 1.2rem 1.3rem;
  border-right:1px solid var(--hair);border-bottom:1px solid var(--hair);
}
body[data-page="jsonparser"] .jp-ident-k{
  margin:0 0 .55rem;
  font-family:var(--mono);font-size:max(12px,.7rem);font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--label-text,var(--muted));
}
body[data-page="jsonparser"] .jp-ident-n{
  margin:0 0 .7rem;
  font-family:var(--mono);font-size:1.16rem;font-weight:500;letter-spacing:-.01em;
  color:var(--ink);overflow-wrap:anywhere;
}
body[data-page="jsonparser"] .jp-ident-b{margin:0 0 .8rem;}
body[data-page="jsonparser"] .jp-ident p.jp-ident-t{
  margin:0;max-width:52ch;
  font-family:var(--prose,var(--sans));font-size:.98rem;line-height:1.55;color:var(--ink-60);
}
body[data-page="jsonparser"] .jp-ident p.jp-ident-t + p.jp-ident-t{margin-top:.6rem;color:var(--muted);}
body[data-page="jsonparser"] .jp-ident code{overflow-wrap:anywhere;}

/* The opening section runs three blocks under one heading; keep them from
   colliding with the hero above and the rail below. */
body[data-page="jsonparser"] .hero .cta-row{margin-top:1.5rem;}
body[data-page="jsonparser"] .hero .fine{margin-top:1.15rem;max-width:58ch;line-height:1.55;}
body[data-page="jsonparser"] .jp-cta{
  display:flex;flex-wrap:wrap;align-items:center;gap:.7rem;
  margin:clamp(1.4rem,2.4vw,1.9rem) 0 .7rem;
}
body[data-page="jsonparser"] .jp-cta .btn-primary{min-height:44px;}
body[data-page="jsonparser"] .jp-open{padding-top:clamp(1.6rem,3vw,2.6rem);padding-bottom:clamp(2.4rem,4vw,3.4rem);}
body[data-page="jsonparser"] .jp-fast a:first-child{
  background:rgba(43,255,111,.07);
}
body[data-page="jsonparser"] .jp-fast a:first-child i{color:var(--signal);}


/* --------------------------------------------------------------------------
   6. RESPONSIVE — checked at 1440, 768 and 390
   -------------------------------------------------------------------------- */
@media (max-width:1020px){
  body[data-page="jsonparser"] .jp-acct{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width:760px){
  body[data-page="jsonparser"] .jp-fast{grid-template-columns:1fr;}
  body[data-page="jsonparser"] .jp-acct{grid-template-columns:1fr;}
  body[data-page="jsonparser"] .jp-ident{grid-template-columns:1fr;}
  body[data-page="jsonparser"] .jp-acct > div{grid-template-columns:3.4rem minmax(0,1fr);padding:.85rem .9rem .9rem;}
  body[data-page="jsonparser"] .jp-rail a{padding:.58rem .7rem;}
}
