/* I'm not paranoid. I'm early. (Lab Notes, 3 Nov 2026). Loaded after blog.css on the post and the index.
   The hero art is her "Verify it's you" card (blog/img/verify-its-you.webp). CSS only: the site CSP allows no script. */

.np-hero .hero-grid { align-items: center; }
.np-hero .np-art { flex: 1 1 300px; display: flex; justify-content: center; }
.np-verify { width: 100%; max-width: 24rem; height: auto; mix-blend-mode: lighten; }   /* the picture's black ground melts into the page */
.np-by { margin: 14px 0 0; font: 600 0.8rem/1.4 var(--mono); letter-spacing: 0.08em; color: var(--faint); }

/* Lab Notes index card */
.np-card-art { display: flex; align-items: center; justify-content: center; padding: clamp(14px, 3vw, 28px); background: #050507; }
.np-card-art img { mix-blend-mode: lighten; }
.np-card-art img { width: auto; max-height: 26rem; }

.np-five { counter-reset: n; }
.np-five li::before { counter-increment: n; content: counter(n); display: grid; place-items: center; width: 18px; height: 18px; left: -11px; top: 2px;
  font: 700 0.66rem/1 var(--mono); color: var(--cyan); }

/* Tick what already happened to you. No script: the circle is the checkbox, a CSS counter adds up the ticks,
   and :has() picks which verdict line shows. The box stays in the tab order (visually hidden, not display:none). */
.np-tick { counter-reset: shrug; }
.np-tick li { padding-bottom: 18px; }
.np-tick label { display: block; cursor: pointer; }
.np-tick input { position: absolute; left: -9px; top: 4px; width: 16px; height: 16px; margin: 0; opacity: 0; cursor: pointer; }
.np-tick li:has(input:checked) { counter-increment: shrug; }
.np-tick li:has(input:checked)::before { background: var(--red); border-color: var(--red); box-shadow: 0 0 12px rgba(248, 113, 113, 0.55); }
.np-tick li:has(input:focus-visible)::before { outline: 2px solid var(--cyan); outline-offset: 3px; }
.np-tick li:has(input:checked) b { color: var(--red); text-decoration: line-through; text-decoration-color: rgba(248, 113, 113, 0.6); }
/* The score is the list's last item, so a sibling chain can count the ticks before it (:has() can't nest). */
.np-tick li.np-score { margin-top: 8px; padding: 16px 20px; border: 1px solid var(--line); border-radius: 14px; background: var(--panel); color: var(--body); }
.np-tick li.np-score::before { display: none; }
.np-score .n { font: 700 1.6rem/1 var(--display); color: var(--hi); }
.np-score .n::before { content: counter(shrug); }
/* one verdict line per band: none, 1-2, 3-4, 5 or more */
.np-band { display: none; margin: 6px 0 0; }
.np-tick .np-b0 { display: block; }
.np-tick li:has(input:checked) ~ .np-score .np-b0 { display: none; }
.np-tick li:has(input:checked) ~ .np-score .np-b1 { display: block; }
.np-tick li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score .np-b1 { display: none; }
.np-tick li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score .np-b3 { display: block; }
.np-tick li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score .np-b3 { display: none; }
.np-tick li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score .np-b5 { display: block; }

/* fold-outs */
.np-hero ~ .section details, .section details { margin-top: 18px; border: 1px solid var(--line); border-radius: 14px; background: var(--panel); }
.section summary { padding: 14px 20px; cursor: pointer; font: 600 0.78rem/1.4 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--cyan); }
.section details[open] summary { border-bottom: 1px solid var(--line); }
.section details p { margin: 12px 20px; color: var(--body); }
.section details :is(p, ul):last-child { margin-bottom: 16px; }

/* four forecaster cards: two even rows instead of three plus one alone */
.panels.np-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 720px) { .panels.np-two { grid-template-columns: 1fr; } }

