/*
 * What's New issue pages — plan whats-new-editorial-redesign: phase 1's static
 * rules, and phase 2's motion layer (reveals, stamps, the compact bar's slide,
 * the title sparkle's twinkle, the More issues hover lift) and Play GIF button.
 *
 * Loaded AFTER /assets/articles/article.css (pageShell), whose theme-v2
 * palette, fonts, chrome and shared ed-* editorial kit this page composes:
 * tints, wash and blobs, .ed-meta, .ed-tagline, .ed-kicker, .ed-section-h,
 * .ed-pills/.ed-pill (the audience switch), the .ed-cover index card with its
 * underline, sticker and sparkle, and the clear on-wash site header. This
 * file never redefines a kit rule; it keeps only the changelog's own pieces
 * from the committed mockup (docs/whats-new/design/editorial-redesign/wn.css)
 * plus the page-local overrides the kit leaves to each page. Linked
 * content-versioned (publicAssetHref('whats-new', 'whats-new.css')).
 * Server-side asset, outside the client design-system ratchets.
 */

/* ------------------------------------------------------------ token aliases */
/* The ported mockup rules keep their --wn-* names; each aliases the kit's --a-* token (article.css :root). */
:root {
  --wn-cobalt: var(--a-brand);
  --wn-cobalt-700: var(--a-primary-700);
  --wn-cobalt-50: var(--a-brand-subtle);
  --wn-gold-ink: var(--a-accent-ink);
  --wn-ink: var(--a-text);
  --wn-ink-2: var(--a-ink-2);
  --wn-muted: var(--a-text-muted);
  --wn-subtle: var(--a-subtle);
  --wn-line: var(--a-border);
  --wn-line-2: var(--a-line-2);
  --wn-paper: var(--a-surface);
  --wn-sunken: var(--a-surface-sunken);
  --wn-display: var(--a-display);
  --wn-sans: var(--a-sans);
  --wn-serif: var(--a-serif);
  --wn-ease: var(--a-ease);
}

/* ------------------------------------------------------------------- page */
.wn-issue { max-width: 76rem; margin: 0 auto; padding: 0 1.25rem 4rem; }
@media (min-width: 768px) { .wn-issue { padding: 0 2rem 5rem; } }
/* Below 768px the issue spans the whole viewport, so clipping it only trims what already sits past the screen edge:
   the kit's 1.6deg backing card behind a very tall cover (a 600-character dek at 320px) swings its corner past the
   1.25rem gutter and would otherwise widen the page. The body's own clip doesn't hide genuine overflow on phones. Wider,
   the full-bleed wash reaches past this container, so it stays unclipped there (and the 2rem gutter absorbs the tilt). */
@media (max-width: 767px) { .wn-issue { overflow-x: clip; } }

/* The switch's short labels (Everyone, Students, Educators) below 480px. */
.wn-short { display: none; }
@media (max-width: 479px) { .wn-short { display: inline; } .wn-long { display: none; } }

/* Focus lands clear of the sticky site header (one row at every width: 65px below 1280px, 81px from 1280px) plus,
   from 768px, the 71px compact bar under it. */
html { scroll-padding-top: 5.5rem; }
@media (min-width: 768px) { html { scroll-padding-top: 9rem; } }
@media (min-width: 1280px) { html { scroll-padding-top: 10rem; } }

/* --------------------------------------------------------------- masthead */
.wn-masthead { position: relative; isolation: isolate; padding: 1.25rem 0 2.25rem; }
/* The kit's clear on-wash header leaves running the wash up behind it to each page (D23). Overshoot rather than
   match the header's height (4rem, 5rem from 1280px): nothing above the top of the
   document is visible or scrollable. The blobs move down by the same 12rem from the kit's resting tops (-6rem, 2rem),
   so the glow stays around the title. */
.wn-masthead > .ed-wash { top: -12rem; }
.wn-masthead .ed-blob-a { top: 6rem; }
.wn-masthead .ed-blob-b { top: 14rem; }

/* The meta row: "Month YYYY · N updates" on the left, the aria-hidden "Issue No." bubbles on the right. */
.wn-meta { display: flex; justify-content: space-between; align-items: center; gap: .75rem; flex-wrap: wrap;
  padding-bottom: .875rem; border-bottom: 1px solid var(--wn-line); }

