/* PHP2Shell special report · loads AFTER site.css and cti-report-september-2026.css
   Adds the heap-grid cover art, status chips, the SAPI matrix, myth/fact cards and code blocks.
   Colours come from the shared tokens, so every figure works in light and dark mode. */

/* ---------- cover art: a worker heap with freed cells and a dangling pointer ---------- */
.cover-art.heap{-webkit-mask-image:linear-gradient(90deg,transparent 0,#000 18%);mask-image:linear-gradient(90deg,transparent 0,#000 18%)}
.heap .cell{fill:var(--card);stroke:var(--line);stroke-width:1}
.heap .cell.live{fill:color-mix(in srgb,var(--accent) 22%,var(--card));stroke:color-mix(in srgb,var(--accent) 55%,var(--line))}
.heap .cell.freed{fill:url(#heapHatch);stroke:var(--k-red);stroke-dasharray:3 3}
.heap .cell.reclaimed{fill:color-mix(in srgb,var(--k-orange) 30%,var(--card));stroke:var(--k-orange)}
.heap .ptr{stroke:var(--k-red);stroke-width:2;fill:none}
.heap .ptr-head{fill:var(--k-red)}
.heap .lab{font:11px var(--mono);letter-spacing:1px;fill:var(--fg);opacity:.85}
.heap .lab-r{font:700 11px var(--mono);letter-spacing:1px;fill:var(--k-red)}
.heap .hatch-l{stroke:var(--k-red);stroke-width:1.2;opacity:.55}
@keyframes heapPulse{0%,100%{opacity:.35}50%{opacity:1}}
@keyframes dash{to{stroke-dashoffset:-24}}
.heap .pulse{animation:heapPulse 2.4s ease-in-out infinite}
.heap .ptr{stroke-dasharray:6 6;animation:dash 1.6s linear infinite}
@media (prefers-reduced-motion:reduce){.heap .pulse,.heap .ptr{animation:none}}

.cover-kicker .badge.special{background:var(--k-red);border-color:var(--k-red);color:#fff}
:root[data-theme=dark] .cover-kicker .badge.special{color:var(--ink-on-k)}

/* 48-hour strip under the dek */
.cover-strip .h48 .tick{stroke:var(--line)}
.cover-strip .h48 .band{fill:color-mix(in srgb,var(--k-red) 14%,transparent)}
.cover-strip .h48 .rail{stroke:var(--muted);stroke-width:1}

/* ---------- status chips (matrix, tables) ---------- */
.st{display:inline-block;font:700 10px/1 var(--mono);letter-spacing:.6px;text-transform:uppercase;padding:5px 8px;border-radius:4px;border:1px solid currentColor;white-space:nowrap}
.st.bad{color:var(--k-red);background:color-mix(in srgb,var(--k-red) 9%,transparent)}
.st.warn{color:var(--k-orange);background:color-mix(in srgb,var(--k-orange) 9%,transparent)}
.st.ok{color:var(--k-green);background:color-mix(in srgb,var(--k-green) 9%,transparent)}
.st.na{color:var(--muted)}
.page-report .tbl td .st{margin:1px 0}
.page-report .tbl td small{display:block;color:var(--muted);font-size:12px;line-height:1.55;margin-top:6px}

/* ---------- myth vs fact cards ---------- */
.myths{display:grid;gap:12px;margin:24px 0}
.myth{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.35fr);border:1px solid var(--line);border-radius:8px;overflow:hidden;background:var(--card)}
.myth>div{padding:16px 18px}
.myth .m{border-right:1px solid var(--line);background:color-mix(in srgb,var(--k-red) 5%,var(--card))}
.myth .tag{display:block;font:700 10px var(--mono);letter-spacing:1.3px;text-transform:uppercase;margin-bottom:6px}
.myth .m .tag{color:var(--k-red)} .myth .f .tag{color:var(--k-green)}
.myth p{margin:0!important;font-size:14px!important;line-height:1.7!important}
.myth .m p{font-weight:600;color:var(--fg)}
.myth .f p{color:var(--muted)}
@media (max-width:700px){.myth{grid-template-columns:1fr}.myth .m{border-right:0;border-bottom:1px solid var(--line)}}

/* ---------- state-family cards ---------- */
.states{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:22px 0}
.states>div{padding:16px 18px;background:var(--card);border:1px solid var(--line);border-radius:8px;border-top:3px solid var(--kc,var(--k-red))}
.states code{font-size:12.5px}
.states h4{font:600 14.5px/1.4 var(--sans)!important;margin:8px 0 6px!important}
.states p{font-size:13.5px!important;line-height:1.7!important;color:var(--muted);margin:0!important}
.states .tag{font:10.5px var(--mono);letter-spacing:1.2px;text-transform:uppercase;color:var(--kc,var(--k-red))}
@media (max-width:760px){.states{grid-template-columns:1fr}}

/* ---------- code blocks ---------- */
.page-report .codeblock{margin:22px 0}
.page-report .codeblock .cb-h{display:flex;justify-content:space-between;gap:12px;font:700 10.5px var(--mono);letter-spacing:1.2px;text-transform:uppercase;color:var(--muted);padding:10px 16px;border:1px solid var(--line);border-bottom:0;border-radius:10px 10px 0 0;background:var(--card)}
.page-report .codeblock pre{margin:0;border-radius:0 0 10px 10px;padding:16px;overflow-x:auto;font-size:12.5px;line-height:1.7}
.page-report .codeblock .c{color:var(--muted)}
.page-report .codeblock .k{color:var(--accent);font-weight:600}
.page-report .codeblock .r{color:var(--k-red)}

/* ---------- pull quote ---------- */
.pull{margin:30px 0;padding:14px 0 0;border-top:1.5px solid var(--fg);font:500 clamp(18px,2vw,22px)/1.5 var(--sans);color:var(--fg);letter-spacing:-.3px}
.pull span{display:block;margin-top:10px;font:12px var(--mono);color:var(--muted);letter-spacing:0}

/* figure helpers */
.fig .lane{fill:color-mix(in srgb,var(--fg) 3%,transparent)}
.fig .warnband{fill:color-mix(in srgb,var(--k-red) 10%,transparent)}
.fig .okband{fill:color-mix(in srgb,var(--k-green) 10%,transparent)}
.fig .dash{stroke-dasharray:4 4}
.fig .s-acc{fill:var(--accent)}
.fig .st-acc{stroke:var(--accent);fill:none}
.fig .s-red{fill:var(--k-red)} .fig .s-org{fill:var(--k-orange)} .fig .s-grn{fill:var(--k-green)} .fig .s-blu{fill:var(--k-blue)}
.fig .bx-acc{fill:color-mix(in srgb,var(--accent) 14%,var(--card));stroke:var(--accent)}
.fig .bx-plain{fill:var(--card);stroke:var(--line)}
.fig .bar-del{fill:color-mix(in srgb,var(--k-red) 70%,var(--card))}

/* dark mode: --line and --k-grey sit too close to the dark card, so outlines, gridlines and
   "approximate" markers in the figures get a stronger, still theme-derived colour */
:root[data-theme=dark] .page-report .fig :is(.bx,.bx-plain){fill:color-mix(in srgb,var(--fg) 5%,var(--card));stroke:color-mix(in srgb,var(--fg) 30%,var(--card))}
:root[data-theme=dark] .page-report .fig .bx-grey{stroke:color-mix(in srgb,var(--fg) 45%,var(--card))}
:root[data-theme=dark] .page-report .fig .s-grid{stroke:color-mix(in srgb,var(--fg) 16%,var(--card))}
:root[data-theme=dark] .page-report .fig .s-axis{stroke:color-mix(in srgb,var(--fg) 45%,var(--card))}
:root[data-theme=dark] .page-report .fig .b-grey{fill:color-mix(in srgb,var(--fg) 58%,var(--card))}
:root[data-theme=dark] .page-report .fig .lane{fill:color-mix(in srgb,var(--fg) 6%,transparent)}
:root[data-theme=dark] .page-report .fig :is(.arrow){stroke:color-mix(in srgb,var(--fg) 55%,var(--card))}
:root[data-theme=dark] .page-report .fig .arw-fill{fill:color-mix(in srgb,var(--fg) 55%,var(--card))}
:root[data-theme=dark] .cover-strip .h48 .tick{stroke:color-mix(in srgb,var(--fg) 22%,transparent)}
:root[data-theme=dark] .cover-strip .h48 .band{fill:color-mix(in srgb,var(--k-red) 24%,transparent)}
/* screenshots of posts are light images; soften their glare on a dark page */
:root[data-theme=dark] .post-card .shot{background:#fff;filter:brightness(.92)}

/* keep the heap artwork behind, not through, the intro text on narrower windows */
@media (max-width:1180px){.cover-art.heap,html.js .article-head>.cover-art.heap.is-in{opacity:.26}}
@media (max-width:700px){.cover-art.heap,html.js .article-head>.cover-art.heap.is-in{opacity:.14}}
/* phones: the 48-hour strip keeps a readable size and scrolls sideways instead of shrinking */
@media (max-width:640px){.cover-strip .h48-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;margin-right:-20px;padding-right:20px}.cover-strip .h48-scroll svg{min-width:600px}}

/* ---------- screenshots of public posts ---------- */
.posts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;margin:26px 0;align-items:start}
.post-card{display:flex;flex-direction:column;background:var(--card);border:1px solid var(--line);border-radius:10px;overflow:hidden}
.post-card .shot{display:block;background:#fff;border-bottom:1px solid var(--line)}
.post-card img{display:block;width:100%;height:auto}
.post-card .role{padding:14px 16px 0;font:700 10.5px var(--mono);letter-spacing:1.1px;text-transform:uppercase;color:var(--accent)}
.post-card .who{padding:4px 16px 0;font:600 15px/1.4 var(--sans);color:var(--fg)}
.post-card .who span{font:400 12px var(--mono);color:var(--muted);margin-left:6px}
.post-card p{padding:8px 16px 0;margin:0;font-size:13.5px;line-height:1.7;color:var(--muted)}
.post-card .meta{padding:10px 16px 14px;font:11.5px/1.6 var(--mono);color:var(--muted)}
.post-card .meta a{color:var(--fg);text-decoration:underline;text-decoration-color:var(--line)}
@media (max-width:760px){.posts{grid-template-columns:1fr}}

/* tablets: tables fit the column instead of scrolling sideways */
@media (max-width:1024px){
  .page-report .tbl table,.page-report .tbl table:has(th){min-width:0}
  .page-report .tbl td code{white-space:normal;overflow-wrap:anywhere}
  .page-report .tbl th{white-space:normal}
}
/* the animated canvas cover replaces the static heap drawing when scripts run */
.cover-art.heap.gl-on svg{display:none}
.cover-art.heap canvas{position:absolute;inset:0}