/* section art */
.np-fig { max-width: 30rem; margin: 1.4rem 0 1.8rem; overflow: hidden; border: 1px solid var(--line); border-radius: 6px; }
.np-fig img { display: block; width: 100%; height: auto; }
/* art comes into focus as it scrolls in. No script; browsers without scroll timelines just show the picture. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .np-fig img { animation: np-focus linear both; animation-timeline: view(); animation-range: entry 0% cover 38%; }
    @keyframes np-focus {
      from { filter: blur(18px) saturate(0.4); opacity: 0; transform: scale(1.08); }
      to { filter: none; opacity: 1; transform: none; }
    }
  }
}

/* tick lists show real boxes: square, with a check when ticked */
.np-tick li:not(.np-score)::before { left: -11px; top: 2px; width: 18px; height: 18px; border-radius: 4px; display: grid; place-items: center;
  font: 700 0.8rem/1 var(--mono); color: var(--bg); }
.np-tick li:has(input:checked)::before { content: "\2713"; }
.np-tick input { left: -11px; top: 2px; width: 18px; height: 18px; }

/* np-magnet: cards pull toward the pointer. The one you hover lifts and glows, its neighbours back off.
   No script, so it can't track the cursor; this is the springy lift instead. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .why p, .panels .panel { transition: transform 0.38s cubic-bezier(0.2, 1.7, 0.4, 1), border-color 0.25s, box-shadow 0.3s, opacity 0.25s; will-change: transform; }
  .why p:hover, .panels .panel:hover { transform: translateY(-7px) scale(1.025); border-color: rgba(34, 211, 238, 0.55);
    box-shadow: 0 20px 48px rgba(34, 211, 238, 0.14), 0 0 0 1px rgba(34, 211, 238, 0.18); z-index: 1; }
  .why:hover p:not(:hover), .panels:hover .panel:not(:hover) { transform: scale(0.985); opacity: 0.62; }
}

/* np-volt: electric border around a tick list. Still and dim until the first tick, then it moves.
   Each tick turns it from yellow through orange to red and turns the crackle and glow up.
   The frame is drawn by the score row's ::after (the score row is the only thing the tick count can reach
   without a script), stretched over the whole list. The jagged edge is an SVG filter in the page. */
.np-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.np-prompt { display: inline-block; margin-top: 24px; padding: 11px 18px; border: 1px solid rgba(34, 211, 238, 0.6); border-radius: 12px;
  box-shadow: 0 0 16px rgba(34, 211, 238, 0.38), inset 0 0 12px rgba(34, 211, 238, 0.12); }
.np-prompt mark { background: none; color: var(--cyan-lift); font-weight: 600;
  text-shadow: 0 0 8px rgba(34, 211, 238, 0.8), 0 0 22px rgba(34, 211, 238, 0.4); }