/* The issue number as filled answer bubbles (practice's selected-choice circle). */
.wn-bubbles { display: inline-flex; gap: .25rem; }
.wn-bubble { display: inline-grid; place-items: center; width: 1.75rem; height: 1.75rem; border-radius: 9999px;
  background: var(--wn-cobalt); color: #fff; font: 800 .9375rem/1 var(--wn-display); letter-spacing: 0;
  box-shadow: inset 0 -2px 0 rgb(0 0 0 / .14); }
.wn-bubbles-sm .wn-bubble { width: 2.25rem; height: 2.25rem; font-size: 1.125rem; background: var(--deep); }
.wn-bubbles-xs .wn-bubble { width: 1.375rem; height: 1.375rem; font-size: .75rem; }

.wn-title { margin: 1.75rem 0 .5rem; text-align: center; font: 800 clamp(3.5rem, 11vw, 8rem)/.9 var(--wn-display);
  letter-spacing: -.045em; color: var(--wn-ink); }
.wn-title-new { position: relative; color: var(--wn-cobalt); }
/* The title's sparkle twinkles with the kit's keyframes, twice (3.2s in all). The articles library renders still; the
   motion section below records why this page differs. */
.wn-title-new .ed-sparkle { position: absolute; width: .32em; height: .32em; right: -.34em; top: -.02em;
  animation: ed-twinkle 1.6s ease-in-out 2; transform-origin: center; }

/* Prev link | switch | next link. The columns are pinned, so a missing side leaves the switch centered. */
.wn-issue-nav { margin-top: 1.75rem; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1rem;
  font: 600 .875rem/1.2 var(--wn-sans); }
.wn-issue-nav > a { display: inline-flex; align-items: center; min-height: 2.75rem; color: var(--wn-muted); text-decoration: none; }
.wn-issue-nav > a:hover { color: var(--wn-cobalt); }
.wn-prev { grid-column: 1; justify-self: start; }
.wn-issue-nav > .ed-pills { grid-column: 2; }
.wn-next { grid-column: 3; justify-self: end; text-align: end; }

@media (max-width: 767px) {
  .wn-meta { justify-content: center; }
  .wn-issue-nav { grid-template-columns: 1fr 1fr; }
  .wn-issue-nav > .ed-pills { grid-column: 1 / -1; grid-row: 1; justify-self: center; }
  .wn-prev { grid-column: 1; grid-row: 2; }
  .wn-next { grid-column: 2; grid-row: 2; }
  .wn-issue-nav .ed-pill { padding: 0 .8rem; font-size: .8125rem; }
}

/* ------------------------------------------------------- compact masthead */
/* Hidden (the [hidden] attribute) until whats-new.js un-hides it, which it does only where IntersectionObserver and
   inert both exist; even then it stays invisible and inert until the masthead has scrolled away (.is-on), then slides
   down into place. One 71px line under the sticky site header, from 768px only. */
.wn-compact { position: sticky; top: 4rem; z-index: 40; height: 0; overflow: visible; }
@media (min-width: 1280px) { .wn-compact { top: 5rem; } }
.wn-compact-inner { max-width: 76rem; margin: 0 auto; display: flex; align-items: center; gap: .75rem; padding: .5rem 2rem;
  background: rgb(255 255 255 / .9); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--wn-line-2); visibility: hidden; transform: translateY(-120%); opacity: 0;
  transition: transform .35s var(--wn-ease), opacity .25s, visibility .35s; }
.wn-compact.is-on .wn-compact-inner { visibility: visible; transform: none; opacity: 1; }
.wn-compact-title { flex: none; font: 800 1.125rem/1 var(--wn-display); letter-spacing: -.02em; color: var(--wn-ink); white-space: nowrap; }
.wn-compact .wn-bubbles { flex: none; }
.wn-compact-month { min-width: 0; margin-right: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 700 .75rem/1 var(--wn-sans); letter-spacing: .12em; text-transform: uppercase; color: var(--wn-muted); }
/* The compact bar's pill row: smaller pills, still 2.75rem tall (the kit's min-height), never wrapping. */
.ed-pills.wn-pills-compact { flex: none; flex-wrap: nowrap; margin: 0; }
.wn-pills-compact .ed-pill { padding: .375rem .75rem; font-size: .8125rem; }
/* Below 1024px the full labels would push the bar past one line at 768px, so it uses the short ones. */
@media (max-width: 1023px) { .wn-pills-compact .wn-long { display: none; } .wn-pills-compact .wn-short { display: inline; } }
@media (max-width: 767px) { .wn-compact { display: none; } }