.np-volt { position: relative; max-width: 48rem; margin-top: 22px; padding: 6px 22px 22px 30px; border-radius: 18px; }
.np-volt .np-tick li.np-score { position: static; }
.np-volt .np-score::after { content: ""; position: absolute; inset: 0; border-radius: 18px; pointer-events: none;
  border: var(--width, 2px) solid var(--volt, rgba(34, 211, 238, 0.55));
  box-shadow: 0 0 var(--glow, 10px) var(--volt, rgba(34, 211, 238, 0.4)), inset 0 0 var(--glow, 10px) var(--volt, rgba(34, 211, 238, 0.4));
  filter: url(#np-volt-0); transition: border-color 0.4s, box-shadow 0.4s; }
.np-volt li:has(input:checked) ~ .np-score { --volt: hsl(52 100% 55%); --glow: 7px; --width: 2px; }
.np-volt li:has(input:checked) ~ .np-score::after { filter: url(#np-volt-1); }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ .np-score { --volt: hsl(45 100% 55%); --glow: 10px; --width: 2px; }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ .np-score::after { filter: url(#np-volt-1); }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score { --volt: hsl(37 100% 55%); --glow: 13px; --width: 2px; }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score::after { filter: url(#np-volt-2); }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score { --volt: hsl(30 100% 55%); --glow: 16px; --width: 2px; }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score::after { filter: url(#np-volt-2); }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score { --volt: hsl(22 100% 55%); --glow: 19px; --width: 2px; }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score::after { filter: url(#np-volt-2); }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score { --volt: hsl(15 100% 55%); --glow: 22px; --width: 3px; }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score::after { filter: url(#np-volt-3); }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score { --volt: hsl(7 100% 55%); --glow: 25px; --width: 3px; }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score::after { filter: url(#np-volt-3); }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score { --volt: hsl(0 100% 55%); --glow: 28px; --width: 3px; }
.np-volt li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ li:has(input:checked) ~ .np-score::after { filter: url(#np-volt-3); }
@media (prefers-reduced-motion: reduce) { .np-volt .np-tick .np-score::after { filter: url(#np-volt-0) !important; } }

/* np-fx: scroll effects for a page whose <body> carries np-fx. Titles wipe in with a red/cyan split that settles;
   every block of text rises out of a blur. Driven by scroll position, no script. Fill is "backwards" only, so once
   a block has arrived the animation lets go and hover effects on cards still work. The score row is left out:
   moving it would drag the electric frame with it. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .np-fx .section h2 { animation: np-title linear backwards; animation-timeline: view(); animation-range: entry 0% cover 30%; }
    .np-fx .section > p, .np-fx .section li:not(.np-score), .np-fx .section .why p, .np-fx .section .panel, .np-fx .section details {
      animation: np-rise linear backwards; animation-timeline: view(); animation-range: entry 0% cover 24%; }
    .np-fx .section .sources li { animation: none; }
    @keyframes np-rise {
      from { opacity: 0; translate: 0 28px; filter: blur(6px); }
      to { opacity: 1; translate: 0 0; filter: blur(0); }
    }
    @keyframes np-title {
      from { opacity: 0; translate: -36px 0; clip-path: inset(-10% 100% -10% 0); text-shadow: 4px 0 var(--red), -4px 0 var(--cyan); }
      55% { opacity: 1; clip-path: inset(-10% 0 -10% 0); text-shadow: 3px 0 var(--red), -3px 0 var(--cyan); }
      to { opacity: 1; translate: 0 0; clip-path: inset(-10% 0 -10% 0); text-shadow: 0 0 transparent, 0 0 transparent; }
    }
  }
}

/* one column: on an np-fx page every title, paragraph, list, card row, tick box and photo shares one width,
   on any screen. Change --np-col to resize all of them together. */
.np-fx { --np-col: 46rem; }
.np-fx .section > * { max-width: var(--np-col); box-sizing: border-box; margin-left: auto; margin-right: auto; }
.np-fx .section > .np-prompt { display: block; }
.np-fx .section > .np-fig { width: 100%; }

/* attention lines: the opening sentence of each section and the bolded punch lines */
.np-lead, .np-fx .section > p strong { color: var(--cyan-lift); font-weight: 600; }

/* np-gf: Glitchface chimes in, drawn as a plain incoming chat message: round avatar, name above, flat grey bubble. */
.np-gf { display: block; position: relative; width: fit-content; max-width: min(28rem, calc(100% - 48px)); margin: 30px 0 10px 48px; padding: 9px 14px 10px;
  border-radius: 18px 18px 18px 5px; background: #262631; color: #ececf4; font-size: 0.95rem; line-height: 1.45; }
.np-gf::before { content: ""; position: absolute; left: -48px; bottom: 0; width: 38px; height: 38px; border-radius: 50%;
  background: #000 url(/blog/img/gf-avatar.webp) center / cover no-repeat; }
.np-gf::after { content: "Glitchface"; position: absolute; left: 14px; top: -19px; font-size: 0.72rem; line-height: 1; color: var(--muted); white-space: nowrap; }
.np-fx .section > .np-gf { max-width: min(28rem, calc(100% - 48px)); margin-right: auto; margin-left: calc(max(0px, (100% - var(--np-col)) / 2) + 48px); }