/* ----------------------------------------------------------------- stamps */
/* Rubber-stamp kind badges: New in cobalt, Improved in the kit's gold ink, Fixed in slate #3C4252. The
   backgrounds are precomputed (no color-mix(): older Safari/Chrome drop the whole declaration). */
.wn-stamp { --ink: var(--wn-cobalt); display: inline-grid; place-items: center; flex: none;
  height: 1.75rem; padding: 0 .75rem; border: 2px solid var(--ink); border-radius: .5rem; color: var(--ink);
  font: 800 .6875rem/1 var(--wn-sans); letter-spacing: .14em; text-transform: uppercase; transform: rotate(-4deg);
  background: var(--stamp-bg, #f1f6ff); }
.wn-stamp-improved { --ink: var(--wn-gold-ink); --stamp-bg: #f8f6f0; }
.wn-stamp-fixed { --ink: #3c4252; --stamp-bg: #f3f4f6; }
.wn-stamp-lg { height: 2.5rem; padding: 0 1.125rem; font-size: .8125rem; border-width: 2.5px; transform: rotate(-8deg); }

.wn-aud { font: 600 .8125rem/1.2 var(--wn-sans); color: var(--wn-muted); }
.wn-feature-meta, .wn-card-meta { font: 600 .8125rem/1.2 var(--wn-sans); color: var(--wn-muted); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------- cover (the kit's index card) */
.wn-cover-top { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: .75rem 1rem; }
/* The cover isn't a link, so the kit's hover lift is neutralized by restating each piece's RESTING kit value
   (never transform: none on the tilted pieces, which would flatten them). */
.ed-cover.wn-cover:hover::before { transform: rotate(1.6deg); }
.ed-cover.wn-cover:hover .ed-cover-card { transform: none; box-shadow: 0 30px 60px -30px rgb(1 61 181 / .35), 0 0 0 1px var(--a-line-2); }
.ed-cover.wn-cover:hover .ed-cover-media { transform: rotate(1.4deg); }
@media (min-width: 1024px) { .ed-cover.wn-cover:hover .ed-cover-media { transform: rotate(2.2deg); } }
/* With media: the tilted frame overlaps the card's right edge from 1024px, so the card keeps 5.5rem clear on its
   right and the frame never covers the dek. The sticker moves left of that overlap too: the frame is centered on the
   card, so on a card not much taller than the frame (a short blurb) the kit's corner spot sits under it. Below 1024px
   the stacked frame would half-cover the sticker, so it goes. */
@media (min-width: 1024px) {
  .wn-cover.has-media .ed-cover-card { padding-right: 5.5rem; }
  .wn-cover.has-media .ed-sticker-star { right: 4.75rem; }
}
@media (max-width: 1023px) { .wn-cover.has-media .ed-sticker-star { display: none; } }

/* -------------------------------------------- media frame (real product captures only) */
.wn-frame { position: relative; margin: 0; border-radius: 1rem; overflow: hidden; background: #fff;
  box-shadow: 0 28px 50px -26px rgb(1 61 181 / .4), 0 0 0 1px rgb(22 26 36 / .08); }
.wn-frame-bar { display: flex; align-items: center; gap: .75rem; height: 2rem; padding: 0 .75rem; background: var(--wn-sunken);
  border-bottom: 1px solid var(--wn-line-2); }
.wn-frame-dots { display: inline-flex; gap: .375rem; flex: none; }
.wn-frame-dots i { width: .5625rem; height: .5625rem; border-radius: 9999px; background: #fecaca; }
.wn-frame-dots i:nth-child(2) { background: #fde68a; }
.wn-frame-dots i:nth-child(3) { background: #bbf7d0; }
.wn-frame-url { flex: 0 1 12rem; margin: 0 auto; height: 1.25rem; border-radius: 9999px; background: #fff; box-shadow: 0 0 0 1px var(--wn-line);
  font: 600 .6875rem/1.25rem var(--wn-sans); color: var(--wn-subtle); text-align: center; }
/* A fixed 16:10 frame on a sunken placeholder, so the layout never shifts while the image loads. */
.wn-frame img { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: top left; background: var(--wn-sunken); }
/* The no-JS "GIF" pill on a poster-first GIF (aria-hidden; the alt text describes both frames). */
.wn-frame-gif { position: absolute; right: .5rem; bottom: .5rem; padding: .125rem .5rem; border-radius: 9999px;
  background: rgb(15 23 42 / .62); color: #fff; font: 800 .6875rem/1.4 var(--wn-sans); letter-spacing: .04em; pointer-events: none; }
/* The Play GIF / Pause GIF button whats-new.js injects (D18: the only way to play; its text is its name), which
   replaces the pill. A pill in the frame's bottom-right corner, 2.75rem tall at every width; the glyph is decoration,
   and the transparent border draws the pill's edge in forced-colors mode. */
.wn-frame-has-toggle .wn-frame-gif { display: none; }
.wn-gif-toggle { position: absolute; right: .75rem; bottom: .75rem; display: inline-flex; align-items: center; gap: .5rem;
  min-height: 2.75rem; padding: 0 1rem; border: 1px solid transparent; border-radius: 9999px; background: rgb(15 23 42 / .78); color: #fff;
  font: 800 .8125rem/1 var(--wn-sans); letter-spacing: .02em; white-space: nowrap; cursor: pointer;
  box-shadow: 0 4px 12px -4px rgb(0 0 0 / .35); }
.wn-gif-toggle:hover { background: rgb(15 23 42 / .92); }
.wn-gif-toggle::before { content: ""; flex: none; width: 0; height: 0; border-style: solid; border-width: .3125rem 0 .3125rem .5rem;
  border-color: transparent transparent transparent currentColor; }
.wn-frame-playing .wn-gif-toggle::before { width: .5rem; height: .625rem; border-width: 0 .1875rem; border-color: currentColor;
  box-sizing: border-box; }
/* Forced colors repaint every border, transparent sides included, which would fill the Play triangle into a square
   (a Stop glyph). The glyph opts out, so its transparent sides stay transparent and its one drawn side keeps the
   button's forced text color (inherited). The button itself stays forced, so its edge still shows. */
@media (forced-colors: active) { .wn-gif-toggle::before { forced-color-adjust: none; } }

/* ---------------------------------------------------------------- stories */
.wn-stories { margin-bottom: 3.5rem; }
.wn-feature { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1.25rem 2rem; align-items: start;
  padding: 2rem 0; border-bottom: 1px solid var(--wn-line); }
.wn-feature:first-of-type { padding-top: .5rem; }
.wn-feature-num { font: 800 clamp(3.5rem, 8vw, 6rem)/.85 var(--wn-display); letter-spacing: -.04em; color: transparent;
  -webkit-text-stroke: 2px var(--wn-cobalt); min-width: 2.2ch; }
.wn-row-top { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem .875rem; margin-bottom: .875rem; }
.wn-feature-title { margin: 0 0 .75rem; font: 800 clamp(1.625rem, 3.4vw, 2.375rem)/1.08 var(--wn-display); letter-spacing: -.025em;
  color: var(--wn-ink); text-wrap: balance; }
.wn-feature-dek { margin: 0 0 1rem; max-width: 44rem; font: 400 1.1875rem/1.6 var(--wn-serif); color: var(--wn-ink-2); }
.wn-feature-meta { margin: 0; }
.wn-feature-media { grid-column: 1 / -1; transform: rotate(-1deg); }
/* On phones the outlined number sits above the story, so the title and dek get the full width (beside a 3.5rem
   number they'd run about 3 words a line). */
@media (max-width: 479px) { .wn-feature { grid-template-columns: minmax(0, 1fr); row-gap: .75rem; } }
/* has-media (only when a frame renders): text left, frame right from 1024px; the frame stacks under the text below. */
@media (min-width: 1024px) {
  .wn-feature.has-media { grid-template-columns: auto minmax(0, 1fr) minmax(0, 1.15fr); align-items: center; }
  .wn-feature.has-media .wn-feature-media { grid-column: 3; grid-row: 1; }
}

.wn-grid { display: grid; gap: 1.25rem; margin-top: 2rem; }
@media (min-width: 768px) { .wn-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; } }
@media (min-width: 1100px) { .wn-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.wn-card { display: flex; flex-direction: column; min-width: 0; padding: 1.5rem 1.5rem 1.25rem; border-radius: 1.5rem; background: var(--wn-paper);
  box-shadow: 0 4px 6px -1px rgb(0 0 0 / .05), 0 0 0 1px var(--wn-line-2); }
/* A card with media: the frame is its first child, full width, 1rem above the number row, never tilted. */
.wn-card .wn-frame { margin-bottom: 1rem; }
.wn-card-top { display: flex; justify-content: space-between; align-items: center; gap: .75rem; margin-bottom: 1rem; }
.wn-card-num { font: 800 1.75rem/1 var(--wn-display); color: transparent; -webkit-text-stroke: 1.5px #4d8bff; letter-spacing: -.03em; }
.wn-card-title { margin: 0 0 .625rem; font: 800 1.3125rem/1.18 var(--wn-display); letter-spacing: -.015em; color: var(--wn-ink); text-wrap: balance; }
.wn-card-dek { margin: 0 0 1.25rem; font: 400 1rem/1.58 var(--wn-serif); color: var(--wn-ink-2); }
.wn-card-meta { margin: auto 0 0; }

/* Titles wrap anywhere with hyphens, so a 120-character title or a 15-letter word never overflows at 320px.
   hyphenate-limit-chars keeps hyphenation to words of 10+ letters (4 each side), so a short word in a display title
   ("arti-cle" at 375px) never splits; a browser without it just hyphenates as hyphens: auto does. */
.wn-cover .ed-cover-title, .wn-feature-title, .wn-card-title, .wn-past-title, .wn-check-text { overflow-wrap: anywhere; hyphens: auto;
  hyphenate-limit-chars: 10 4 4; }

/* The dek wrappers are divs around renderMarkdownSegment's own <p>s and lists. */
.wn-cover .ed-cover-dek > p, .wn-feature-dek > p, .wn-card-dek > p { margin: 0; }
.wn-cover .ed-cover-dek > * + *, .wn-feature-dek > * + *, .wn-card-dek > * + * { margin-top: .75em; }

/* --------------------------------------------------- also shipped (checklist) */
.wn-also { margin-bottom: 4rem; max-width: 60rem; }
.wn-checklist { list-style: none; margin: 0; padding: .5rem 1.25rem; border-radius: 1.5rem; background: var(--wn-sunken);
  box-shadow: 0 0 0 1px var(--wn-line-2); }
.wn-check { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: .875rem; align-items: start; padding: 1rem 0;
  border-bottom: 1px dashed var(--wn-line); }
.wn-check:last-child { border-bottom: 0; }
.wn-check-box { width: 1.375rem; height: 1.375rem; border-radius: .4rem; background: var(--wn-cobalt); display: grid; place-items: center; margin-top: .1rem; }
.wn-check-box svg { width: .9rem; height: .9rem; fill: none; stroke: #fff; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
/* The row's title only (> strong): a **bold** inside the markdown blurb keeps the blurb's own type. */
.wn-check-text > strong { font: 700 1rem/1.4 var(--wn-sans); color: var(--wn-ink); }
.wn-check-blurb { display: block; margin-top: .25rem; font: 400 .9375rem/1.5 var(--wn-serif); color: var(--wn-muted); }
.wn-check-meta { font: 600 .75rem/1.4 var(--wn-sans); letter-spacing: .06em; text-transform: uppercase; color: var(--wn-muted); white-space: nowrap; }
@media (max-width: 600px) { .wn-check { grid-template-columns: auto minmax(0, 1fr); } .wn-check-meta { grid-column: 2; } }

/* ------------------------------------------------------------ more issues */
.wn-pastwrap { margin-top: 1rem; }
/* Scrolls sideways inside itself (scroll-snap); from 1100px 3.5 cards show, so the row visibly continues. */
.wn-past-row { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(15rem, 1fr); gap: 1.25rem; overflow-x: auto;
  padding: .5rem .25rem 1.25rem; scroll-snap-type: x mandatory; scrollbar-width: thin; }
@media (min-width: 1100px) { .wn-past-row { grid-auto-columns: calc((100% - 3 * 1.25rem) / 3.5); } }
/* Each card carries its OWN issue's ed-tint-*, which its art reads (--wash, --wash-2, --deep). */
.wn-past { scroll-snap-align: start; display: flex; flex-direction: column; border-radius: 1.5rem; overflow: hidden; text-decoration: none; color: inherit;
  background: var(--wn-paper); box-shadow: 0 4px 6px -1px rgb(0 0 0 / .05), 0 0 0 1px var(--wn-line-2);
  transition: transform .35s var(--wn-ease), box-shadow .35s var(--wn-ease); }
/* The page's only hover lift: More issues cards are the only links among the stories (D16). */
.wn-past:hover { transform: translateY(-4px) rotate(-.6deg); box-shadow: 0 20px 34px -18px rgb(1 61 181 / .3), 0 0 0 1px var(--wn-line); }
.wn-past-art { position: relative; height: 8.5rem; padding: 1.125rem; display: flex; flex-direction: column; justify-content: space-between;
  background: radial-gradient(120% 120% at 100% 0%, var(--wash-2) 0%, var(--wash) 60%); overflow: hidden; }
.wn-past-art .ed-sparkle { position: absolute; right: -.75rem; bottom: -1rem; width: 6rem; height: 6rem; fill: var(--deep); opacity: .12;
  transition: transform .5s var(--wn-ease); }
.wn-past:hover .wn-past-art .ed-sparkle { transform: rotate(25deg) scale(1.1); }
.wn-past-month { font: 800 .75rem/1 var(--wn-sans); letter-spacing: .14em; text-transform: uppercase; color: var(--deep); }
.wn-past-body { padding: 1rem 1.125rem 1.25rem; display: flex; flex-direction: column; gap: .75rem; flex: 1; }
.wn-past-title { font: 800 1.0625rem/1.25 var(--wn-display); letter-spacing: -.01em; color: var(--wn-ink);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.wn-past-count { margin-top: auto; font: 600 .8125rem/1 var(--wn-sans); color: var(--wn-muted); }

/* ------------------------------------------------------------ empty states */
/* The empty corpus's line sits in the masthead under the tagline; an audience-empty view's line and its "See
   everything in this issue" pill (a standalone kit pill) sit under the masthead. */
.wn-empty-line { margin: 0; text-align: center; font: 400 clamp(1.0625rem, 2.2vw, 1.3125rem)/1.6 var(--wn-serif); color: var(--wn-ink-2);
  text-wrap: balance; overflow-wrap: anywhere; }
.wn-masthead .wn-empty-line { margin-top: 1.75rem; }
.wn-empty { display: flex; flex-direction: column; align-items: center; gap: 1rem; max-width: 40rem; margin: .5rem auto 4rem; }
.wn-empty .ed-pill { background: #fff; color: var(--wn-cobalt-700); box-shadow: 0 1px 2px rgb(0 0 0 / .05), 0 0 0 1px var(--wn-line-2); }
.wn-empty .ed-pill:hover { background: var(--wn-cobalt-50); }

/* ------------------------------------------------------------------ motion */
/* D17: progressive enhancement. whats-new.js marks every .wn-reveal already on screen .is-in.wn-initial and only then
   adds html.wn-motion, so nothing on screen at load flashes hidden or re-animates; a story or checklist row below the
   fold fades and rises in (--d staggers the cards) once any of it scrolls into view, and its stamp lands once. Every
   rule that can HIDE content sits under screen + no-preference, so reduced motion, print, and a page without the
   script (no wn-motion) never hide a story or a stamp. The cover's underline is the kit's one CSS draw on load, never
   restarted here.
   Deliberate divergence from the articles library, flagged for Albert on the final PR: the library renders still
   (article.css `.article-library`, Albert 2026-09-23, because clicking a pill replayed its masthead's drift, draw and
   twinkles), while these pages keep the kit's load-time motion and add the title's twinkle, as the approved D1, D17 and
   phase-2 task call for. So every issue link, each audience pill included, is a full page load that replays the drift,
   the underline draw and the twinkles once, each done within 5s, and none under reduced motion. Matching the library
   is four page-local rules: `.wn-issue .ed-blob-a { animation: none; transform: translate3d(6%, 8%, 0) }`,
   `.wn-issue .ed-blob-b { animation: none; transform: translate3d(-4%, 0, 0) }`, and `animation: none` on
   `.wn-issue .ed-underline path` and `.wn-issue .ed-sparkle`. */
@media screen and (prefers-reduced-motion: no-preference) {
  .wn-motion .wn-reveal { opacity: 0; transform: translateY(18px);
    transition: opacity .7s var(--wn-ease) var(--d, 0ms), transform .7s var(--wn-ease) var(--d, 0ms); }
  .wn-motion .wn-reveal.is-in { opacity: 1; transform: none; }
  .wn-motion .wn-reveal:not(.is-in) .wn-stamp { opacity: 0; transform: scale(1.6) rotate(-14deg); }
  .wn-motion .wn-reveal.is-in:not(.wn-initial) .wn-stamp { animation: wn-stamp .45s cubic-bezier(.3, 1.5, .5, 1) calc(var(--d, 0ms) + .25s) both; }
  .wn-motion .wn-reveal.is-in:not(.wn-initial) .wn-stamp-lg { animation-name: wn-stamp-lg; }
}
/* Each lands on its stamp's resting tilt (-4deg, -8deg for the cover's large stamp). */
@keyframes wn-stamp { 0% { opacity: 0; transform: scale(1.6) rotate(-14deg) } 70% { opacity: 1; transform: scale(.94) rotate(-2deg) } 100% { opacity: 1; transform: rotate(-4deg) } }
@keyframes wn-stamp-lg { 0% { opacity: 0; transform: scale(1.6) rotate(-18deg) } 70% { opacity: 1; transform: scale(.94) rotate(-6deg) } 100% { opacity: 1; transform: rotate(-8deg) } }

/* Nothing moves on its own for more than 5s, delay included (WCAG 2.2.2), so no pause control is needed. The ambient
   budget, kit animations included: the blobs' drift 5s and .4s + 4.6s, the underline's draw .35s + 1.1s, the sticker's
   and the title's sparkle twice 1.6s (3.2s). A stamp lands in at most .25s + 90ms + .45s and a reveal takes at most
   90ms + .7s, each once, as its story scrolls in. The scroll-linked header (ed-header-solidify) has no duration: it
   follows the scroll. */

/* ONE block stops every ambient animation and transition on the page under reduced motion: the kit's, named here
   because this page composes them (the blobs, both sparkles, the underline path, the cover pieces, the pills), and this
   page's own. It leaves the kit's scroll-linked header alone (D23: it moves only as the reader scrolls). The reveal
   and stamp rules need nothing here, since they apply only with no motion preference. Hover transforms go to none only
   where the resting transform is none (the More issues cards and their art sparkle); the cover keeps its resting-value
   neutralization above. */
@media (prefers-reduced-motion: reduce) {
  .ed-blob-a, .ed-blob-b, .wn-title-new .ed-sparkle, .ed-sticker-star .ed-sparkle, .ed-underline path { animation: none; }
  .ed-underline path { stroke-dashoffset: 0; }
  .ed-cover::before, .ed-cover-card, .ed-cover-media, .ed-pill,
  .wn-past, .wn-past-art .ed-sparkle, .wn-compact-inner { transition: none; }
  .wn-past:hover, .wn-past:hover .wn-past-art .ed-sparkle { transform: none; }
}

/* ---------------------------------------------------------- focus + print */
/* This page's own links; the pills (switch, compact bar, "See everything") keep the kit's own focus ring. */
.wn-issue-nav > a:focus-visible, .wn-past:focus-visible { outline: 2px solid var(--wn-cobalt-700); outline-offset: 2px; }
/* The GIF button sits on a screenshot of any color, so its ring is two-tone (white inside, cobalt outside), and it
   stays inside the frame's overflow: hidden (a .75rem inset against a 4px ring). */
.wn-gif-toggle:focus-visible { outline: 2px solid var(--wn-cobalt-700); outline-offset: 2px; box-shadow: 0 0 0 2px #fff; }
/* Print: no compact bar, and no GIF button (it does nothing on paper); the still keeps its no-JS "GIF" pill instead. */
@media print {
  .wn-compact { display: none !important; }
  .wn-gif-toggle { display: none; }
  .wn-frame-has-toggle .wn-frame-gif { display: block; }
}
