/*
Theme Name: Newsdesign Blocks
Theme URI: https://tsnvwrld.com
Author: Newsdesign
Author URI: https://tsnvwrld.com
Description: A full block (Site Editor) editorial theme for music news — bold condensed headlines, monochrome palette with one red accent. Ships 44 custom blocks (Hero Story, Card Grid, News Listing, Events, Releases, Charts, Quiz, Poll, Remix, Liveblog, FAQ/How-To/Review Verdict with JSON-LD schema and more), an Artist taxonomy with hubs, a Google News sitemap, cookie consent and reader features. Built from the @newsdesign/ui design system.
Version: 1.1.0
Requires at least: 6.1
Tested up to: 7.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: newsdesign-blocks
Tags: news, magazine, blog, editorial, full-site-editing, block-patterns, custom-menu, featured-images
*/

/*
 * Block theme: the visual system lives in assets/newsdesign.css (the compiled
 * @newsdesign/ui bundle). theme.json wires the palette / fonts / layout into
 * the editor; this file only carries the required header plus a few glue rules.
 */

/* The whole site tree is tagged .nd-root (see functions.php body_class) so the
   design system styles apply. A few extras the block markup needs: */

/* Visually-hidden but screen-reader-readable. Used for the homepage's
   descriptive <h1> (the front page has no visible heading of its own). */
.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ----- Masthead search: match the design's compact pill + magnifier ------ */
.nd-root .nd-masthead__search.wp-block-search {
  margin: 0;
  flex: 0 1 210px;
  max-width: 210px;
  min-width: 0;
  /* Reset the form itself so only the inner pill shows (no outer box).
     border-radius MUST be zeroed too: the design system's .nd-masthead__search
     carries a 999px pill radius which, left on the form, rounds the corners
     off the mobile fullscreen overlay (content shows through the arcs). */
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
  box-shadow: none;
}
.nd-root .nd-masthead__search .wp-block-search__inside-wrapper {
  display: flex;
  align-items: center;
  gap: var(--nd-space-2);
  background: var(--nd-color-paper-2);
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-pill);
  padding: 6px var(--nd-space-3);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
/* the magnifying-glass icon (the core Search block has no icon of its own) */
.nd-root .nd-masthead__search .wp-block-search__inside-wrapper::before {
  content: "";
  flex: none;
  width: 18px;
  height: 18px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%238a8a8a' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='16.5' y1='16.5' x2='21' y2='21'/%3E%3C/svg%3E") center / contain no-repeat;
}
.nd-root .nd-masthead__search .wp-block-search__input {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  outline: none;
  padding: 0;
  margin: 0;
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  color: var(--nd-color-ink);
}
.nd-root .nd-masthead__search .wp-block-search__input::placeholder {
  color: var(--nd-color-subtle);
}
/* The bar has its own ✕ — hide the browser's built-in clear button. */
.nd-root .nd-masthead__search .wp-block-search__input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}
.nd-root .nd-masthead__search:focus-within .wp-block-search__inside-wrapper {
  background: var(--nd-color-paper);
  border-color: var(--nd-color-ink);
}
.nd-root .nd-masthead__search .wp-block-search__button {
  display: none;
}

/* Instant-search takeover panel: full masthead width under the open bar. */
.nd-root .nd-masthead__search { position: relative; }
.nd-instant {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--nd-color-paper);
  border: 1px solid var(--nd-color-rule-strong);
  border-top: 1px solid var(--nd-color-rule);
  border-radius: 0 0 var(--nd-radius-md) var(--nd-radius-md);
  box-shadow: var(--nd-shadow-md);
  padding: var(--nd-space-4) var(--nd-space-4) var(--nd-space-5);
  max-height: min(75vh, 640px);
  overflow-y: auto;
  z-index: 80;
}
.nd-instant[hidden] { display: none; }

/* Section header row: "TRENDING NEWS ............... SEE ALL" */
.nd-instant__bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--nd-space-3);
  margin: var(--nd-space-5) 0 var(--nd-space-3);
}
.nd-instant__bar:first-child { margin-top: 0; }
.nd-instant__h {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-lg);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--nd-color-ink);
}
.nd-instant__seeall {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--nd-color-ink);
  text-decoration: none;
}
.nd-instant__seeall:hover { text-decoration: underline; }

/* Story cards: image on top, kicker line, bold title. */
.nd-instant__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--nd-space-4);
}
.nd-instant__card {
  display: block;
  min-width: 0;
  color: var(--nd-color-ink);
  text-decoration: none;
}
.nd-instant__img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--nd-radius-sm);
  background: var(--nd-color-paper-3);
}
.nd-instant__cardmeta {
  display: block;
  margin-top: var(--nd-space-2);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--nd-color-subtle);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.nd-instant__cardmeta b { color: var(--nd-color-ink); font-weight: 700; }
.nd-instant__sep { margin: 0 6px; color: var(--nd-color-rule-strong); }
.nd-instant__cardtitle {
  display: block;
  margin-top: 4px;
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-base);
  font-weight: 700;
  line-height: 1.3;
}
.nd-instant__card:hover .nd-instant__cardtitle { text-decoration: underline; }

/* Artists: a scrollable row of round avatars. */
.nd-instant__artists {
  display: flex;
  gap: var(--nd-space-4);
  overflow-x: auto;
  padding-bottom: var(--nd-space-2);
}
.nd-instant__artist {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--nd-space-2);
  width: 92px;
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 600;
  text-align: center;
  color: var(--nd-color-ink);
  text-decoration: none;
}
.nd-instant__artist:hover span:last-child { text-decoration: underline; }
.nd-instant__avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--nd-color-paper-3);
}
.nd-instant__avatar--ph {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--nd-text-xl);
  font-weight: 700;
  color: var(--nd-color-subtle);
}

/* Swipe-progress indicator: only meaningful on the mobile rails. */
.nd-instant__scroll { display: none; }

.nd-instant__empty {
  padding: var(--nd-space-3) 0;
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  color: var(--nd-color-muted);
}
.nd-instant__all {
  display: block;
  margin-top: var(--nd-space-4);
  padding: var(--nd-space-2) var(--nd-space-3);
  background: var(--nd-color-paper-2);
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-sm);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  font-weight: 600;
  color: var(--nd-color-accent);
  text-decoration: none;
  text-align: center;
}
.nd-instant__all:hover { background: var(--nd-color-paper-3); }

/* Close ✕ in the expanded bar (JS injects it; hidden while collapsed). */
.nd-instant__close {
  display: none;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--nd-color-ink);
  cursor: pointer;
}
.nd-root .nd-masthead__search.is-open .nd-instant__close { display: inline-flex; }

/* Icon-only collapsible search (JS adds .nd-search-collapsible; without JS the
   full field shows as a graceful fallback). Click the magnifier to expand. */
.nd-root .nd-masthead__search.nd-search-collapsible {
  flex: 0 0 auto;
  max-width: none;
}
/* Collapsed: just the magnifier — transparent, no pill. */
.nd-root .nd-masthead__search.nd-search-collapsible .wp-block-search__inside-wrapper {
  width: 36px;
  height: 36px;
  padding: 0;
  justify-content: center;
  background: transparent;
  border-color: transparent;
  cursor: pointer;
  transition: width 0.25s ease, padding 0.25s ease, background-color 0.2s ease, border-color 0.2s ease;
}
.nd-root .nd-masthead__search.nd-search-collapsible .wp-block-search__inside-wrapper::before {
  margin: 0;
}
.nd-root .nd-masthead__search.nd-search-collapsible .wp-block-search__input {
  width: 0;
  min-width: 0;
  padding: 0;
  opacity: 0;
  transition: width 0.25s ease, opacity 0.2s ease;
}
/* Open (JS adds .is-open when you click the magnifier / focus the field):
   the search takes over the whole masthead row — full-width bar with the
   magnifier, the hint and a close ✕ — and the .nd-instant panel drops in
   flush below it. Class-driven, not :focus-within, so the panel stays up
   while the pointer wanders through it. */
.nd-root .nd-masthead__search.nd-search-collapsible.is-open {
  position: absolute;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  /* Matches .nd-container's gutter so the bar lines up with page content. */
  padding-inline: var(--nd-space-4);
  background: var(--nd-color-paper);
}
.nd-root .nd-masthead__search.nd-search-collapsible.is-open .wp-block-search__inside-wrapper {
  width: 100%;
  height: 40px;
  padding: 6px var(--nd-space-3);
  justify-content: flex-start;
  background: var(--nd-color-paper-2);
  border-color: var(--nd-color-rule);
  cursor: text;
}
.nd-root .nd-masthead__search.nd-search-collapsible.is-open .wp-block-search__input {
  width: auto;
  flex: 1;
  opacity: 1;
}

/* ---- Mobile search: full-width bar + 16px font (kills iOS zoom-on-focus) -- */
/* Keep the wordmark truly centered. The Site-Editor copy of the header turns
   the inner group into a flex row (is-layout-flex + space-between via a
   wp-container-* class that core prints AFTER theme styles), which silently
   overrides the design's grid — and with unequal sides the title drifts.
   Two classes out-rank core's single wp-container class, so this re-asserts
   the 3-column grid: equal 1fr sides, title mathematically centered. Works
   with or without the .nd-masthead__center wrapper. */
.nd-root .nd-masthead__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  /* Anchor for the open search bar + its full-width panel. */
  position: relative;
}

@media (max-width: 860px) {
  /* Tighter gutter so both icon pairs fit on narrow phones. */
  .nd-root .nd-masthead__inner {
    gap: var(--nd-space-3);
  }

  /* iOS Safari zooms into any input under 16px when focused — bump the size so
     tapping the search never zooms the page. */
  .nd-root .nd-masthead__search .wp-block-search__input { font-size: 16px; }

  /* Open search takes the WHOLE screen: the bar pinned to the top, the
     panel filling the rest with its own scroll. Behind it the page is
     covered and its scroll locked (html.nd-search-open, set by JS). */
  .nd-root .nd-masthead__search.nd-search-collapsible.is-open {
    position: fixed;
    inset: 0;
    z-index: 95; /* above share/drawers (70-90), below the cookie banner (100) */
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: calc(var(--nd-space-3) + env(safe-area-inset-top, 0px)) var(--nd-space-4) 0;
    background: var(--nd-color-paper);
    /* Panning only inside the panel — the chrome (bar) drags nothing. */
    touch-action: none;
  }
  .nd-root .nd-masthead__search.nd-search-collapsible.is-open .wp-block-search__inside-wrapper {
    flex: none;
    width: 100%;
    height: 44px;
  }
  .nd-root .nd-masthead__search.is-open .nd-instant {
    position: static;
    flex: 1;
    min-height: 0;
    max-height: none;
    margin-top: var(--nd-space-3);
    padding: 0 0 calc(var(--nd-space-5) + env(safe-area-inset-bottom, 0px));
    border: 0;
    border-radius: 0;
    box-shadow: none;
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-y;
  }
  /* Hard scroll lock behind the overlay — html AND body, both axes, so the
     page can't wiggle sideways under the fullscreen search. */
  html.nd-search-open,
  html.nd-search-open body {
    overflow: hidden;
    overscroll-behavior: none;
  }

  /* Complex-style fullscreen chrome: the bar is bare (big magnifier + text +
     ✕, no pill), each section starts with a full-bleed hairline. */
  .nd-root .nd-masthead__search.nd-search-collapsible.is-open .wp-block-search__inside-wrapper {
    height: 48px;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
  }
  .nd-root .nd-masthead__search.nd-search-collapsible.is-open .wp-block-search__inside-wrapper::before {
    width: 22px;
    height: 22px;
  }
  .nd-root .nd-masthead__search.nd-search-collapsible.is-open .wp-block-search__input {
    font-size: 17px;
  }

  .nd-instant__bar {
    margin: var(--nd-space-5) calc(-1 * var(--nd-space-4)) var(--nd-space-3);
    padding: var(--nd-space-4) var(--nd-space-4) 0;
    border-top: 1px solid var(--nd-color-rule);
  }
  /* The first section's rule doubles as the divider under the search bar. */
  .nd-instant__bar:first-child { margin-top: 0; }
  .nd-instant__h { font-size: var(--nd-text-md); }
  .nd-instant__seeall { text-decoration: underline; }

  /* Bigger cards: one nearly-full-width card + a slim peek of the next. */
  .nd-instant__cardtitle { font-size: var(--nd-text-md); }

  /* Story cards become one swipeable row (same idiom as the News Slider):
     full-bleed to the screen edge, one card + a peek of the next, snap per
     card, no scrollbar. No touch-action lock — vertical swipes must still
     scroll the panel. */
  .nd-instant__grid {
    display: flex;
    gap: var(--nd-space-3);
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    margin-inline: calc(-1 * var(--nd-space-4));
    padding-inline: var(--nd-space-4);
    scroll-padding-inline: var(--nd-space-4);
  }
  .nd-instant__grid::-webkit-scrollbar { display: none; }
  /* Any card type — the panel's own and the nd-card used on the search
     results page share this rail. */
  .nd-instant__grid > * {
    flex: 0 0 88%;
    max-width: 360px;
    scroll-snap-align: start;
  }

  /* Swipe-progress indicator under a rail (injected by theme.js): a short
     left-aligned track whose thumb mirrors the scroll position. */
  .nd-instant__scroll {
    display: block;
    position: relative;
    width: 96px;
    height: 3px;
    margin-top: var(--nd-space-3);
    border-radius: 2px;
    background: var(--nd-color-paper-3);
    overflow: hidden;
  }
  .nd-instant__scroll i {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    border-radius: 2px;
    background: var(--nd-color-subtle);
  }

  /* The artists row swipes the same way. */
  .nd-instant__artists {
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    margin-inline: calc(-1 * var(--nd-space-4));
    padding-inline: var(--nd-space-4);
    scroll-padding-inline: var(--nd-space-4);
  }
  .nd-instant__artists::-webkit-scrollbar { display: none; }
  .nd-instant__artist { scroll-snap-align: start; }
}

/* ----- Search results page: type tabs, artists strip, no-results ---------- */
.nd-root .nd-searchhead { margin-top: var(--nd-space-4); }
.nd-searchtabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nd-space-2);
}
.nd-searchtabs__tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-pill);
  background: var(--nd-color-paper);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 600;
  color: var(--nd-color-ink);
  text-decoration: none;
}
.nd-searchtabs__tab:hover { background: var(--nd-color-paper-2); }
.nd-searchtabs__tab.is-active {
  background: var(--nd-color-ink);
  border-color: var(--nd-color-ink);
  color: var(--nd-color-paper);
}
.nd-searchtabs__count {
  font-weight: 400;
  font-size: var(--nd-text-xs);
  color: var(--nd-color-subtle);
}
.nd-searchtabs__tab.is-active .nd-searchtabs__count {
  color: inherit;
  opacity: 0.75;
}
.nd-searchhead__artists { margin-top: var(--nd-space-4); }
.nd-search-empty { margin-top: var(--nd-space-5); }

/* A byline that starts with the meta (event cards: date · city, no author)
   must not show the "·" separator the sm byline prefixes meta with. */
.nd-root .nd-byline--sm .nd-byline__meta:first-child::before { content: none; }

/* ----- Pagination: numbered pills, current page in solid ink -------------
   Styles the core query-pagination markup (.nd-pagination in the archive /
   index / artist / search templates). Two-class selectors on purpose — core
   prints its layout CSS after ours (see the wp-container gotcha). */
.nd-root .nd-pagination {
  margin-top: var(--nd-space-6, 40px);
  align-items: center;
  gap: var(--nd-space-4);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 600;
}
.nd-root .nd-pagination .wp-block-query-pagination-numbers {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
}
.nd-root .nd-pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: 36px;
  padding: 0 8px;
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-pill);
  background: var(--nd-color-paper);
  color: var(--nd-color-ink);
  text-decoration: none;
}
.nd-root .nd-pagination a.page-numbers:hover {
  background: var(--nd-color-paper-2);
  border-color: var(--nd-color-rule-strong);
}
.nd-root .nd-pagination .page-numbers.current {
  background: var(--nd-color-ink);
  border-color: var(--nd-color-ink);
  color: var(--nd-color-paper);
}
.nd-root .nd-pagination .page-numbers.dots {
  min-width: auto;
  padding: 0 2px;
  border: 0;
  background: transparent;
  color: var(--nd-color-subtle);
}
.nd-root .nd-pagination .wp-block-query-pagination-previous,
.nd-root .nd-pagination .wp-block-query-pagination-next {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 14px;
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-pill);
  background: var(--nd-color-paper);
  color: var(--nd-color-ink);
  text-decoration: none;
  margin: 0;
}
.nd-root .nd-pagination .wp-block-query-pagination-previous:hover,
.nd-root .nd-pagination .wp-block-query-pagination-next:hover {
  background: var(--nd-color-paper-2);
  border-color: var(--nd-color-rule-strong);
}

@media (max-width: 560px) {
  /* Narrow screens: Previous/Next collapse to round arrow-only buttons (the
     words stay in the DOM for screen readers; only their font-size is 0). */
  .nd-root .nd-pagination { gap: var(--nd-space-3); }
  .nd-root .nd-pagination .wp-block-query-pagination-previous,
  .nd-root .nd-pagination .wp-block-query-pagination-next {
    width: 36px;
    padding: 0;
    justify-content: center;
    font-size: 0;
    gap: 0;
  }
  .nd-root .nd-pagination .wp-block-query-pagination-previous-arrow,
  .nd-root .nd-pagination .wp-block-query-pagination-next-arrow {
    font-size: var(--nd-text-sm);
  }
  .nd-root .nd-pagination .page-numbers {
    min-width: 32px;
    height: 32px;
  }
}

/* ----- Standalone search form (404, search results) ---------------------- */
.nd-root .nd-search-form .wp-block-search__inside-wrapper {
  gap: var(--nd-space-2);
}
.nd-root .nd-search-form .wp-block-search__input {
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-sm);
  padding: var(--nd-space-3);
  font: inherit;
}
.nd-root .nd-search-form .wp-block-search__button {
  background: var(--nd-color-accent);
  color: var(--nd-color-accent-ink);
  border: none;
  border-radius: var(--nd-radius-sm);
  font-weight: var(--nd-weight-bold);
  padding-inline: var(--nd-space-4);
}

/* Section heading helper (a styled core Heading via className). */
.nd-root .nd-section__head {
  font-family: var(--nd-font-display);
  font-weight: var(--nd-weight-regular);
  text-transform: uppercase;
  border-bottom: 2px solid var(--nd-color-ink);
  padding-bottom: var(--nd-space-2);
}

/* Card / story-list grids emitted by the custom blocks */
.nd-grid {
  display: grid;
  gap: var(--nd-space-6);
}
.nd-grid--1 { grid-template-columns: 1fr; }
.nd-grid--2 { grid-template-columns: repeat(2, 1fr); }
.nd-grid--3 { grid-template-columns: repeat(3, 1fr); }
.nd-grid--4 { grid-template-columns: repeat(4, 1fr); }
.nd-stack { display: flex; flex-direction: column; gap: var(--nd-space-5); }

@media (max-width: 900px) {
  .nd-grid--3, .nd-grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .nd-grid--2, .nd-grid--3, .nd-grid--4 { grid-template-columns: 1fr; }
}

.nd-masthead__menu-toggle { display: none; }

/* ----- Responsive utility classes (add to a block's "Additional CSS class")
   nd-hide-mobile   → hidden on phones (≤781px)
   nd-hide-desktop  → hidden on desktop (≥782px), i.e. mobile-only
   nd-only-mobile   → alias of nd-hide-desktop                              ---- */
@media (max-width: 781px) {
  .nd-hide-mobile,
  .is-style-nd-desktop-only { display: none !important; }
}
@media (min-width: 782px) {
  .nd-hide-desktop,
  .nd-only-mobile,
  .is-style-nd-mobile-only { display: none !important; }
}
/* In the editor, keep both visible but flag which device they target. */
.editor-styles-wrapper .is-style-nd-desktop-only,
.editor-styles-wrapper .is-style-nd-mobile-only {
  position: relative;
  outline: 1px dashed var(--nd-color-rule-strong);
  outline-offset: 2px;
}
.editor-styles-wrapper .is-style-nd-desktop-only::before {
  content: "Desktop only";
}
.editor-styles-wrapper .is-style-nd-mobile-only::before {
  content: "Mobile only";
}
.editor-styles-wrapper .is-style-nd-desktop-only::before,
.editor-styles-wrapper .is-style-nd-mobile-only::before {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 5;
  font: 700 10px/1 var(--nd-font-sans);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--nd-color-paper);
  background: var(--nd-color-accent);
  padding: 3px 6px;
  border-radius: 0 0 0 var(--nd-radius-sm);
}

/* ----- Section nav built from the core Navigation block ------------------ */
.nd-root .nd-sectionnav {
  border-bottom: 1px solid var(--nd-color-rule);
  padding-block: 0;
}
.nd-root .nd-sectionnav .wp-block-navigation {
  justify-content: center;
}
/* Keep the sections on ONE line. When they all fit they stay centered; when
   there are too many, the row scrolls horizontally instead of wrapping. */
.nd-root .nd-sectionnav .wp-block-navigation__container {
  gap: 0 var(--nd-space-3);
  flex-wrap: nowrap;
  justify-content: safe center;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.nd-root .nd-sectionnav .wp-block-navigation__container::-webkit-scrollbar {
  display: none;
}
.nd-root .nd-sectionnav .wp-block-navigation-item {
  flex: 0 0 auto;
}

/* ----- Classic Menu block: dropdown submenus ----------------------------- */
.nd-root .nd-sectionnav__item { position: relative; }
.nd-root .nd-sectionnav__item.menu-item-has-children > .nd-sectionnav__link::after {
  content: "";
  display: inline-block;
  width: 0.4em;
  height: 0.4em;
  margin-left: 0.4em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}
.nd-root .nd-sectionnav .sub-menu {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 210px;
  margin: 0;
  padding: var(--nd-space-2) 0;
  list-style: none;
  background: var(--nd-color-paper);
  border: 1px solid var(--nd-color-rule);
  box-shadow: var(--nd-shadow-md);
  z-index: 60;
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
}
.nd-root .nd-sectionnav__item:hover > .sub-menu,
.nd-root .nd-sectionnav__item:focus-within > .sub-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
}
.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__item { display: block; }
.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__link {
  display: block;
  height: auto;
  padding: var(--nd-space-2) var(--nd-space-4);
  border-bottom: none;
  white-space: nowrap;
}
.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__link:hover {
  background: var(--nd-color-paper-2);
}

/* Nested (3rd-level) submenu: fly out to the right of its parent, not below. */
.nd-root .nd-sectionnav .sub-menu .sub-menu {
  top: 0;
  left: 100%;
  transform: translateX(4px);
}
/* A submenu item that itself has children: caret points right, pushed to edge. */
.nd-root .nd-sectionnav .sub-menu .menu-item-has-children > .nd-sectionnav__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--nd-space-3);
}
.nd-root .nd-sectionnav .sub-menu .menu-item-has-children > .nd-sectionnav__link::after {
  margin-left: 0;
  transform: rotate(-45deg);
}

.nd-root .nd-sectionnav .wp-block-navigation-item__content {
  font-size: var(--nd-text-xs);
  font-weight: var(--nd-weight-bold);
  letter-spacing: var(--nd-tracking-wide);
  text-transform: uppercase;
  color: var(--nd-color-ink);
  padding: var(--nd-space-3) var(--nd-space-3);
  border-bottom: 2px solid transparent;
}
.nd-root .nd-sectionnav .wp-block-navigation-item__content:hover {
  color: var(--nd-color-accent);
}
.nd-root .nd-sectionnav .current-menu-item > .wp-block-navigation-item__content {
  border-bottom-color: var(--nd-color-accent);
}

/* ----- Footer columns from Navigation blocks ----------------------------- */
.nd-root .nd-footer .wp-block-navigation .wp-block-navigation__container {
  flex-direction: column;
  gap: var(--nd-space-2);
}
.nd-root .nd-footer .wp-block-navigation-item__content {
  color: rgba(255, 255, 255, 0.7);
  font-size: var(--nd-text-sm);
}
.nd-root .nd-footer .wp-block-navigation-item__content:hover {
  color: #fff;
}
/* A footer is a plain link list — never collapse it into a burger overlay,
   even if a Navigation block is set to "overlay on mobile". */
.nd-root .nd-footer .wp-block-navigation__responsive-container-open,
.nd-root .nd-footer .wp-block-navigation__responsive-container-close {
  display: none !important;
}
.nd-root .nd-footer .wp-block-navigation__responsive-container {
  display: block !important;
  position: static !important;
  width: auto !important;
  height: auto !important;
  background: transparent !important;
  visibility: visible !important;
  opacity: 1 !important;
  z-index: auto !important;
}
.nd-root .nd-footer .wp-block-navigation__responsive-container .wp-block-navigation__container {
  display: flex;
  flex-direction: column;
}

/* ----- Layout glue for Query Loop columns & block-based byline ----------- */
.nd-front-cols {
  align-items: flex-start;
  gap: var(--nd-space-7);
}
.nd-front-cols > .wp-block-column:last-child {
  flex-grow: 0;
}
/* The Query Loop's own grid already lays cards out; keep the inner gap tidy. */
.nd-root .wp-block-post-template.nd-grid {
  gap: var(--nd-space-6);
}
.nd-root .wp-block-post-template {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* post-author rendered as the byline */
.nd-root .nd-byline .wp-block-post-author {
  display: flex;
  align-items: center;
  gap: var(--nd-space-3);
}
.nd-root .nd-byline .wp-block-post-author__avatar img {
  border-radius: var(--nd-radius-pill);
}
/* Text-only byline: "By NAME" on one line, matching the card bylines. */
.nd-root .nd-byline .wp-block-post-author__content {
  display: flex;
  align-items: baseline;
  gap: var(--nd-space-1);
}
.nd-root .nd-byline .wp-block-post-author__byline {
  margin: 0;
  font-size: var(--nd-text-sm);
  color: var(--nd-color-muted);
}
.nd-root .nd-byline .wp-block-post-author__name {
  margin: 0;
  font-size: var(--nd-text-sm);
  font-weight: var(--nd-weight-semibold);
  color: var(--nd-color-ink);
}
.nd-root .nd-byline .wp-block-post-date {
  color: var(--nd-color-subtle);
  font-size: var(--nd-text-sm);
}

/* post-terms used as a kicker: strip the inner link color so it reads as accent */
.nd-root .nd-kicker a {
  color: inherit;
}
.nd-root .nd-kicker a:hover {
  color: inherit;
  text-decoration: underline;
}

/* tags rendered from post-terms */
.nd-root .nd-tags a {
  color: inherit;
}

/* ----- Newsletter / promo well (used by patterns) ------------------------ */
.nd-root .nd-well {
  background: var(--nd-color-paper-2);
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-md);
  padding: var(--nd-space-5);
}
.nd-root .nd-well__title {
  font-family: var(--nd-font-display);
  font-weight: var(--nd-weight-regular);
  text-transform: uppercase;
  font-size: var(--nd-text-lg);
  line-height: 1.1;
  margin: var(--nd-space-2) 0 var(--nd-space-4);
}
.nd-root .nd-section__head {
  font-size: var(--nd-text-2xl);
  margin-bottom: var(--nd-space-5);
}

/* ======================================================================== *
 * Dark mode
 * Tokens flip when the OS prefers dark (unless the user forced light), or
 * when the toggle sets data-nd-theme="dark" explicitly.
 * ======================================================================== */
@media (prefers-color-scheme: dark) {
  :root:not([data-nd-theme="light"]) {
    --nd-color-ink: #f2f2f2;
    --nd-color-ink-soft: #e2e2e2;
    --nd-color-muted: #b3b3b3;
    /* #8a8a8a passes on paper (#121212) but lands at 4.4:1 on the raised
       surfaces (paper-3 #262626) — one step lighter clears AA everywhere. */
    --nd-color-subtle: #949494;
    --nd-color-paper: #121212;
    --nd-color-paper-2: #1c1c1c;
    --nd-color-paper-3: #262626;
    --nd-color-rule: #2c2c2c;
    --nd-color-rule-strong: #3a3a3a;
    --nd-color-link: #f2f2f2;
    --nd-color-accent-soft: #2a1417;
  }
}
:root[data-nd-theme="dark"] {
  --nd-color-ink: #f2f2f2;
  --nd-color-ink-soft: #e2e2e2;
  --nd-color-muted: #b3b3b3;
  --nd-color-subtle: #949494;
  --nd-color-paper: #121212;
  --nd-color-paper-2: #1c1c1c;
  --nd-color-paper-3: #262626;
  --nd-color-rule: #2c2c2c;
  --nd-color-rule-strong: #3a3a3a;
  --nd-color-link: #f2f2f2;
  --nd-color-accent-soft: #2a1417;
}
/* Footer is intentionally dark in both modes — pin it so the ink-token flip
   doesn't turn it light. */
:root[data-nd-theme="dark"] .nd-footer { background: #0a0a0a; }
@media (prefers-color-scheme: dark) {
  :root:not([data-nd-theme="light"]) .nd-footer { background: #0a0a0a; }
}

/* ======================================================================== *
 * Sticky masthead + theme toggle + back-to-top
 * ======================================================================== */
.nd-root .nd-masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--nd-color-paper);
}
.nd-theme-toggle { margin-left: var(--nd-space-1); }

.nd-backtotop {
  position: fixed;
  right: var(--nd-space-5);
  bottom: var(--nd-space-5);
  width: 44px;
  height: 44px;
  border: none;
  border-radius: var(--nd-radius-pill);
  background: var(--nd-color-ink);
  color: var(--nd-color-paper);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
  z-index: 60;
  box-shadow: var(--nd-shadow-md);
}
.nd-backtotop.is-visible { opacity: 1; visibility: visible; transform: none; }
.nd-backtotop:hover { background: var(--nd-color-accent); }

/* ======================================================================== *
 * Breaking-news ticker
 * ======================================================================== */
.nd-breaking {
  display: flex;
  align-items: stretch;
  background: var(--nd-color-accent);
  color: #fff;
  font-family: var(--nd-font-sans);
  overflow: hidden;
}
.nd-breaking__label {
  background: rgba(0, 0, 0, 0.18);
  font-weight: var(--nd-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  font-size: var(--nd-text-xs);
  display: flex;
  align-items: center;
  padding: var(--nd-space-2) var(--nd-space-4);
  white-space: nowrap;
  flex: none;
}
.nd-breaking__viewport { overflow: hidden; flex: 1; display: flex; align-items: center; }
.nd-breaking__track { display: inline-flex; white-space: nowrap; animation: nd-ticker 36s linear infinite; }
.nd-breaking__run { display: inline-flex; align-items: center; gap: var(--nd-space-3); padding-left: var(--nd-space-4); }
.nd-breaking:hover .nd-breaking__track { animation-play-state: paused; }
.nd-breaking__item { color: #fff; font-size: var(--nd-text-sm); font-weight: var(--nd-weight-semibold); }
.nd-breaking__item:hover { color: #fff; text-decoration: underline; }
.nd-breaking__sep { opacity: 0.55; }
@keyframes nd-ticker {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .nd-breaking__track { animation: none; }
  .nd-breaking__viewport { overflow-x: auto; }
}

/* ======================================================================== *
 * Author box (single post)
 * ======================================================================== */
.nd-authorbox {
  display: flex;
  gap: var(--nd-space-4);
  align-items: flex-start;
  margin-top: var(--nd-space-7);
  padding: var(--nd-space-5);
  background: var(--nd-color-paper-2);
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-md);
}
.nd-authorbox .wp-block-post-author { gap: var(--nd-space-4); align-items: flex-start; }
.nd-authorbox .wp-block-post-author__avatar img,
.nd-authorbox .avatar {
  width: 64px;
  height: 64px;
  border-radius: var(--nd-radius-pill);
}
.nd-authorbox .wp-block-post-author__name {
  font-family: var(--nd-font-display);
  text-transform: uppercase;
  font-size: var(--nd-text-lg);
  line-height: 1.1;
}
.nd-authorbox .wp-block-post-author__bio {
  font-size: var(--nd-text-sm);
  color: var(--nd-color-muted);
  margin-top: var(--nd-space-2);
}

/* ======================================================================== *
 * Key-facts box & FAQ (single post / SEO blocks)
 * ======================================================================== */
.nd-keyfacts {
  background: var(--nd-color-paper-2);
  border-left: 4px solid var(--nd-color-accent);
  border-radius: var(--nd-radius-md);
  padding: var(--nd-space-5);
  margin-block: var(--nd-space-5);
}
.nd-keyfacts__title {
  font-family: var(--nd-font-display);
  text-transform: uppercase;
  font-size: var(--nd-text-lg);
  line-height: 1.1;
  margin-bottom: var(--nd-space-3);
}
.nd-keyfacts ul { margin: 0; padding-left: 1.1rem; }
.nd-keyfacts li { margin-bottom: var(--nd-space-2); }

/* ======================================================================== *
 * Star rating
 * ======================================================================== */
.nd-rating { display: inline-flex; align-items: center; gap: 1px; font-size: 1.2rem; line-height: 1; }
.nd-rating__star { color: var(--nd-color-rule-strong); }
.nd-rating__star.is-full { color: var(--nd-color-accent); }
.nd-rating__star.is-half {
  background: linear-gradient(90deg, var(--nd-color-accent) 50%, var(--nd-color-rule-strong) 50%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.nd-rating__value {
  margin-left: var(--nd-space-2);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: var(--nd-weight-bold);
  color: var(--nd-color-muted);
}

/* ======================================================================== *
 * Read-also inline callout
 *
 * Four looks, chosen per instance in the editor. "rules" is the original and
 * still the default, so every callout already sitting in an article keeps the
 * exact look it had. Only "thumb" prints a picture.
 * ======================================================================== */
.nd-readalso { margin-block: var(--nd-space-5); }
.nd-readalso__label {
  font-family: var(--nd-font-sans);
  font-weight: var(--nd-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  font-size: var(--nd-text-xs);
  color: var(--nd-color-accent);
  flex: none;
}
.nd-readalso__cat { color: var(--nd-color-muted); }
.nd-readalso__cat::before {
  content: "\00b7";
  margin: 0 0.4em;
  color: var(--nd-color-subtle);
}
.nd-readalso__link { font-weight: var(--nd-weight-bold); font-size: var(--nd-text-md); }

/* ----- Rules: label and headline between two hairlines ------------------- */
.nd-readalso.nd-readalso--rules {
  display: flex;
  gap: var(--nd-space-3);
  align-items: baseline;
  border-top: 1px solid var(--nd-color-ink);
  border-bottom: 1px solid var(--nd-color-ink);
  padding: var(--nd-space-3) 0;
}

/* ----- Plain: one quiet line, no rules ----------------------------------- */
.nd-readalso.nd-readalso--plain {
  display: flex;
  gap: var(--nd-space-2);
  align-items: baseline;
  flex-wrap: wrap;
}
.nd-readalso--plain .nd-readalso__link { font-size: var(--nd-text-base); }
.nd-readalso__arrow { margin-left: 0.3em; }

/* ----- Shared by the two card-shaped looks ------------------------------- */
.nd-readalso--thumb .nd-readalso__inner,
.nd-readalso--panel .nd-readalso__inner {
  text-decoration: none;
  color: inherit;
}
.nd-readalso--thumb .nd-readalso__body,
.nd-readalso--panel .nd-readalso__body {
  display: flex;
  flex-direction: column;
  gap: var(--nd-space-2);
  min-width: 0;
}
.nd-readalso--thumb .nd-readalso__title,
.nd-readalso--panel .nd-readalso__title {
  font-family: var(--nd-font-display);
  font-weight: var(--nd-weight-regular);
  line-height: var(--nd-leading-snug);
  font-size: var(--nd-text-lg);
  color: var(--nd-color-ink);
  letter-spacing: 0.005em;
}
.nd-readalso--thumb .nd-readalso__dek,
.nd-readalso--panel .nd-readalso__dek {
  font-size: var(--nd-text-sm);
  line-height: var(--nd-leading-normal);
  color: var(--nd-color-muted);
}

/* ----- Picture + headline ------------------------------------------------ */
.nd-readalso--thumb .nd-readalso__inner {
  display: grid;
  grid-template-columns: 148px minmax(0, 1fr);
  gap: var(--nd-space-4);
  align-items: center;
  border-top: 1px solid var(--nd-color-ink);
  border-bottom: 1px solid var(--nd-color-ink);
  padding-block: var(--nd-space-3);
}
/* Picture on the right instead: swap the track widths and move the media
   after the text. Order (not direction) so the reading order stays intact. */
.nd-readalso--thumb.is-flipped .nd-readalso__inner { grid-template-columns: minmax(0, 1fr) 148px; }
.nd-readalso--thumb.is-flipped .nd-readalso__media { order: 2; }
/* Chosen "picture + headline" but the story has no featured image. */
.nd-readalso--thumb.is-nomedia .nd-readalso__inner { grid-template-columns: minmax(0, 1fr); }

.nd-readalso__media {
  display: block;
  overflow: hidden;
  border-radius: var(--nd-radius-md);
  background: var(--nd-color-paper-3);
}
.nd-readalso__img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  /* Honours the per-article focal point / zoom like every other thumbnail. */
  object-position: var(--nd-focal, 50% 50%);
  transform: scale(var(--nd-zoom, 1));
  transition: transform 0.35s ease;
}

/* ----- Panel: tinted, with an accent bar --------------------------------- */
.nd-readalso--panel .nd-readalso__inner {
  display: block;
  background: var(--nd-color-paper-2);
  border-left: 3px solid var(--nd-color-accent);
  border-radius: 0 var(--nd-radius-md) var(--nd-radius-md) 0;
  padding: var(--nd-space-4);
}

@media (hover: hover) {
  .nd-readalso__inner:hover .nd-readalso__title { color: var(--nd-color-accent); }
  .nd-readalso--thumb .nd-readalso__inner:hover .nd-readalso__img {
    transform: scale(calc(var(--nd-zoom, 1) * 1.03));
  }
}
@media (prefers-reduced-motion: reduce) {
  .nd-readalso__img { transition: none; }
  .nd-readalso--thumb .nd-readalso__inner:hover .nd-readalso__img { transform: scale(var(--nd-zoom, 1)); }
}

@media (max-width: 600px) {
  .nd-readalso--thumb .nd-readalso__inner {
    grid-template-columns: 104px minmax(0, 1fr);
    gap: var(--nd-space-3);
  }
  .nd-readalso--thumb.is-flipped .nd-readalso__inner { grid-template-columns: minmax(0, 1fr) 104px; }
  .nd-readalso--thumb .nd-readalso__title,
  .nd-readalso--panel .nd-readalso__title { font-size: var(--nd-text-md); }
}

/* ======================================================================== *
 * Review rating header (single-review)
 * ======================================================================== */
.nd-review-meta {
  display: flex;
  align-items: center;
  gap: var(--nd-space-4);
  margin: var(--nd-space-3) 0 var(--nd-space-5);
}

/* ======================================================================== *
 * WooCommerce — map primary actions to the brand accent
 * ======================================================================== */
.nd-root .woocommerce a.button,
.nd-root .woocommerce button.button.alt,
.nd-root .woocommerce #respond input#submit,
.nd-root .woocommerce .wc-block-components-button {
  background: var(--nd-color-accent);
  color: var(--nd-color-accent-ink);
  border-radius: var(--nd-radius-sm);
  font-weight: var(--nd-weight-bold);
}
.nd-root .woocommerce ul.products li.product .price { color: var(--nd-color-ink); font-weight: var(--nd-weight-bold); }
.nd-root .woocommerce span.onsale {
  background: var(--nd-color-accent);
  color: var(--nd-color-accent-ink);
  border-radius: var(--nd-radius-pill);
}
.nd-verdict__score .nd-rating { font-size: 1.4rem; }
.nd-verdict--editing .nd-verdict__hint,
.nd-albuminfo--editing .nd-albuminfo__hint {
  font: var(--nd-weight-bold) var(--nd-text-xs)/1 var(--nd-font-sans);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  color: var(--nd-color-accent);
  margin-bottom: var(--nd-space-3);
}

/* ======================================================================== *
 * Album / Track info card
 * ======================================================================== */
.nd-albuminfo {
  background: var(--nd-color-paper-2);
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-md);
  padding: var(--nd-space-5);
  margin-block: var(--nd-space-5);
}
.nd-albuminfo__cover { margin-bottom: var(--nd-space-4); }
.nd-albuminfo__cover img { width: 100%; max-width: 220px; border-radius: var(--nd-radius-sm); }
.nd-albuminfo__list { margin: 0; }
.nd-albuminfo__row {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: var(--nd-space-3);
  padding: var(--nd-space-2) 0;
  border-bottom: 1px solid var(--nd-color-rule);
  font-size: var(--nd-text-sm);
}
.nd-albuminfo__row:last-child { border-bottom: none; }
.nd-albuminfo__row dt {
  font-weight: var(--nd-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  font-size: var(--nd-text-xs);
  color: var(--nd-color-subtle);
}
.nd-albuminfo__row dd { margin: 0; color: var(--nd-color-ink); }

/* ======================================================================== *
 * Opinion label banner
 * ======================================================================== */
.nd-opinion {
  display: flex;
  align-items: center;
  gap: var(--nd-space-3);
  border-left: 4px solid var(--nd-color-accent);
  background: var(--nd-color-accent-soft);
  border-radius: 0;
  padding: var(--nd-space-3) var(--nd-space-4);
  margin-block: var(--nd-space-4);
  flex-wrap: wrap;
}
.nd-opinion__tag {
  font: var(--nd-weight-bold) var(--nd-text-xs)/1 var(--nd-font-sans);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  color: var(--nd-color-accent);
  background: var(--nd-color-paper);
  border: 1px solid var(--nd-color-accent);
  border-radius: var(--nd-radius-pill);
  padding: 4px 12px;
  flex: none;
}
.nd-opinion__note { font-size: var(--nd-text-sm); color: var(--nd-color-muted); }
.nd-howto--editing .nd-howto__edit-label,
.nd-faq--editing .nd-faq__edit-label {
  display: block;
  font: var(--nd-weight-bold) var(--nd-text-xs)/1 var(--nd-font-sans);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  color: var(--nd-color-subtle);
  margin-bottom: var(--nd-space-2);
}
/* A proper, visible multi-line description box in the editor. */
.nd-howto--editing .nd-howto__edit-text,
.nd-faq--editing .nd-faq__edit-a {
  min-height: 84px;
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-sm);
  padding: var(--nd-space-3);
  background: #fff;
  color: var(--nd-color-ink);
  font-size: var(--nd-text-base);
  line-height: 1.55;
}
.nd-howto--editing .nd-howto__edit-text:focus,
.nd-faq--editing .nd-faq__edit-a:focus {
  outline: none;
  border-color: var(--nd-color-ink);
}

/* ======================================================================== *
 * Listen (embedded player)
 * ======================================================================== */
.nd-listen {
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-md);
  background: var(--nd-color-paper);
  padding: var(--nd-space-3);
  margin-block: var(--nd-space-5);
}
.nd-listen__label {
  display: block;
  font: var(--nd-weight-bold) var(--nd-text-xs)/1 var(--nd-font-sans);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  color: var(--nd-color-accent);
  margin-bottom: var(--nd-space-3);
}
.nd-listen__frame { display: block; }
.nd-listen__yt { position: relative; aspect-ratio: 16 / 9; }
.nd-listen__yt iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: var(--nd-radius-sm);
}
.nd-listen__hint,
.nd-listen__fallback { font-size: var(--nd-text-sm); color: var(--nd-color-muted); }
.nd-listen__fallback { word-break: break-all; }

/* ======================================================================== *
 * Artist Hub header
 * ======================================================================== */
.nd-artist {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: var(--nd-space-6);
  align-items: center;
  max-width: var(--nd-container);
  margin-inline: auto;
  padding: var(--nd-space-6) var(--nd-space-4);
  border-bottom: 2px solid var(--nd-color-ink);
}
.nd-artist--no-image { grid-template-columns: 1fr; }
.nd-artist__media img {
  width: 200px;
  height: 200px;
  object-fit: cover;
  border-radius: var(--nd-radius-pill);
}
.nd-artist__name {
  font-family: var(--nd-font-display);
  font-weight: var(--nd-weight-regular);
  text-transform: uppercase;
  font-size: var(--nd-text-4xl);
  line-height: 1;
  margin: var(--nd-space-2) 0;
}
.nd-artist__bio { color: var(--nd-color-muted); max-width: 60ch; margin: 0 0 var(--nd-space-4); }
.nd-artist__socials { display: flex; gap: var(--nd-space-2); flex-wrap: wrap; }
.nd-artist__social {
  font: var(--nd-weight-bold) var(--nd-text-xs)/1 var(--nd-font-sans);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  color: var(--nd-color-ink);
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-pill);
  padding: 7px 14px;
}
.nd-artist__social:hover { background: var(--nd-color-ink); color: var(--nd-color-paper); text-decoration: none; }
@media (max-width: 700px) {
  .nd-artist { grid-template-columns: 1fr; text-align: center; }
  .nd-artist__media img { margin-inline: auto; width: 140px; height: 140px; }
  .nd-artist__socials { justify-content: center; }
  .nd-artist__name { font-size: var(--nd-text-3xl); }
}
.nd-authorhero__intro .nd-kicker { display: block; margin-bottom: var(--nd-space-1); }

/* ======================================================================== *
 * Listing-block layout controls (Card Grid / News Listing "Layout & style")
 * ======================================================================== */
/* Image ratio overrides (theme default is 3:2). */
.nd-root .nd-cards--r169 .nd-card__image { aspect-ratio: 16 / 9; height: auto; object-fit: cover; }
.nd-root .nd-cards--r43 .nd-card__image { aspect-ratio: 4 / 3; height: auto; object-fit: cover; }
.nd-root .nd-cards--r11 .nd-card__image { aspect-ratio: 1 / 1; height: auto; object-fit: cover; }
/* Gap between cards. */
.nd-root .nd-cards--tight .nd-grid,
.nd-root .nd-cards--tight .nd-stack { gap: var(--nd-space-4); }
.nd-root .nd-cards--loose .nd-grid,
.nd-root .nd-cards--loose .nd-stack { gap: var(--nd-space-7); }
/* Two columns on phones (default collapses to one). */
@media (max-width: 600px) {
  .nd-root .nd-cards--m2 .nd-grid { grid-template-columns: repeat(2, 1fr); gap: var(--nd-space-4); }
  .nd-root .nd-cards--m2 .nd-card__title { font-size: var(--nd-text-md); }
}
/* Card styles: ruled rows / boxed cards. */
.nd-root .nd-cards--ruled .nd-grid > .nd-card,
.nd-root .nd-cards--ruled .nd-stack > .nd-card {
  padding-bottom: var(--nd-space-5);
  border-bottom: 1px solid var(--nd-color-rule);
}
.nd-root .nd-cards--ruled .nd-grid > .nd-card:last-child,
.nd-root .nd-cards--ruled .nd-stack > .nd-card:last-child { border-bottom: 0; padding-bottom: 0; }
.nd-root .nd-cards--boxed .nd-card {
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-md);
  padding: var(--nd-space-4);
  background: var(--nd-color-paper);
}
/* Title clamp (Card display → "Max title lines"). */
.nd-card__title--clamp {
  display: -webkit-box;
  -webkit-line-clamp: var(--nd-title-lines, 3);
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Author-page story list: readable column, ruled rows like a story index. */
.nd-root .nd-authorlist { max-width: 860px; margin-inline: auto; }
.nd-authorlist .nd-newslist__grid { gap: var(--nd-space-5); }
.nd-authorlist .nd-newslist__grid > .nd-card {
  padding-bottom: var(--nd-space-5);
  border-bottom: 1px solid var(--nd-color-rule);
}
.nd-authorlist .nd-newslist__grid > .nd-card:last-child { border-bottom: 0; }

/* Infinite listings: the Show-more button is the scroll sentinel; keep the
   wrap's height stable so auto-loading doesn't make the page jump. */
.nd-newslist--infinite .nd-newslist__more-wrap { min-height: 48px; }
/* Once theme.js confirms auto-loading works it hides the fallback button —
   visibility (not display) so the sentinel keeps its geometry. */
.nd-newslist__more--auto { visibility: hidden; }

/* Author names link to the author page; keep byline styling, accent on hover. */
a.nd-byline__name { color: inherit; text-decoration: none; }
a.nd-byline__name:hover { color: var(--nd-color-accent); text-decoration: none; }
.nd-root .wp-block-post-author__name a { color: inherit; text-decoration: none; }
.nd-root .wp-block-post-author__name a:hover { color: var(--nd-color-accent); text-decoration: none; }

/* Hover = accent only. The bundle's blanket `.nd-root :where(a):hover` adds
   an underline; cards opt out themselves, these two don't — pin them here. */
.nd-root .nd-hero__title-link:hover { text-decoration: none; }
.nd-root .nd-masthead__wordmark a:hover { color: var(--nd-color-accent); text-decoration: none; }
.nd-prose .nd-release__listen { text-decoration: none; }
/* In post content, the generic .nd-prose a / .nd-prose h3 styles would recolour,
   underline and add big margins to these — pin them so the row stays compact. */
.nd-prose .nd-release__title a,
.nd-prose .nd-release__artist { text-decoration: none; }
.nd-prose .nd-release__title a { color: var(--nd-color-ink); }
.nd-prose .nd-release__title a:hover { color: var(--nd-color-accent); }
.nd-prose .nd-release__title {
  margin: 0 !important;
  font-family: var(--nd-font-display);
  font-size: var(--nd-text-lg);
  line-height: 1.1;
  letter-spacing: 0;
}
.nd-prose .nd-release__artist,
.nd-prose .nd-release__date { margin: 0 !important; }
.nd-prose .nd-release__item { margin: 0 !important; }

/* ======================================================================== *
 * Table of Contents
 * ======================================================================== */
.nd-toc {
  display: block;
  background: var(--nd-color-paper-2);
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-md);
  padding: var(--nd-space-4) var(--nd-space-5);
  margin-block: var(--nd-space-5);
}
.nd-toc[hidden] { display: none; }
.nd-toc__title {
  display: block;
  font: var(--nd-weight-bold) var(--nd-text-xs)/1 var(--nd-font-sans);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  color: var(--nd-color-subtle);
  margin-bottom: var(--nd-space-3);
}
.nd-toc__list { list-style: none; margin: 0; padding: 0; }
.nd-toc__item { margin-bottom: var(--nd-space-2); }
.nd-toc__item--h3 { padding-left: var(--nd-space-4); }
.nd-toc__item a { font-size: var(--nd-text-sm); font-weight: var(--nd-weight-semibold); color: var(--nd-color-ink); }
.nd-toc__item a:hover { color: var(--nd-color-accent); }
.nd-toc--editing .nd-listen__hint { display: block; margin-top: var(--nd-space-2); }

/* ======================================================================== *
 * Artist Card (in-article)
 * ======================================================================== */
.nd-artistcard {
  display: flex;
  gap: var(--nd-space-4);
  align-items: center;
  padding: var(--nd-space-4);
  background: var(--nd-color-paper-2);
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-md);
  margin-block: var(--nd-space-5);
}
.nd-artistcard__media { flex: none; }
.nd-artistcard__media img {
  width: 84px;
  height: 84px;
  object-fit: cover;
  border-radius: var(--nd-radius-pill);
}
.nd-artistcard__body { min-width: 0; }
.nd-artistcard__name {
  font-family: var(--nd-font-display);
  font-weight: var(--nd-weight-regular);
  text-transform: uppercase;
  font-size: var(--nd-text-xl);
  line-height: 1.05;
  margin: var(--nd-space-1) 0;
}
.nd-artistcard__name a { color: var(--nd-color-ink); }
.nd-artistcard__name a:hover { color: var(--nd-color-accent); }
.nd-artistcard__bio { font-size: var(--nd-text-sm); color: var(--nd-color-muted); margin: 0 0 var(--nd-space-2); }
.nd-artistcard__more {
  font: var(--nd-weight-bold) var(--nd-text-xs)/1 var(--nd-font-sans);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  color: var(--nd-color-accent);
}

/* ======================================================================== *
 * Breadcrumbs
 * ======================================================================== */
.nd-breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nd-space-2);
  font-size: var(--nd-text-xs);
  color: var(--nd-color-subtle);
  margin-bottom: var(--nd-space-4);
}
.nd-breadcrumbs__link {
  color: var(--nd-color-muted);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  font-weight: var(--nd-weight-semibold);
}
.nd-breadcrumbs__link:hover { color: var(--nd-color-accent); }
.nd-breadcrumbs__current {
  color: var(--nd-color-ink);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  font-weight: var(--nd-weight-semibold);
}
.nd-breadcrumbs__sep { color: var(--nd-color-rule-strong); }

/* The standalone category kicker is inline-block by design (for cards), so the
   constrained layout can't centre it and it drifts to the far left. Make it a
   block when it's a direct child of the centred content so it lines up with the
   title. (Cards are unaffected — their kicker isn't a constrained child.) */
.nd-root .is-layout-constrained > .wp-block-post-terms.nd-kicker {
  display: block;
}

/* ======================================================================== *
 * Article body links — the theme accent (red), underlined. Only bare content
 * links: anchors with a class belong to embedded components (cards, kickers,
 * bylines, buttons) which keep their own look.
 * ======================================================================== */
.nd-root .nd-prose a:not([class]),
.nd-root .nd-prose a.nd-autolink {
  color: var(--nd-color-accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.nd-root .nd-prose a:not([class]):hover,
.nd-root .nd-prose a.nd-autolink:hover {
  color: var(--nd-color-ink);
}

/* Cards / rails embedded in page or post prose keep their component look —
   the bundle's generic .nd-prose a / .nd-prose h2,h3 rules must not leak in
   (they underlined card titles and pushed them var(--nd-space-6) down). */
.nd-root .nd-prose a[class]:not(.nd-autolink) { text-decoration: none; }
.nd-root .nd-prose .nd-card__title,
.nd-root .nd-prose .nd-hero__title,
.nd-root .nd-prose .nd-trending__head,
.nd-root .nd-prose .nd-storylist__heading { margin-top: 0; }
.nd-root .nd-prose .nd-card__title-link,
.nd-root .nd-prose .nd-hero__title-link,
.nd-root .nd-prose .nd-storylist__title,
.nd-root .nd-prose a.nd-byline__name { color: inherit; }
.nd-root .nd-prose .nd-card__title-link:hover,
.nd-root .nd-prose .nd-hero__title-link:hover,
.nd-root .nd-prose .nd-storylist__title:hover,
.nd-root .nd-prose a.nd-byline__name:hover { color: var(--nd-color-accent); }
.nd-root .nd-prose a.nd-kicker--accent { color: var(--nd-color-accent); }
.nd-root .nd-prose a.nd-kicker--ink { color: var(--nd-color-ink); }
.nd-root .nd-prose a.nd-kicker--muted { color: var(--nd-color-muted); }
.nd-root .nd-prose a.nd-button--primary { color: #fff; }
.nd-root .nd-prose a.nd-button--secondary { color: var(--nd-color-ink); }
.nd-root .nd-prose a.nd-button--secondary:hover { color: var(--nd-color-paper); }

/* Pages (the "no title" template has no .nd-prose wrapper) get the same
   accent links. Only bare text links — p/li anchors without a class — so
   buttons, cards, other pattern components and the core breadcrumbs block
   keep their own colours. */
.nd-root.page .wp-block-post-content p a:not([class]):not(.wp-block-breadcrumbs *),
.nd-root.page .wp-block-post-content li a:not([class]):not(.wp-block-breadcrumbs *) {
  color: var(--nd-color-accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.nd-root.page .wp-block-post-content p a:not([class]):not(.wp-block-breadcrumbs *):hover,
.nd-root.page .wp-block-post-content li a:not([class]):not(.wp-block-breadcrumbs *):hover {
  color: var(--nd-color-ink);
}

/* ======================================================================== *
 * "Read the story" jump button + smooth anchor scrolling
 * ======================================================================== */
html { scroll-behavior: smooth; }
.nd-anchor {
  display: block;
  height: 0;
  scroll-margin-top: 84px; /* clear the sticky masthead */
}
.nd-jumplink-wrap {
  margin: var(--nd-space-2) 0 0;
}
.nd-jumplink {
  font: var(--nd-weight-bold) var(--nd-text-sm)/1 var(--nd-font-sans);
  letter-spacing: 0.02em;
  color: var(--nd-color-accent);
  text-decoration: none;
}
.nd-jumplink:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ======================================================================== *
 * Article body subheads — keep the display face, drop the all-caps, and use
 * editorial spacing: generous space ABOVE a subhead (it starts a new section),
 * tight space to the paragraph it introduces.
 * ======================================================================== */
.nd-root .nd-prose h2,
.nd-root .nd-prose h3,
.nd-root .nd-prose h4 {
  text-transform: none;
  letter-spacing: 0;
  line-height: 1.18;
  margin-top: var(--nd-space-7);
  margin-bottom: 0;
}
.nd-root .nd-prose h2 + *,
.nd-root .nd-prose h3 + *,
.nd-root .nd-prose h4 + * {
  margin-top: var(--nd-space-3);
}
/* First subhead shouldn't push a big gap if it opens the article. */
.nd-root .nd-prose > h2:first-child,
.nd-root .nd-prose > h3:first-child {
  margin-top: 0;
}

/* ======================================================================== *
 * Share buttons — icon bar pinned to the bottom of the viewport
 * (mobile + desktop). Two-class selector so WP layout CSS can't override.
 * ======================================================================== */
.nd-root .nd-share {
  position: fixed;
  left: 50%;
  bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  transform: translate(-50%, 8px);
  z-index: 70; /* above back-to-top / save (60), below cookie banner (100) */
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 5px;
  background: var(--nd-color-paper);
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-pill);
  box-shadow: var(--nd-shadow-md);
  /* Hidden until theme.js adds .is-visible at ≥30% page scroll. */
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
}
.nd-root .nd-share.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}
/* Very narrow phones: slim the pill so it clears the corner buttons. */
@media (max-width: 380px) {
  .nd-root .nd-share { gap: 2px; padding: 4px; }
  .nd-share__btn { width: 36px; height: 36px; }
}
/* Keep the very end of the page reachable under the floating bar. The space
   lives INSIDE the dark footer — as body padding it showed up as a white
   strip below the footer (body background ≠ footer background). */
body.nd-root:has(.nd-share) .nd-footer {
  padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px));
}
.nd-share__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  color: var(--nd-color-ink);
  background: transparent;
  border: none;
  border-radius: var(--nd-radius-pill);
  cursor: pointer;
}
.nd-share__btn svg {
  display: block;
  width: 18px;
  height: 18px;
  fill: currentColor;
}
.nd-share__btn:hover {
  background: var(--nd-color-ink);
  color: var(--nd-color-paper);
  text-decoration: none;
}
.nd-share__copy.is-copied,
.nd-share__copy.is-copied:hover {
  background: var(--nd-color-accent);
  color: #fff;
}
.nd-share__check { display: none; }
.nd-share__copy.is-copied .nd-share__ico { display: none; }
.nd-share__copy.is-copied .nd-share__check { display: block; }

/* Editor canvas link fidelity: the canvas body lacks .nd-root, so the design
   system's link reset never applies there and WP's global styles underline and
   recolour every anchor (site title, hero titles, card titles). Mirror the
   front end: components keep their own look, bare content links get accent. */
.editor-styles-wrapper a:not([class]) {
  color: inherit;
  text-decoration: none;
}
.editor-styles-wrapper p a:not([class]),
.editor-styles-wrapper li a:not([class]) {
  color: var(--nd-color-accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.editor-styles-wrapper .nd-root a[class]:not(.nd-autolink) { text-decoration: none; }

/* In the block-editor canvas the bar must stay in flow, not stick to the
   iframe viewport (style.css is loaded there via enqueue_block_assets). */
.editor-styles-wrapper .nd-share {
  position: static;
  transform: none;
  width: max-content;
  margin-block: var(--nd-space-5);
  opacity: 1;
  visibility: visible;
}

/* ======================================================================== *
 * News Listing — Show more
 * ======================================================================== */
.nd-newslist__grid { margin-bottom: var(--nd-space-6); }
.nd-newslist__more-wrap {
  display: flex;
  justify-content: center;
  margin-top: var(--nd-space-5);
}
.nd-newslist__more[disabled] { opacity: 0.6; cursor: default; }

/* Progressive reveal (Card Grid / Story List "Show more") */
.is-nd-hidden { display: none !important; }

/* ======================================================================== *
 * Mobile: burger menu on the left, search on the right
 * ======================================================================== */
@media (max-width: 860px) {
  /* Show the burger; keep the masthead left clean (hide the dark toggle). */
  .nd-root .nd-masthead__menu-toggle { display: inline-flex; }
  .nd-root .nd-theme-toggle { display: none; }

  /* The bundled design hides the search ≤860px; we keep it (icon, on the
     right) since the nav now lives in the burger instead. */
  .nd-root .nd-masthead__search.wp-block-search { display: flex; }

  /* Section nav becomes a drawer: hidden until the burger opens it, then
     slides down with a soft fade. */
  .nd-root .nd-sectionnav { display: none; }
  .nd-root .nd-sectionnav.is-open {
    display: block;
    border-top: 2px solid var(--nd-color-accent);
    animation: nd-nav-in 0.26s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .nd-root .nd-sectionnav.is-open .nd-sectionnav__list {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    justify-content: flex-start;
    overflow: visible;
    gap: 0;
    padding-block: var(--nd-space-2);
  }
  .nd-root .nd-sectionnav.is-open .nd-sectionnav__item { width: 100%; }
  .nd-root .nd-sectionnav.is-open .nd-sectionnav__link {
    display: flex;
    width: 100%;
    height: auto;
    justify-content: space-between;
    padding: var(--nd-space-3) var(--nd-space-4);
    border-bottom: 1px solid var(--nd-color-rule);
  }

  /* Submenus are collapsed accordions — tap the caret to expand. */
  .nd-root .nd-sectionnav.is-open .nd-sectionnav__item { position: relative; }
  .nd-root .nd-sectionnav.is-open .menu-item-has-children > .nd-sectionnav__link::after { display: none; }
  .nd-root .nd-sectionnav.is-open .menu-item-has-children > .nd-sectionnav__link { padding-right: 56px; }
  /* Submenus stay in the DOM and animate open via max-height (a clip, not a
     display flip), so the expand/collapse is smooth. The accent left border
     marks the nesting. Generous cap covers even the longest section. */
  .nd-root .nd-sectionnav.is-open .sub-menu {
    display: block;
    position: static;
    visibility: visible;
    transform: none;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
    border-left: 2px solid var(--nd-color-accent);
    box-shadow: none;
    background: var(--nd-color-paper-2);
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    transition: max-height 0.3s ease, opacity 0.24s ease;
  }
  /* Open state: opacity via the class; the height is animated inline by JS
     (initSubmenuToggles) to the real content height — no guessed cap to clip
     large / deeply-nested submenus, and a smooth reveal both ways. */
  .nd-root .nd-sectionnav.is-open .nd-sectionnav__item.is-expanded > .sub-menu {
    opacity: 1;
  }
  /* Expanded section: accent the row + caret so it's clear what's open. */
  .nd-root .nd-sectionnav.is-open .menu-item-has-children.is-expanded > .nd-sectionnav__link {
    color: var(--nd-color-accent);
    background: var(--nd-color-accent-soft);
  }
  .nd-root .nd-sectionnav.is-open .nd-sectionnav__item.is-expanded > .nd-submenu-toggle { color: var(--nd-color-accent); }
  /* Submenu items: readable Title-case (not tiny all-caps), lighter weight. */
  .nd-root .nd-sectionnav.is-open .sub-menu .nd-sectionnav__link {
    padding-left: var(--nd-space-6);
    text-transform: none;
    letter-spacing: 0;
    font-weight: var(--nd-weight-semibold);
    color: var(--nd-color-ink-soft);
  }
  .nd-root .nd-sectionnav.is-open .sub-menu .sub-menu .nd-sectionnav__link { padding-left: var(--nd-space-7); }
  .nd-root .nd-sectionnav.is-open .sub-menu .current-menu-item > .nd-sectionnav__link { color: var(--nd-color-accent); }

  /* The injected caret button that toggles each submenu. */
  .nd-root .nd-sectionnav.is-open .nd-submenu-toggle {
    display: flex;
    position: absolute;
    top: 0;
    right: 0;
    width: 52px;
    height: 44px;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--nd-color-rule);
    color: var(--nd-color-ink);
    cursor: pointer;
  }
  .nd-root .nd-sectionnav.is-open .nd-submenu-toggle svg { transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1); }
  .nd-root .nd-sectionnav.is-open .nd-sectionnav__item.is-expanded > .nd-submenu-toggle svg { transform: rotate(180deg); }
  .nd-root .nd-sectionnav.is-open .nd-submenu-toggle:active { background: var(--nd-color-accent-soft); }

  /* ----- Footer: stack on mobile ------------------------------------- */
  .nd-root .nd-footer__inner { grid-template-columns: 1fr; gap: var(--nd-space-6); }
  .nd-root .nd-footer__columns { grid-template-columns: 1fr 1fr; gap: var(--nd-space-5); }
}

/* The submenu caret button is mobile-only (desktop uses hover dropdowns). */
.nd-root .nd-submenu-toggle { display: none; }

/* Mobile drawer entrance. */
@keyframes nd-nav-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .nd-root .nd-sectionnav.is-open { animation: none; }
  .nd-root .nd-sectionnav.is-open .sub-menu { transition: opacity 0.15s ease; }
  .nd-root .nd-sectionnav.is-open .nd-submenu-toggle svg { transition: none; }
}

@media (max-width: 480px) {
  .nd-root .nd-footer__columns { grid-template-columns: 1fr; }
}

/* ======================================================================== *
 * Cookie consent banner (GDPR)
 * Fixed bottom bar; colours use the design tokens so it flips with dark mode.
 * Hidden until JS decides to show it (no flash for visitors who've chosen).
 * ======================================================================== */
.nd-consent {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100; /* above back-to-top (60) */
  background: var(--nd-color-paper);
  border-top: 1px solid var(--nd-color-rule-strong);
  box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.12);
  transform: translateY(100%);
  transition: transform 0.28s ease;
}
.nd-consent.is-open { transform: none; }
.nd-consent[hidden] { display: none; }

.nd-consent__inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--nd-space-4) var(--nd-space-5);
  display: flex;
  align-items: center;
  gap: var(--nd-space-4);
  flex-wrap: wrap;
}
.nd-consent__text {
  margin: 0;
  flex: 1 1 320px;
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  line-height: var(--nd-leading-normal);
  color: var(--nd-color-ink);
}
.nd-consent__text a {
  color: var(--nd-color-accent);
  text-decoration: underline;
}
.nd-consent__actions {
  display: flex;
  gap: var(--nd-space-2);
  flex-shrink: 0;
}
.nd-consent__btn {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 600;
  padding: 0.6em 1.5em;
  border-radius: var(--nd-radius-pill);
  border: 1px solid transparent;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.nd-consent__btn--accept {
  background: var(--nd-color-accent);
  color: #fff;
}
.nd-consent__btn--accept:hover { background: var(--nd-color-ink); }
.nd-consent__btn--ghost {
  background: transparent;
  color: var(--nd-color-ink);
  border-color: var(--nd-color-rule-strong);
}
.nd-consent__btn--ghost:hover { border-color: var(--nd-color-ink); }

@media (max-width: 600px) {
  .nd-consent__inner { padding: var(--nd-space-3) var(--nd-space-4); }
  .nd-consent__actions { width: 100%; }
  .nd-consent__btn { flex: 1; }
}

/* ======================================================================== *
 * Stream / Buy buttons (affiliate)
 * ======================================================================== */
.nd-streamlinks { margin: var(--nd-space-5) 0; }
.nd-streamlinks__label {
  display: block;
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--nd-color-muted);
  margin-bottom: var(--nd-space-2);
}
.nd-streamlinks__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nd-space-2);
}
.nd-streamlinks__btn {
  display: inline-flex;
  align-items: center;
  gap: var(--nd-space-2);
  padding: 0.55em 0.95em;
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-pill);
  background: var(--nd-color-paper);
  color: var(--nd-color-ink);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.nd-streamlinks__btn:hover {
  border-color: var(--nd-color-ink);
  transform: translateY(-1px);
  box-shadow: var(--nd-shadow-sm);
}
.nd-streamlinks__ico { display: inline-flex; flex: none; }
.nd-streamlinks__ico svg { width: 20px; height: 20px; display: block; }
.nd-streamlinks__hint {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  color: var(--nd-color-muted);
}

/* ======================================================================== *
 * Sponsored / paid-content disclosure label
 * ======================================================================== */
.nd-sponsored {
  display: flex;
  align-items: center;
  gap: var(--nd-space-3);
  flex-wrap: wrap;
  margin: 0;
  padding: var(--nd-space-3) var(--nd-space-4);
  background: var(--nd-color-paper-2);
  border: 1px solid var(--nd-color-rule);
  border-left: 4px solid var(--nd-color-accent);
  border-radius: var(--nd-radius-md);
}
.nd-sponsored__tag {
  flex: none;
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #fff;
  background: var(--nd-color-accent);
  padding: 0.25em 0.6em;
  border-radius: var(--nd-radius-sm);
}
.nd-sponsored__text {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  color: var(--nd-color-muted);
}
.nd-sponsored__link {
  color: var(--nd-color-accent);
  text-decoration: underline;
}
/* Give the article body clear separation from the disclosure label. The owl
   spacing only gives the next element var(--nd-space-5); bump it after the
   banner so the story doesn't start right under the label. */
.nd-prose > .nd-sponsored + * {
  margin-top: var(--nd-space-7);
}

/* ======================================================================== *
 * Trending Now widget
 * ======================================================================== */
.nd-trending { margin: 0; }
/* Only the compact list gets the boxed-widget look; numbered (Most Read) and
   cards render clean to match their respective styles. */
.nd-trending--compact {
  border: 1px solid var(--nd-color-rule);
  border-radius: var(--nd-radius-md);
  padding: var(--nd-space-4);
  background: var(--nd-color-paper);
}
/* Reuse the Most Read rail markup with no extra spacing inside the widget. */
.nd-trending .nd-storylist { margin: 0; }
/* Card view: responsive grid that collapses to one column in narrow sidebars. */
.nd-trending__cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--nd-space-4);
}
/* Match the Most Read (.nd-storylist__heading) look exactly so the two widgets
   share one heading style. (For You's "small label" heading joins in too;
   its grid is the Card Grid's own .nd-grid.) */
.nd-foryou__head,
.nd-fromartists__head,
.nd-trending__head {
  display: flex;
  align-items: center;
  gap: var(--nd-space-2);
  margin: 0 0 var(--nd-space-2);
  padding-bottom: var(--nd-space-3);
  border-bottom: 2px solid var(--nd-color-ink);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: var(--nd-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--nd-tracking-wide);
  color: var(--nd-color-ink);
}
.nd-trending__flame { color: var(--nd-color-accent); flex: none; }
.nd-trending__list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: nd-trend;
}
.nd-trending__item { border-top: 1px solid var(--nd-color-rule); }
.nd-trending__item:first-child { border-top: 0; }
.nd-trending__link {
  display: flex;
  align-items: center;
  gap: var(--nd-space-3);
  padding: var(--nd-space-3) 0;
  text-decoration: none;
  color: var(--nd-color-ink);
}
.nd-trending__rank {
  flex: none;
  width: 1.6em;
  font-family: var(--nd-font-display);
  font-size: var(--nd-text-xl);
  line-height: 1;
  color: var(--nd-color-rule-strong);
  text-align: center;
}
.nd-trending__link:hover .nd-trending__rank { color: var(--nd-color-accent); }
.nd-trending__thumb {
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: var(--nd-radius-sm);
  overflow: hidden;
  background: var(--nd-color-paper-3);
}
.nd-trending__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.nd-trending__body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.nd-trending__title {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 600;
  line-height: 1.3;
}
.nd-trending__link:hover .nd-trending__title { color: var(--nd-color-accent); }
.nd-trending__views {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  color: var(--nd-color-subtle);
}

/* ======================================================================== *
 * Accessibility
 * ======================================================================== */

/* Skip-to-content link (injected by theme.js). Hidden off-screen until it
   receives keyboard focus, then slides into view. */
.nd-skiplink {
  position: fixed;
  top: -120px;
  left: var(--nd-space-4);
  z-index: 200;
  padding: var(--nd-space-2) var(--nd-space-4);
  background: var(--nd-color-accent);
  color: #fff;
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 600;
  text-decoration: none;
  border-radius: 0 0 var(--nd-radius-md) var(--nd-radius-md);
  transition: top 0.15s ease;
}
.nd-skiplink:focus {
  top: 0;
  outline: 2px solid #fff;
  outline-offset: -4px;
}
/* The main region gets tabindex=-1 so the skip link can move focus to it
   without showing a focus ring on the whole page region. */
main:focus { outline: none; }

/* Guarantee a visible keyboard-focus indicator on the theme's interactive
   controls (mouse clicks stay clean via :focus-visible). */
.nd-root a:focus-visible,
.nd-iconbtn:focus-visible,
.nd-backtotop:focus-visible,
.nd-masthead__menu-toggle:focus-visible,
.nd-submenu-toggle:focus-visible,
.nd-streamlinks__btn:focus-visible,
.nd-consent__btn:focus-visible,
.nd-trending__link:focus-visible,
.nd-instant__card:focus-visible,
.nd-instant__artist:focus-visible,
.nd-instant__seeall:focus-visible,
.nd-instant__close:focus-visible,
.nd-instant__all:focus-visible {
  outline: 2px solid var(--nd-color-link);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Respect users who prefer reduced motion: drop animations/transitions. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ======================================================================== *
 * Tweaks
 * ======================================================================== */

/* Accessibility: nudge the subtle text colour to meet WCAG AA (4.5:1). The DS
   token is #8a8a8a ≈ 3.5:1 on white — too light for the meta lines it carries.
   #666 is chosen so it also clears AA on the TINTED surfaces (paper-2 #f5f5f4,
   paper-3 #e9e9e7 — 4.7:1), not just on paper; #6e6e6e only cleared it on
   white. The dark-mode value lives with the other dark tokens above. */
:root { --nd-color-subtle: #666666; }

/* Tighten the gap between the header and the first content block (was 2rem). */
.nd-root main.nd-container { padding-top: var(--wp--preset--spacing--30) !important; }

/* ======================================================================== *
 * News Slider (swipeable rail, native scroll-snap)
 * ======================================================================== */
.nd-slider { margin: var(--nd-space-4) 0; }
.nd-slider__head {
  margin: 0 0 var(--nd-space-3);
  font-family: var(--nd-font-display);
  font-weight: var(--nd-weight-regular, 400);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-size: var(--nd-text-lg);
  color: var(--nd-color-ink);
}
.nd-slider__track {
  --nd-gap: var(--nd-space-3);
  --nd-per: 2;
  display: flex;
  gap: var(--nd-gap);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  touch-action: pan-x; /* lock gestures to horizontal — no vertical wobble */
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.nd-slider__track::-webkit-scrollbar { display: none; }

/* --- Slide (shared) --------------------------------------------------- */
.nd-slide {
  flex: 0 0 calc((100% - (var(--nd-per) - 1) * var(--nd-gap)) / var(--nd-per));
  scroll-snap-align: start;
  min-width: 0;
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: var(--nd-color-ink);
}
.nd-slide:focus-visible {
  outline: 2px solid var(--nd-color-link);
  outline-offset: 2px;
}
.nd-slide__media {
  display: block;
  overflow: hidden;
  background: var(--nd-color-paper-3);
}
.nd-slide__img,
.nd-slide__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.nd-slide__kicker { margin-bottom: 2px; }
.nd-slide__title {
  font-family: var(--nd-font-sans);
  font-weight: 700;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.nd-slide__dek {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  color: var(--nd-color-muted);
}
.nd-slide__date {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  color: var(--nd-color-subtle);
}

/* --- Card layout: image on top, text below --------------------------- */
.nd-slide--card .nd-slide__media { aspect-ratio: 3 / 2; border-radius: var(--nd-radius-md); }
.nd-slide--card .nd-slide__body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: var(--nd-space-2) 0 0;
}
.nd-slide--card .nd-slide__title { font-size: var(--nd-text-sm); }
.nd-slide--card:hover .nd-slide__title { color: var(--nd-color-accent); }

/* --- Overlay layout: title over image with a dark scrim -------------- */
.nd-slide--overlay {
  position: relative;
  border-radius: var(--nd-radius-md);
  overflow: hidden;
}
.nd-slide--overlay .nd-slide__media { aspect-ratio: 4 / 3; }
.nd-slide--overlay .nd-slide__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.85) 0%,
    rgba(0, 0, 0, 0.45) 35%,
    rgba(0, 0, 0, 0) 65%
  );
}
.nd-slide--overlay .nd-slide__body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--nd-space-3);
  color: #fff;
}
.nd-slide--overlay .nd-slide__title { color: #fff; font-size: var(--nd-text-md); }
.nd-slide--overlay .nd-slide__dek,
.nd-slide--overlay .nd-slide__date { color: rgba(255, 255, 255, 0.85); }

/* Smaller list/slide titles on phones (they read too large in narrow rails). */
@media (max-width: 781px) {
  .nd-storylist__title { font-size: var(--nd-text-sm); }
  .nd-slide--overlay .nd-slide__title { font-size: var(--nd-text-sm); }

  /* Trending: a touch smaller still, and capped at two lines. */
  .nd-trending .nd-storylist__title,
  .nd-trending__title {
    font-size: var(--nd-text-xs);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}
.nd-events__filters,
.nd-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nd-space-2);
  margin-bottom: var(--nd-space-3);
}
.nd-events__filter,
.nd-filter {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  min-width: 170px;
  padding: 0.45em 0.7em;
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-md);
  background: var(--nd-color-paper);
  color: var(--nd-color-ink);
}
/* iOS zooms into any input under 16px on focus — bump it on phones. */
@media (max-width: 781px) {
  .nd-events__filter,
  .nd-filter { font-size: 16px; }
}
/* Searchable filter dropdown (combobox). */
.nd-events__fbox,
.nd-fbox { position: relative; }
.nd-events__dd,
.nd-dd {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 60;
  min-width: 100%;
  max-height: 260px;
  overflow-y: auto;
  background: var(--nd-color-paper);
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-md);
  box-shadow: var(--nd-shadow-md);
}
.nd-events__dd[hidden],
.nd-dd[hidden] { display: none; }
.nd-events__opt,
.nd-opt {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.5em 0.85em;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--nd-color-rule);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  color: var(--nd-color-ink);
  white-space: nowrap;
  cursor: pointer;
}
.nd-events__opt:last-child,
.nd-opt:last-child { border-bottom: 0; }
.nd-events__opt:hover,
.nd-opt:hover { background: var(--nd-color-paper-2); color: var(--nd-color-accent); }
/* The theme's global `.nd-root :where(a)` (and `.nd-prose a`) would recolour /
   underline these links — pin the button text so it stays white & readable
   everywhere (archive page, in-content, hover). */
.nd-events .nd-events__tickets,
.nd-events .nd-events__tickets:hover,
.nd-prose .nd-events__tickets,
.nd-prose .nd-events__tickets:hover { color: #fff; text-decoration: none; }
.nd-events .nd-cal__opt,
.nd-prose .nd-cal__opt,
.nd-prose .nd-events__title { text-decoration: none; }
.nd-prose .nd-events__title { color: var(--nd-color-ink); }
.nd-prose .nd-events__title:hover { color: var(--nd-color-accent); }
.nd-events__more-wrap,
.nd-more-wrap { text-align: center; margin-top: var(--nd-space-4); }
.nd-events__more,
.nd-more {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 600;
  padding: 0.6em 1.6em;
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-pill);
  background: var(--nd-color-paper);
  color: var(--nd-color-ink);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.nd-events__more:hover,
.nd-more:hover { border-color: var(--nd-color-ink); background: var(--nd-color-paper-2); }
.nd-prose .nd-events__more { text-decoration: none; }
.nd-prose .nd-events__past-link { text-decoration: none; }
.nd-prose .nd-events__act { text-decoration: none; }
.nd-prose .nd-events__act--link:hover { color: var(--nd-color-accent); }

/* ======================================================================== *
 * Archive chrome: the window switch and the one-box search.
 *
 * Shared by Releases and Events on purpose — they are the same two controls
 * doing the same two jobs, and a reader moving between the archives should not
 * have to learn the page twice. Unprefixed names for the same reason .nd-filters
 * and .nd-more above are unprefixed. Lives in style.css rather than a per-block
 * file because two archives need it and two copies would drift.
 * ======================================================================== */

/* Links, not buttons — so they carry the theme's global anchor styling and have
   to opt out of it explicitly, the same way .nd-events__tickets does. Sized off
   .nd-more so the switch and the button under the list are one family. */
.nd-switch {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nd-space-2);
  margin-bottom: var(--nd-space-3);
}
.nd-root .nd-switch__tab,
.nd-prose .nd-switch__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--nd-space-2);
  /* 44px tall on touch: this is the primary control on the page and half the
     readers are on a phone. */
  min-height: 44px;
  padding: 0.45em 1.1em;
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-pill);
  background: var(--nd-color-paper);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 600;
  line-height: 1.2;
  color: var(--nd-color-ink);
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
/* The count is the reason the switch is worth its space — it says how much is
   behind each tab before anyone clicks, and how a search landed once they type.
   Kept quieter than the label so it reads as an annotation. */
.nd-switch__n {
  font-family: var(--nd-font-mono);
  font-size: var(--nd-text-xs);
  font-weight: var(--nd-weight-regular);
  color: var(--nd-color-subtle);
}
.nd-root .nd-switch__tab.is-active,
.nd-prose .nd-switch__tab.is-active {
  background: var(--nd-color-accent);
  border-color: var(--nd-color-accent);
  color: var(--nd-color-accent-ink);
}
/* Held just off white — quiet enough to read as an annotation, still over 4.5:1
   on the accent. The count is the reason this control earns its space; it does
   not get to be decorative. */
.nd-switch__tab.is-active .nd-switch__n { color: rgba(255, 255, 255, 0.85); }
/* An empty window still gets a tab: hiding it would leave the reader guessing
   whether the section exists at all. It just stops advertising itself. */
.nd-switch__tab.is-none:not(.is-active) { color: var(--nd-color-subtle); }
@media (hover: hover) {
  .nd-root .nd-switch__tab:hover,
  .nd-prose .nd-switch__tab:hover {
    border-color: var(--nd-color-ink);
    background: var(--nd-color-paper-2);
  }
  .nd-root .nd-switch__tab.is-active:hover,
  .nd-prose .nd-switch__tab.is-active:hover {
    background: var(--nd-color-accent);
    border-color: var(--nd-color-accent);
    color: var(--nd-color-accent-ink);
  }
}
/* Releases' three tabs come to ~362px, just wider than a 375px phone minus its
   gutters — so they wrap to two rows and the switch costs 96px of a screen that
   has none to spare. Tightening the sides buys the ~25px that fits them on one
   line, and the height stays 44px. If a translation is longer they simply wrap
   again, which is why this is padding and not nowrap. */
@media (max-width: 480px) {
  .nd-switch { gap: var(--nd-space-1); }
  .nd-root .nd-switch__tab,
  .nd-prose .nd-switch__tab { padding: 0.45em 0.8em; }
}
@media (prefers-reduced-motion: reduce) {
  .nd-switch__tab { transition: none; }
}

/* Several controls became one. The box has to LOOK like a single field while
   holding chips and a text input, so the border lives on the wrapper and the
   input inside it is stripped bare — otherwise you get a box inside a box. */
.nd-root .nd-seek {
  flex: 1 1 260px;
  min-width: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--nd-space-2);
  padding: 0.3em 0.7em;
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-md);
  background: var(--nd-color-paper);
  cursor: text;
}
.nd-root .nd-seek:focus-within { border-color: var(--nd-color-ink); }
.nd-root .nd-seek__input {
  flex: 1 1 8em;
  min-width: 8em;
  /* The wrapper is the field now. */
  border: 0;
  border-radius: 0;
  background: none;
  padding: 0.35em 0;
  min-height: 38px;
}
.nd-root .nd-seek__input:focus { outline: none; }
.nd-seek__chips { display: contents; }
/* A pinned facet: an exact filter, as opposed to the text you are still typing.
   Solid accent rather than the accent-on-accent-soft tint used elsewhere — at
   12px bold that tint measures 2.9:1 in dark mode, and this is the only thing on
   screen telling you what the list is filtered to. Same fill as the active tab,
   so "pinned" looks the same wherever it appears. */
.nd-root .nd-seek__chip,
.nd-prose .nd-seek__chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.25em 0.5em 0.25em 0.7em;
  border-radius: var(--nd-radius-pill);
  background: var(--nd-color-accent);
  color: var(--nd-color-accent-ink);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  font-weight: 700;
  line-height: 1.4;
  text-decoration: none;
  white-space: nowrap;
  max-width: 100%;
}
.nd-seek__chiptext { overflow: hidden; text-overflow: ellipsis; }
.nd-seek__chipx { font-size: 1.15em; line-height: 1; opacity: 0.75; }
/* Hover is the REMOVE affordance, so it darkens rather than brightens. */
@media (hover: hover) {
  .nd-root .nd-seek__chip:hover,
  .nd-prose .nd-seek__chip:hover { background: var(--nd-color-ink); color: var(--nd-color-paper); }
  .nd-root .nd-seek__chip:hover .nd-seek__chipx { opacity: 1; }
}
/* The suggestion list hangs off the whole box, not off the input. */
.nd-seek .nd-dd { top: calc(100% + 4px); left: 0; right: 0; }
/* A suggestion row: the name on the left, what kind of thing it is on the
   right, so the names stay one scannable column. */
.nd-seek .nd-opt { display: flex; align-items: center; }
/* Picking one is the main interaction on these pages, and half these readers are
   on a phone where the shared 29px row is a miss waiting to happen. */
@media (pointer: coarse) {
  .nd-seek .nd-opt { min-height: 44px; }
}
/* Group headers. Sticky, because typing "artist" can open a list of hundreds
   and the reader should still know what they are scrolling. */
.nd-root .nd-opt__head {
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 0;
  padding: var(--nd-space-2) 0.85em;
  background: var(--nd-color-paper-2);
  border-bottom: 1px solid var(--nd-color-rule);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--nd-color-subtle);
}
.nd-opt__head[hidden] { display: none; }
/* What the box can do, shown the moment it is focused — otherwise nobody
   discovers that the words in the placeholder open anything. */
.nd-root .nd-seek__hint {
  margin: 0;
  padding: 0.7em 0.85em;
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  line-height: 1.45;
  color: var(--nd-color-subtle);
}
.nd-seek__hint[hidden] { display: none; }
/* "31 releases" / "9 shows" — the running total, pushed to the end of the
   filter row. */
.nd-releases__count,
.nd-count {
  font-size: var(--nd-text-xs);
  color: var(--nd-color-subtle);
  margin-left: auto;
  align-self: center;
}

/* Only one list is on screen at a time once the switch is live. */
.nd-switchable[hidden] { display: none; }

/* The heading above each list. It is what tells the two lists apart with no
   JavaScript; the script hides it, because by then the lit tab says the same. */
.nd-events__winhead {
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--nd-color-muted);
  margin: var(--nd-space-4) 0 var(--nd-space-2);
}
.nd-events__winhead[hidden] { display: none; }


/* ----- Reading UX: progress bar, bookmarks, continue-reading chip -------- */

/* Thin accent bar across the very top of article pages. */
.nd-progress {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	z-index: 90;
	pointer-events: none;
	background: transparent;
}
.nd-progress__fill {
	display: block;
	height: 100%;
	background: var(--nd-color-accent);
	transform: scaleX(0);
	transform-origin: left center;
}

/* Floating "save for later" button on articles (mirrors .nd-backtotop). */
.nd-savebtn {
	position: fixed;
	left: var(--nd-space-5);
	bottom: var(--nd-space-5);
	width: 44px;
	height: 44px;
	border: none;
	border-radius: var(--nd-radius-pill);
	background: var(--nd-color-ink);
	color: var(--nd-color-paper);
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	z-index: 60;
	box-shadow: var(--nd-shadow-md);
}
.nd-savebtn:hover,
.nd-savebtn.is-saved { background: var(--nd-color-accent); }

/* Inline save pill in the byline (icon + label), pushed to the row's end. */
.nd-savebtn--inline {
	position: static;
	width: auto;
	height: auto;
	margin-left: auto;
	padding: 5px 12px;
	gap: 6px;
	background: transparent;
	color: var(--nd-color-ink);
	border: 1px solid var(--nd-color-rule-strong);
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-xs);
	font-weight: 700;
	box-shadow: none;
}
.nd-savebtn--inline:hover { background: var(--nd-color-paper-2); border-color: var(--nd-color-ink); }
.nd-savebtn--inline.is-saved {
	background: var(--nd-color-accent-soft);
	border-color: var(--nd-color-accent);
	color: var(--nd-color-accent);
}
.nd-savebtn--inline svg { width: 16px; height: 16px; }
.nd-savebtn__label { line-height: 1; }

/* Mobile sticky title bar — appears once the article title scrolls off. Sits
   just under the pinned breaking ticker; truncated title + a save button. */
.nd-stickytitle { display: none; }
@media (max-width: 860px) {
	.nd-stickytitle {
		position: fixed;
		top: var(--nd-brkh, 0px);
		left: 0;
		right: 0;
		z-index: 58; /* under the breaking ticker (60), above content */
		display: flex;
		align-items: center;
		gap: var(--nd-space-3);
		padding: 8px 14px;
		padding-left: max(14px, env(safe-area-inset-left));
		padding-right: max(14px, env(safe-area-inset-right));
		background: var(--nd-color-paper);
		border-bottom: 1px solid var(--nd-color-rule);
		box-shadow: var(--nd-shadow-sm, 0 2px 8px rgba(0, 0, 0, 0.08));
		/* Translate3d + will-change keep the slide on the compositor — iOS
		   Safari otherwise repaints the fixed bar every scroll frame, which
		   is the jank. transition is transform-only for the same reason. */
		transform: translate3d(0, -110%, 0);
		will-change: transform;
		-webkit-backface-visibility: hidden;
		backface-visibility: hidden;
		transition: transform 0.24s cubic-bezier(0.22, 0.61, 0.36, 1);
		pointer-events: none;
	}
	.nd-stickytitle.is-visible {
		transform: translate3d(0, 0, 0);
		pointer-events: auto;
	}
	.nd-stickytitle__text {
		flex: 1;
		min-width: 0;
		font-family: var(--nd-font-display);
		font-weight: var(--nd-weight-regular);
		text-transform: uppercase;
		font-size: var(--nd-text-md);
		line-height: 1.1;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}
	.nd-savebtn--sticky {
		position: static;
		flex: none;
		width: 38px;
		height: 38px;
		box-shadow: none;
		background: transparent;
		color: var(--nd-color-ink);
		border: 1px solid var(--nd-color-rule-strong);
	}
	.nd-savebtn--sticky.is-saved {
		background: var(--nd-color-accent-soft);
		border-color: var(--nd-color-accent);
		color: var(--nd-color-accent);
	}
	.nd-savebtn--sticky svg { width: 18px; height: 18px; }
}

/* Saved-stories dropdown panel (opened from the masthead bookmark icon,
   which sits on the right next to the search — so anchor right). */
.nd-bookmarks {
	position: fixed;
	top: 72px;
	right: 12px;
	width: min(340px, calc(100vw - 24px));
	max-height: min(60vh, 480px);
	overflow: auto;
	background: var(--nd-color-paper);
	border: 1px solid var(--nd-color-rule);
	border-radius: var(--nd-radius-md);
	box-shadow: var(--nd-shadow-md);
	z-index: 80;
	padding: 10px;
}
.nd-bookmarks__head {
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: 0.8rem;
	padding: 4px 6px 10px;
	border-bottom: 1px solid var(--nd-color-rule);
	margin-bottom: 6px;
}
.nd-bookmarks__empty { margin: 8px 6px; color: var(--nd-color-subtle); font-size: 0.9rem; }
.nd-bookmarks__list { list-style: none; margin: 0; padding: 0; }
.nd-bookmarks__item { display: flex; align-items: center; gap: 6px; }
.nd-bookmarks__link {
	flex: 1;
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 7px 6px;
	text-decoration: none;
	color: inherit;
	border-radius: var(--nd-radius-md);
	min-width: 0;
}
.nd-bookmarks__link:hover { background: var(--nd-color-accent-soft); }
.nd-bookmarks__thumb {
	width: 44px;
	height: 34px;
	object-fit: cover;
	border-radius: 3px;
	flex: none;
	background: var(--nd-color-rule);
}
.nd-bookmarks__title {
	font-size: 0.88rem;
	line-height: 1.3;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.nd-bookmarks__rm {
	flex: none;
	border: none;
	background: transparent;
	color: var(--nd-color-subtle);
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
	padding: 6px 8px;
	border-radius: var(--nd-radius-pill);
}
.nd-bookmarks__rm:hover { color: var(--nd-color-accent); background: var(--nd-color-accent-soft); }

/* "Continue reading" chip, bottom-left, above the save button. */
.nd-resume {
	position: fixed;
	left: var(--nd-space-5);
	/* Track the share bar: it sits at 10px + safe-area and is ~52px tall,
	   so without the inset added here it slides under this chip on phones
	   with a home indicator. */
	bottom: calc(84px + env(safe-area-inset-bottom, 0px));
	display: flex;
	align-items: stretch;
	max-width: min(340px, calc(100vw - 48px));
	background: var(--nd-color-paper);
	border: 1px solid var(--nd-color-rule);
	border-radius: var(--nd-radius-md);
	box-shadow: var(--nd-shadow-md);
	z-index: 60;
	overflow: hidden;
	transition: opacity 0.35s ease, transform 0.35s ease;
}
.nd-resume.is-leaving { opacity: 0; transform: translateY(8px); }
.nd-resume__link {
	display: block;
	padding: 10px 12px;
	text-decoration: none;
	color: inherit;
	min-width: 0;
}
.nd-resume__link:hover { background: var(--nd-color-accent-soft); }
.nd-resume__kicker {
	display: block;
	font-size: 0.7rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--nd-color-accent);
	margin-bottom: 2px;
}
.nd-resume__title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: 0.88rem;
	line-height: 1.3;
}
.nd-resume__close {
	flex: none;
	border: none;
	border-left: 1px solid var(--nd-color-rule);
	background: transparent;
	color: var(--nd-color-subtle);
	font-size: 1.1rem;
	cursor: pointer;
	padding: 0 12px;
}
.nd-resume__close:hover { color: var(--nd-color-accent); background: var(--nd-color-accent-soft); }

/* ----- Post UX: reactions, prev/next nav, up-next, listen, share, lightbox */

/* Reactions bar under the article. */
.nd-react {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--nd-space-3);
	margin-top: var(--nd-space-6);
	padding: var(--nd-space-4);
	border: 1px solid var(--nd-color-rule);
	border-radius: var(--nd-radius-md);
}
.nd-react__label {
	font-family: var(--nd-font-sans);
	font-weight: 700;
	font-size: var(--nd-text-sm);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}
.nd-react__btns { display: flex; gap: var(--nd-space-2); flex-wrap: wrap; }
.nd-react__btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 12px;
	border: 1px solid var(--nd-color-rule);
	border-radius: var(--nd-radius-pill);
	background: var(--nd-color-paper);
	cursor: pointer;
	font-size: 1rem;
	line-height: 1;
	transition: transform 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.nd-react__btn:hover { transform: translateY(-1px) scale(1.04); border-color: var(--nd-color-ink); }
.nd-react__count {
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-xs);
	font-weight: 700;
	color: var(--nd-color-subtle);
}
.nd-react.is-done .nd-react__btn { cursor: default; opacity: 0.55; }
.nd-react.is-done .nd-react__btn:hover { transform: none; border-color: var(--nd-color-rule); }
.nd-react.is-done .nd-react__btn.is-chosen {
	opacity: 1;
	border-color: var(--nd-color-accent);
	background: var(--nd-color-accent-soft);
}
.nd-react.is-done .nd-react__btn.is-chosen .nd-react__count { color: var(--nd-color-accent); }

/* Previous / next article nav. */
.nd-postnav {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--nd-space-3);
	margin-top: var(--nd-space-4);
}
.nd-postnav__link {
	display: block;
	padding: var(--nd-space-3) var(--nd-space-4);
	border: 1px solid var(--nd-color-rule);
	border-radius: var(--nd-radius-md);
	text-decoration: none;
	color: inherit;
	min-width: 0;
}
.nd-postnav__link:hover { border-color: var(--nd-color-ink); background: var(--nd-color-accent-soft); }
.nd-postnav__link--next { text-align: right; grid-column: 2; }
.nd-postnav__link--prev { grid-column: 1; }
.nd-postnav__dir {
	display: block;
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-xs);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--nd-color-accent);
	margin-bottom: 4px;
}
.nd-postnav__title {
	font-family: var(--nd-font-sans);
	font-weight: 600;
	font-size: var(--nd-text-sm);
	line-height: 1.35;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
@media (max-width: 600px) {
	.nd-postnav { grid-template-columns: 1fr; }
	.nd-postnav__link--next { grid-column: 1; text-align: left; }
}

/* "Up next" banner (bottom-right, above back-to-top). */
.nd-upnext {
	position: fixed;
	right: var(--nd-space-5);
	/* Same safe-area tracking as .nd-resume — keeps it clear of the share bar. */
	bottom: calc(84px + env(safe-area-inset-bottom, 0px));
	display: flex;
	align-items: center;
	gap: 10px;
	max-width: min(340px, calc(100vw - 48px));
	padding: 10px 12px;
	background: var(--nd-color-paper);
	border: 1px solid var(--nd-color-rule);
	border-radius: var(--nd-radius-md);
	box-shadow: var(--nd-shadow-md);
	text-decoration: none;
	color: inherit;
	z-index: 60;
	opacity: 0;
	visibility: hidden;
	transform: translateY(8px);
	transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
}
.nd-upnext.is-visible { opacity: 1; visibility: visible; transform: none; }
.nd-upnext:hover { border-color: var(--nd-color-ink); }
.nd-upnext__thumb {
	width: 52px;
	height: 40px;
	object-fit: cover;
	border-radius: 3px;
	flex: none;
	background: var(--nd-color-rule);
}
.nd-upnext__body { min-width: 0; }
.nd-upnext__kicker {
	display: block;
	font-family: var(--nd-font-sans);
	font-size: 0.68rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--nd-color-accent);
	margin-bottom: 2px;
}
.nd-upnext__title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-family: var(--nd-font-sans);
	font-size: 0.85rem;
	font-weight: 600;
	line-height: 1.3;
}
.nd-upnext__close {
	flex: none;
	border: none;
	background: transparent;
	color: var(--nd-color-subtle);
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
	padding: 4px 6px;
	align-self: flex-start;
}
.nd-upnext__close:hover { color: var(--nd-color-accent); }

/* "Listen" button at the top of the article body.
   Two classes on purpose: core prints its post-content layout CSS AFTER the
   theme stylesheet, and its "> *" rules zero children's block margins at
   single-class specificity — a bare .nd-listenbtn margin silently loses.
   (Same trick as .nd-root .nd-masthead__inner.) */
.nd-root .nd-listenbtn {
	display: flex;
	width: fit-content;
	align-items: center;
	gap: 8px;
	padding: 7px 14px;
	margin: 0 0 var(--nd-space-6);
	border: 1px solid var(--nd-color-rule-strong);
	border-radius: var(--nd-radius-pill);
	background: var(--nd-color-paper);
	color: var(--nd-color-ink);
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-sm);
	font-weight: 700;
	cursor: pointer;
	transition: border-color 0.12s ease, background 0.12s ease;
}
.nd-listenbtn:hover { border-color: var(--nd-color-ink); }
.nd-listenbtn.is-active {
	border-color: var(--nd-color-accent);
	background: var(--nd-color-accent-soft);
	color: var(--nd-color-accent);
}
.nd-poll__kicker,
.nd-quiz__kicker {
	display: inline-block;
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-xs);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: var(--nd-tracking-wide);
	color: var(--nd-color-accent);
	margin-bottom: var(--nd-space-2);
}
.nd-poll__q,
.nd-quiz__title {
	margin: 0 0 var(--nd-space-4);
	font-size: var(--nd-text-lg);
	line-height: 1.25;
}
.nd-poll__share,
.nd-quiz__share,
.nd-quiz__again,
.nd-quiz__next,
.nd-quiz__start {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 7px 14px;
	border: 1px solid var(--nd-color-rule-strong);
	border-radius: var(--nd-radius-pill);
	background: var(--nd-color-paper);
	color: var(--nd-color-ink);
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-sm);
	font-weight: 700;
	cursor: pointer;
	transition: border-color 0.12s ease, background 0.12s ease;
}
.nd-poll__share:hover,
.nd-quiz__share:hover,
.nd-quiz__again:hover,
.nd-quiz__next:hover,
.nd-quiz__start:hover { border-color: var(--nd-color-ink); }

/* Editor-only UI for both blocks. */
.nd-poll__edit-list,
.nd-quiz__edit-list { display: flex; flex-direction: column; gap: var(--nd-space-2); }
.nd-poll__edit-row,
.nd-quiz__edit-a {
	display: flex;
	align-items: center;
	gap: var(--nd-space-2);
	padding: 6px 10px;
	border: 1px dashed var(--nd-color-rule);
	border-radius: var(--nd-radius-sm);
}
.nd-poll__edit-opt,
.nd-quiz__edit-a-text { flex: 1; }
.nd-poll__edit-tools,
.nd-quiz__edit-tools { display: flex; gap: 2px; }
.nd-poll__edit-hint,
.nd-quiz__edit-hint {
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-xs);
	color: var(--nd-color-subtle);
}

/* ----- "For you" recommendations ------------------------------------------ */

.nd-foryou { margin-top: var(--nd-space-6); }
.nd-foryou__edit-note {
	padding: var(--nd-space-3);
	border: 1px dashed var(--nd-color-rule);
	border-radius: var(--nd-radius-sm);
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-xs);
	color: var(--nd-color-subtle);
}

/* ----- Discreet motion ----------------------------------------------------
   theme.js adds html.nd-fx + .nd-fx-item only when JS runs, motion is OK and
   the element starts below the fold — so nothing is ever hidden without JS
   and above-the-fold content never flashes in. */
html.nd-fx .nd-fx-item {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 0.45s ease, transform 0.45s ease;
}
html.nd-fx .nd-fx-item.is-inview {
	opacity: 1;
	transform: translateY(0);
}
/* Soft image zoom on card hover (pointer devices only). Multiplies the
   article's own framing zoom (--nd-zoom) instead of replacing it. */
@media (hover: hover) {
	.nd-card__media { overflow: hidden; }
	.nd-card__media .nd-card__image { transition: transform 0.35s ease; }
	.nd-card:hover .nd-card__media .nd-card__image { transform: scale(calc(var(--nd-zoom, 1) * 1.03)); }
}
@media (prefers-reduced-motion: reduce) {
	html.nd-fx .nd-fx-item { opacity: 1; transform: none; transition: none; }
	.nd-card__media .nd-card__image { transition: none; }
	.nd-card:hover .nd-card__media .nd-card__image { transform: scale(var(--nd-zoom, 1)); }
}

/* ----- Per-article image framing (focal point + zoom) --------------------- */
/* inc/focal.php writes --nd-focal / --nd-zoom inline on teaser images for
   articles with a saved framing ("Featured image framing" editor panel).
   Untouched articles keep the defaults below — pixel-identical to before.
   .nd-card__media img also catches the core Post Featured Image block used
   as a card in the archive templates. */
.nd-root .nd-card__image,
.nd-root .nd-card__media img,
.nd-root .nd-hero__image,
.nd-root .nd-slide__img,
.nd-root .nd-slide__media img,
.nd-root .nd-trending__thumb img {
	object-position: var(--nd-focal, 50% 50%);
	transform: scale(var(--nd-zoom, 1));
	transform-origin: var(--nd-focal, 50% 50%);
}
/* The bundle's own card-hover rule must stay multiplicative with the zoom. */
.nd-root .nd-card__media:hover .nd-card__image {
	transform: scale(calc(var(--nd-zoom, 1) * 1.03));
}
@media (prefers-reduced-motion: reduce) {
	.nd-root .nd-card__media:hover .nd-card__image { transform: scale(var(--nd-zoom, 1)); }
}
/* JS-rendered thumbs (instant search, saved stories, up-next): bare <img>
   elements without an overflow-hidden wrapper, so they take the focal shift
   only — a transform zoom would bleed outside their rounded box. */
.nd-root .nd-instant__img,
.nd-root .nd-bookmarks__thumb,
.nd-root .nd-upnext__thumb {
	object-position: var(--nd-focal, 50% 50%);
}
/* With the scroll-reveal active, bars grow to their width on first view. */
html.nd-fx .nd-chart__row.nd-fx-item .nd-chart__barfill {
	width: 0;
	transition: width 0.8s ease 0.2s;
}
html.nd-fx .nd-chart__row.nd-fx-item.is-inview .nd-chart__barfill { width: var(--nd-bar, 0%); }
.nd-chart__edit-hint,
.nd-branch__edit-hint {
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-xs);
	color: var(--nd-color-subtle);
}
.nd-remix__head .nd-section__head { margin-bottom: var(--nd-space-2); }

/* ======================================================================== *
 * Mobile tab bar — Instagram-style bottom pill (built by theme.js initTabBar):
 * Home / Events / Search / Saved (+ Share on pages with the share bar; it
 * opens the native share sheet, so the classic floating share pill and the
 * back-to-top button are hidden on mobile — that's how they coexist).
 * ======================================================================== */
.nd-tabbar { display: none; }
@media (max-width: 860px) {
	.nd-tabbar {
		position: fixed;
		left: 50%;
		transform: translateX(-50%);
		bottom: calc(10px + env(safe-area-inset-bottom, 0px));
		z-index: 72; /* above back-to-top/share (70), under search overlay (95) */
		display: flex;
		align-items: center;
		gap: 4px;
		padding: 6px;
		background: rgba(10, 10, 10, 0.92);
		border-radius: var(--nd-radius-pill);
		box-shadow: var(--nd-shadow-md);
		-webkit-backdrop-filter: blur(8px);
		backdrop-filter: blur(8px);
	}
	.nd-tabbar__btn {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 48px;
		height: 44px;
		border: 0;
		background: none;
		color: #f2f2f2;
		border-radius: var(--nd-radius-pill);
		cursor: pointer;
	}
	.nd-tabbar__btn.is-active { background: rgba(255, 255, 255, 0.16); }
	.nd-tabbar__btn:active { background: rgba(255, 255, 255, 0.1); }

	/* Coexistence: the bar replaces the floating share pill and back-to-top
	   on mobile, and the footer reserves room for it. */
	body.nd-tabbar-on .nd-share { display: none; }
	body.nd-tabbar-on.nd-share-forced .nd-share {
		display: flex;
		bottom: calc(84px + env(safe-area-inset-bottom, 0px));
	}
	body.nd-tabbar-on .nd-backtotop { display: none; }
	body.nd-root.nd-tabbar-on .nd-footer {
		padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px));
	}

	/* Search + Saved now live in the bottom bar, so drop them from the
	   masthead on mobile. The search form must stay in the DOM (the bar's
	   Search button ports it to <body> to open it) — hide only its collapsed
	   home state; when open it carries .is-open + inline styles and shows. */
	body.nd-tabbar-on .nd-root .nd-masthead__search:not(.is-open),
	body.nd-tabbar-on .nd-bookmarks-toggle { display: none; }

	/* The floating per-article save button clashed with the tab bar (both at
	   the bottom edge) — lift it clear above the bar. */
	body.nd-tabbar-on .nd-savebtn {
		bottom: calc(84px + env(safe-area-inset-bottom, 0px));
	}

	/* Saved list: a bottom sheet instead of the top-right dropdown — it opens
	   from the bottom bar, so it should rise from there. Sits just above the
	   bar (which stays tappable, so the Saved button toggles it closed). */
	.nd-bookmarks {
		top: auto;
		left: 0;
		right: 0;
		bottom: calc(76px + env(safe-area-inset-bottom, 0px));
		width: 100%;
		max-width: none;
		max-height: 60vh;
		border-radius: var(--nd-radius-lg) var(--nd-radius-lg) 0 0;
		border: 1px solid var(--nd-color-rule);
		box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.18);
		padding: 14px 14px calc(14px + env(safe-area-inset-bottom, 0px));
	}
}

/* Fullscreen mobile search: the panel must never pan sideways — an accidental
   horizontal swipe (a rail chaining at its edge, or a dead zone over wide
   content) was dragging the whole overlay. Inline in theme.js too (cache
   immunity); this is the stylesheet belt. */
html.nd-search-open .nd-instant { overflow-x: hidden; }
.nd-instant__grid { overscroll-behavior-x: contain; }

/* Swipe-progress indicator under News Slider rails (injected by theme.js
   initSliderProgress) — mobile only, same look as the search panel rails. */
.nd-slider__scroll { display: none; }
@media (max-width: 860px) {
	.nd-slider__scroll {
		display: block;
		position: relative;
		width: 96px;
		height: 3px;
		margin: var(--nd-space-3) auto 0;
		border-radius: 2px;
		background: var(--nd-color-paper-3);
		overflow: hidden;
	}
	.nd-slider__scroll i {
		position: absolute;
		top: 0;
		bottom: 0;
		left: 0;
		border-radius: 2px;
		background: var(--nd-color-subtle);
	}
}

/* Pinned breaking ticker (initBreakingPin in theme.js fixes it to the top at
   load; core geometry is inline for cache immunity — this only adds polish).
   The safe-area padding keeps the ticker text off the notch in landscape. */
.nd-breaking.is-pinned {
	box-shadow: var(--nd-shadow-md);
	padding-left: env(safe-area-inset-left);
	padding-right: env(safe-area-inset-right);
}
/* Everything that pins or anchors below the ticker reads its JS-published
   height (--nd-brkh on <html>; 0 when there is no breaking bar). The masthead
   rule needs the 2-class specificity (WP layout CSS gotcha). */
.nd-root .nd-masthead { top: var(--nd-brkh, 0px); }
.nd-root :where(h1, h2, h3, h4)[id] { scroll-margin-top: calc(var(--nd-brkh, 0px) + 12px); }

/* Featured-image caption under the article hero (appended by
   newsdesign_featured_caption — the core block ignores the attachment
   caption). Same look as .nd-prose figcaption; 2-class anchor so WP's
   late-printed layout CSS can't zero the margin (§ the usual gotcha). */
.nd-root .nd-herocap {
	margin-top: var(--nd-space-2);
	font-size: var(--nd-text-xs);
	color: var(--nd-color-subtle);
	line-height: 1.5;
}

/* Paragraph rhythm in articles/pages. The DS bundle's `.nd-prose p {margin:0}`
   (0,1,1) used to beat the sibling-rhythm owl (0,1,0) and zero the spacing
   between consecutive paragraphs; the bundle now resets via :where(), and this
   2-class anchor (0,2,0) also outranks WP's late-printed layout rules
   (`:root :where(.is-layout-flow) > *`) — the usual WP-container gotcha. */
.nd-root .nd-prose > * + * { margin-top: var(--nd-space-5); }

/* Tighten the header-chrome → content gap (was ~64px, now just the <main>
   padding). Three stacked sources: (1) wp-site-blocks block-gap pushed <main>
   24px down on every template; (2) on the front page the invisible
   screen-reader <h1> costs another block-gap before the first real section;
   (3) a hidden device-scoped block ("Mobile only"/"Desktop only") first in
   the content keeps the block-gap of the block that IS visible — the
   media-scoped rules zero the one that renders first on that device. */
.nd-root main.wp-block-group { margin-block-start: 0; }
.nd-root .entry-content > .screen-reader-text:first-child + * { margin-block-start: 0; }
@media (min-width: 782px) {
	.nd-root .entry-content > .screen-reader-text:first-child + .is-style-nd-mobile-only + *,
	.nd-root .entry-content > .screen-reader-text:first-child + .nd-only-mobile + *,
	.nd-root .entry-content > .screen-reader-text:first-child + .nd-hide-desktop + * { margin-block-start: 0; }
}
@media (max-width: 781px) {
	.nd-root .entry-content > .screen-reader-text:first-child + .is-style-nd-desktop-only + *,
	.nd-root .entry-content > .screen-reader-text:first-child + .nd-hide-mobile + * { margin-block-start: 0; }
}
@keyframes nd-lb-in {
	0% { background: var(--nd-color-accent-soft); }
	100% { background: transparent; }
}

/* Artist hub RSS pill (inc/feeds.php). */
.nd-artist__feed svg { vertical-align: -1px; margin-right: 4px; }

/* ----- Artist hub content filter (artist-header block) -------------------- */

.nd-root .nd-artist__filter {
	grid-column: 1 / -1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--nd-space-3);
	flex-wrap: wrap;
	margin-top: var(--nd-space-4);
	padding-top: var(--nd-space-3);
	border-top: 1px solid var(--nd-color-rule);
}
.nd-root .nd-artist__tabs { margin: 0; border: 0; padding: 0; }
.nd-artist__searchform { flex: 0 1 260px; min-width: 200px; }
.nd-artist__search {
	width: 100%;
	padding: 8px 14px;
	border: 1px solid var(--nd-color-rule-strong);
	border-radius: var(--nd-radius-pill);
	background: var(--nd-color-paper);
	color: var(--nd-color-ink);
	font-family: var(--nd-font-sans);
	font-size: 16px; /* not smaller — avoids iOS focus zoom */
}
.nd-artist__search:focus-visible {
	outline: 2px solid var(--nd-color-link);
	outline-offset: 1px;
}
@media (max-width: 600px) {
	.nd-artist__searchform { flex-basis: 100%; }
}

/* Search page: the "scoped to artist X" chip next to the type tabs. */
.nd-searchtabs__scope {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 10px;
	border: 1px dashed var(--nd-color-rule-strong);
	border-radius: var(--nd-radius-pill);
	font-family: var(--nd-font-sans);
	font-size: var(--nd-text-sm);
	color: var(--nd-color-muted);
}
.nd-searchtabs__scopeclear {
	color: var(--nd-color-ink);
	text-decoration: none;
	font-weight: 700;
	line-height: 1;
}
.nd-searchtabs__scopeclear:hover { color: var(--nd-color-accent); }

/* In-hub search: ONE clear control — our × inside the pill. The browser's
   native search-cancel is hidden so the two never double up, and the form
   itself stays pinned to the right of the filter row. */
.nd-artist__searchform { position: relative; }
.nd-artist__search { padding-right: 36px; }
.nd-artist__search::-webkit-search-cancel-button,
.nd-artist__search::-webkit-search-decoration {
	-webkit-appearance: none;
	appearance: none;
}
.nd-artist__clear {
	position: absolute;
	right: 6px;
	top: 50%;
	transform: translateY(-50%);
	border: 0;
	background: none;
	padding: 2px 10px;
	font-size: 20px;
	line-height: 1;
	color: var(--nd-color-muted);
	cursor: pointer;
	border-radius: var(--nd-radius-pill);
}
.nd-artist__clear:hover { color: var(--nd-color-accent); }
.nd-artist__clear:focus-visible {
	outline: 2px solid var(--nd-color-link);
	outline-offset: 1px;
}

/* Live in-hub filtering: soft fade while a request is in flight + the
   no-matches row. */
.nd-root .wp-block-post-template.is-nd-filtering { opacity: 0.55; transition: opacity 0.15s ease; }
.nd-artist__nomatch {
	list-style: none;
	font-family: var(--nd-font-sans);
	color: var(--nd-color-muted);
	padding: var(--nd-space-4) 0;
}

/* ===== iOS / Safari polish =============================================== */
/* Half the audience is on iOS. viewport-fit=cover is opted into from
   functions.php (newsdesign_ios_meta), which activates every
   env(safe-area-inset-*) below and the ones set earlier in this file. */

/* Stop Safari inflating text on rotation to landscape. */
html { -webkit-text-size-adjust: 100%; }

/* Landscape notch: keep in-flow content off the sensor housing / rounded
   corners. Portrait resolves to 0 — no visual change there. */
body.nd-root {
	padding-left: env(safe-area-inset-left, 0px);
	padding-right: env(safe-area-inset-right, 0px);
}

/* Fixed elements are viewport-relative, so each pads itself. These were the
   ones still missing their insets: */
.nd-root .nd-backtotop {
	right: calc(var(--nd-space-5) + env(safe-area-inset-right, 0px));
	bottom: calc(var(--nd-space-5) + env(safe-area-inset-bottom, 0px));
}
.nd-root .nd-savebtn {
	left: calc(var(--nd-space-5) + env(safe-area-inset-left, 0px));
	bottom: calc(var(--nd-space-5) + env(safe-area-inset-bottom, 0px));
}
.nd-root .nd-consent {
	padding-left: env(safe-area-inset-left, 0px);
	padding-right: env(safe-area-inset-right, 0px);
	padding-bottom: env(safe-area-inset-bottom, 0px);
}
@media (max-width: 860px) {
	.nd-root .nd-tabbar {
		padding-left: max(14px, env(safe-area-inset-left));
		padding-right: max(14px, env(safe-area-inset-right));
	}
}

/* Kill the double-tap-zoom hesitation on primary controls. Deliberately an
   enumerated :where() list (zero extra specificity), NOT a blanket a/button
   rule — the remix drag handles rely on touch-action: none. */
.nd-root :where(.nd-card__title-link, .nd-card__media, .nd-hero__title-link,
	.nd-hero__media, .nd-slide, .nd-storylist__title, .nd-searchtabs__tab,
	.nd-tabbar__link, .nd-button, .nd-iconbtn, .nd-tag, .nd-poll__opt,
	.nd-quiz__opt, .nd-react__btn, .nd-instant__card, .nd-artist__clear) {
	touch-action: manipulation;
}

/* Large image links flash a grey slab on tap — the hover/focus styles carry
   the affordance instead. */
.nd-root :where(.nd-card__media, .nd-hero__media, .nd-slide, .nd-instant__card) {
	-webkit-tap-highlight-color: transparent;
}

/* Scrollable panels must not chain-scroll the page behind them. */
.nd-root .nd-instant,
.nd-root .nd-bookmarks,
.nd-root .nd-events__dd,
.nd-root .nd-dd,
.nd-root .nd-consent {
	overscroll-behavior: contain;
}

/* iOS renders search/text inputs with its own rounding + inner shadow. */
.nd-root input[type="search"],
.nd-root input[type="text"],
.nd-root input[type="email"],
.nd-root input[type="url"] {
	-webkit-appearance: none;
	appearance: none;
}

/* The DS bundle's card-hover zoom is not hover-gated, so on touch a tap
   "sticks" the zoom until something else is tapped. Neutralize on touch. */
@media (hover: none) {
	.nd-root .nd-card__media:hover .nd-card__image { transform: scale(var(--nd-zoom, 1)); }
}

/* ===== Nav dropdown polish (desktop) ==================================== */
/* Refines the classic-menu dropdowns; scoped to ≥861px so the mobile
   accordion (the .is-open rules earlier) is untouched. Overrides the base
   .sub-menu look by source order at equal specificity. */
@media (min-width: 861px) {

	/* Top-level: an underline that wipes in from the left on hover, instead
	   of the flat 2px border only on the active item. */
	.nd-root .nd-sectionnav__list > .nd-sectionnav__item > .nd-sectionnav__link {
		position: relative;
		border-bottom: none;
		overflow: visible;
	}
	.nd-root .nd-sectionnav__list > .nd-sectionnav__item > .nd-sectionnav__link::before {
		content: "";
		position: absolute;
		left: var(--nd-space-3);
		right: var(--nd-space-3);
		bottom: 6px;
		height: 2px;
		background: var(--nd-color-accent);
		transform: scaleX(0);
		transform-origin: left center;
		transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
	}
	.nd-root .nd-sectionnav__list > .nd-sectionnav__item:hover > .nd-sectionnav__link::before,
	.nd-root .nd-sectionnav__list > .nd-sectionnav__item:focus-within > .nd-sectionnav__link::before,
	.nd-root .nd-sectionnav__list > .current-menu-item > .nd-sectionnav__link::before,
	.nd-root .nd-sectionnav__list > .current-menu-ancestor > .nd-sectionnav__link::before {
		transform: scaleX(1);
	}

	/* Caret: rotate down→up when the panel opens. */
	.nd-root .nd-sectionnav__item.menu-item-has-children > .nd-sectionnav__link::after {
		transition: transform 0.2s ease;
	}
	.nd-root .nd-sectionnav__list > .nd-sectionnav__item.menu-item-has-children:hover > .nd-sectionnav__link::after,
	.nd-root .nd-sectionnav__list > .nd-sectionnav__item.menu-item-has-children:focus-within > .nd-sectionnav__link::after {
		transform: translateY(1px) rotate(-135deg);
	}

	/* Panel: rounded, brand accent cap, layered soft shadow, springier entrance. */
	.nd-root .nd-sectionnav .sub-menu {
		min-width: 236px;
		padding: 8px;
		border: 1px solid var(--nd-color-rule);
		border-top: 2px solid var(--nd-color-accent);
		border-radius: 0 0 var(--nd-radius-lg) var(--nd-radius-lg);
		box-shadow:
			0 14px 34px -10px rgba(0, 0, 0, 0.20),
			0 4px 12px -4px rgba(0, 0, 0, 0.12);
		transform: translateY(8px) scale(0.98);
		transform-origin: top center;
		transition:
			opacity 0.18s ease,
			transform 0.2s cubic-bezier(0.22, 1, 0.36, 1),
			visibility 0.2s;
	}
	.nd-root .nd-sectionnav__item:hover > .sub-menu,
	.nd-root .nd-sectionnav__item:focus-within > .sub-menu {
		transform: none;
	}

	/* Invisible hover bridge over the gap between the top link and the panel,
	   so the pointer can travel down without the dropdown dismissing. */
	.nd-root .nd-sectionnav .sub-menu::before {
		content: "";
		position: absolute;
		top: -10px;
		left: 0;
		right: 0;
		height: 10px;
	}

	/* Items: readable Title-case (not tiny all-caps), roomy, with a growing
	   accent bar + a small shift on hover. */
	.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__link {
		position: relative;
		border-radius: var(--nd-radius-md);
		padding: 9px 14px 9px 18px;
		font-size: var(--nd-text-sm);
		font-weight: var(--nd-weight-semibold);
		letter-spacing: 0;
		text-transform: none;
		color: var(--nd-color-ink-soft);
		transition: color 0.14s ease, background 0.14s ease, transform 0.14s ease;
	}
	.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__link::before {
		content: "";
		position: absolute;
		left: 7px;
		top: 50%;
		width: 3px;
		height: 0;
		border-radius: 2px;
		background: var(--nd-color-accent);
		transform: translateY(-50%);
		transition: height 0.16s ease;
	}
	.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__link:hover,
	.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__link:focus-visible {
		background: var(--nd-color-paper-2);
		color: var(--nd-color-ink);
		transform: translateX(2px);
	}
	.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__link:hover::before,
	.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__link:focus-visible::before {
		height: 18px;
	}
	.nd-root .nd-sectionnav .sub-menu .current-menu-item > .nd-sectionnav__link {
		color: var(--nd-color-accent);
	}
	.nd-root .nd-sectionnav .sub-menu .current-menu-item > .nd-sectionnav__link::before {
		height: 18px;
	}

	/* Nested (3rd-level) flyout: accent moves to the leading edge, rounded all
	   corners, slides in from the left of its parent. */
	.nd-root .nd-sectionnav .sub-menu .sub-menu {
		top: -9px; /* align panel top with the parent item's padding box */
		border-top: 1px solid var(--nd-color-rule);
		border-left: 2px solid var(--nd-color-accent);
		border-radius: var(--nd-radius-lg);
		transform: translateX(8px) scale(0.98);
		transform-origin: left top;
	}
	.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__item:hover > .sub-menu,
	.nd-root .nd-sectionnav .sub-menu .nd-sectionnav__item:focus-within > .sub-menu {
		transform: none;
	}
	/* Bridge for the side flyout sits on the left edge, not the top. */
	.nd-root .nd-sectionnav .sub-menu .sub-menu::before {
		top: 0;
		bottom: 0;
		left: -10px;
		right: auto;
		width: 10px;
		height: auto;
	}
	/* Parent-of-flyout caret (points right): nudge to accent on hover. */
	.nd-root .nd-sectionnav .sub-menu .menu-item-has-children:hover > .nd-sectionnav__link::after,
	.nd-root .nd-sectionnav .sub-menu .menu-item-has-children:focus-within > .nd-sectionnav__link::after {
		transform: rotate(-45deg) translate(1px, -1px);
	}

	@media (prefers-reduced-motion: reduce) {
		.nd-root .nd-sectionnav .sub-menu,
		.nd-root .nd-sectionnav .sub-menu .sub-menu {
			transition: opacity 0.15s ease, visibility 0.15s;
			transform: none;
		}
		.nd-root .nd-sectionnav__list > .nd-sectionnav__item > .nd-sectionnav__link::before { transition: none; }
	}
}


/* ======================================================================== *
 * Follow artist + "From your artists"
 * The follow list lives in the browser, so the button always ships in the
 * "Follow" state and theme.js paints the truth on load. Both label states
 * are in the markup — the swap is a class change, never a re-render.
 * ======================================================================== */
.nd-follow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--nd-font-sans);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-radius: 999px;
  border: 1px solid var(--nd-color-ink);
  background: var(--nd-color-ink);
  color: var(--nd-color-paper);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.nd-follow--lg { font-size: var(--nd-text-sm); padding: 9px 18px; }
.nd-follow--sm { font-size: var(--nd-text-xs); padding: 6px 13px; }
.nd-follow__ico { flex: none; }
.nd-follow__ico--on { display: none; }

/* Following: quiet outline — the action is done, it shouldn't keep shouting. */
.nd-follow.is-following {
  background: transparent;
  color: var(--nd-color-ink);
  border-color: var(--nd-color-rule-strong);
}
.nd-follow.is-following .nd-follow__ico--add { display: none; }
.nd-follow.is-following .nd-follow__ico--on { display: inline-block; }
.nd-follow.is-following .nd-follow__ico--on { color: var(--nd-color-accent); }

/* Hover is decoration only — every state is readable without it (iOS). */
@media (hover: hover) {
  .nd-follow:hover { background: var(--nd-color-accent); border-color: var(--nd-color-accent); color: var(--nd-color-accent-ink); }
  .nd-follow.is-following:hover { background: transparent; color: var(--nd-color-accent); border-color: var(--nd-color-accent); }
}

/* Follow sits in the same row as the social links, not stacked on top of them.
   The row's gap (0.75rem) is deliberately wider than the gap between the
   social pills themselves (0.5rem), so the eye reads two groups rather than
   five equal buttons. The bio already carries the space above. */
.nd-artist__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--nd-space-3);
  margin-top: var(--nd-space-1);
}
/* Match the social pills exactly, whatever size class the button carries —
   two pill heights that differ by a couple of pixels look like a mistake. */
.nd-root .nd-artist__actions .nd-follow {
  margin-top: 0;
  padding: 7px 14px;
  font-size: var(--nd-text-xs);
  line-height: 1;
  /* Room for the longer of the two labels, so pressing Follow doesn't shove
     the social pills sideways. A floor, not a cap — a longer translation
     simply widens the button. */
  min-width: 10.8em;
  justify-content: center;
}
/* The icon, not the text, was setting the button's height — 13px of SVG next
   to a 12px line box made Follow one pixel taller than every pill beside it. */
.nd-artist__actions .nd-follow__ico { width: 12px; height: 12px; display: block; }

@media (max-width: 700px) {
  .nd-artist__actions { justify-content: center; }
}
.nd-artistcard__actions {
  display: flex;
  align-items: center;
  gap: var(--nd-space-3);
  flex-wrap: wrap;
  margin-top: var(--nd-space-2);
}
.nd-root .nd-artistcard__actions .nd-artistcard__more { margin: 0; }

.nd-root .nd-fromartists { margin-top: var(--nd-space-6); }

@media (prefers-reduced-motion: reduce) {
  .nd-follow { transition: none; }
}


/* ======================================================================== *
 * Ad slots (newsdesign/ad-slot)
 * The height is reserved from the server render (--nd-ad-h / --nd-ad-hm), so
 * the slot occupies its space before anything loads and the article never
 * jumps when the ad arrives. That reservation IS the feature.
 * ======================================================================== */
.nd-root .nd-ad {
  margin: var(--nd-space-5) auto;
  text-align: center;
  max-width: 100%;
}
.nd-ad__label {
  display: block;
  font-family: var(--nd-font-sans);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--nd-color-subtle);
  margin-bottom: 4px;
}
.nd-ad__box {
  min-height: var(--nd-ad-hm, 250px);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.nd-ad__box > * { max-width: 100%; }

@media (min-width: 782px) {
  .nd-ad__box { min-height: var(--nd-ad-h, 90px); }
}

/* Editor placeholder — never a live ad in wp-admin. */
.nd-ad--placeholder .nd-ad__box {
  border: 1px dashed var(--nd-color-rule-strong);
  border-radius: var(--nd-radius-sm);
  background: var(--nd-color-paper-2);
  color: var(--nd-color-subtle);
  font-family: var(--nd-font-sans);
  font-size: var(--nd-text-xs);
  letter-spacing: 0.04em;
}


/* ======================================================================== *
 * Series navigation (newsdesign/series-nav)
 * A quiet strip: where you are in the series, the other parts on demand,
 * and the two steps either side. Never competes with the headline.
 * ======================================================================== */
.nd-root .nd-series {
  margin: var(--nd-space-5) 0;
  padding: var(--nd-space-4);
  background: var(--nd-color-paper-2);
  border-radius: var(--nd-radius-md);
}
.nd-series__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--nd-space-2);
}
.nd-series__name {
  font-family: var(--nd-font-display);
  font-size: var(--nd-text-lg);
  line-height: 1.15;
  color: var(--nd-color-ink);
  text-decoration: none;
}
.nd-series__name:hover { color: var(--nd-color-accent); }
.nd-series__pos {
  font-size: var(--nd-text-sm);
  color: var(--nd-color-subtle);
  margin-left: auto;
  white-space: nowrap;
}

.nd-series__all { margin-top: var(--nd-space-3); }
.nd-series__all > summary {
  cursor: pointer;
  font-size: var(--nd-text-sm);
  font-weight: 600;
  color: var(--nd-color-muted);
  list-style: none;
}
.nd-series__all > summary::-webkit-details-marker { display: none; }
.nd-series__all > summary::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
}
.nd-series__all[open] > summary::after { transform: rotate(-135deg) translateY(-1px); }
.nd-root .nd-series__parts {
  margin: var(--nd-space-2) 0 0;
  padding-left: 1.4em;
  font-size: var(--nd-text-sm);
}
.nd-root .nd-series__part { margin: 4px 0; }
.nd-series__part a { color: var(--nd-color-ink); text-decoration: none; }
.nd-series__part a:hover { color: var(--nd-color-accent); }
.nd-series__part.is-current { color: var(--nd-color-subtle); font-weight: 700; }

.nd-series__nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--nd-space-3);
  margin-top: var(--nd-space-3);
  padding-top: var(--nd-space-3);
  border-top: 1px solid var(--nd-color-rule);
}
.nd-series__step { text-decoration: none; min-width: 0; }
/* A lone "next" link must sit on the right, where the reader looks for it. */
.nd-series__step--next:only-child { grid-column: 2; }
.nd-series__step--next { text-align: right; }
.nd-series__steplabel {
  display: block;
  font-size: var(--nd-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--nd-color-subtle);
}
.nd-series__steptitle {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-weight: 700;
  font-size: var(--nd-text-sm);
  line-height: 1.3;
  color: var(--nd-color-ink);
}
.nd-series__step:hover .nd-series__steptitle { color: var(--nd-color-accent); }

@media (max-width: 600px) {
  .nd-series__nav { grid-template-columns: 1fr; }
  .nd-series__step--next, .nd-series__step--next:only-child { text-align: left; grid-column: 1; }
  .nd-series__pos { margin-left: 0; width: 100%; }
}

/* ----- Single release page ---------------------------------------------- */
.nd-relsingle { margin-top: var(--nd-space-5); }
.nd-root .nd-relsingle__facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nd-space-4);
  margin: 0 0 var(--nd-space-4);
  padding: var(--nd-space-3) var(--nd-space-4);
  background: var(--nd-color-paper-2);
  border-radius: var(--nd-radius-md);
}
.nd-root .nd-relsingle__facts dt {
  font-size: var(--nd-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--nd-color-subtle);
  margin: 0;
}
.nd-root .nd-relsingle__facts dd {
  margin: 2px 0 0;
  font-weight: 700;
  font-size: var(--nd-text-sm);
}
.nd-relsingle__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nd-space-2);
  margin-bottom: var(--nd-space-4);
}
.nd-relsingle__link {
  display: inline-block;
  padding: 9px 16px;
  border: 1px solid var(--nd-color-rule-strong);
  border-radius: 999px;
  font-size: var(--nd-text-sm);
  font-weight: 700;
  text-decoration: none;
  color: var(--nd-color-ink);
}
.nd-relsingle__link:hover { border-color: var(--nd-color-accent); color: var(--nd-color-accent); }
.nd-root .nd-relsingle__review { margin: 0 0 var(--nd-space-4); font-weight: 700; }
.nd-root .nd-relsingle__head {
  font-family: var(--nd-font-display);
  font-size: var(--nd-text-lg);
  margin: 0 0 var(--nd-space-2);
}
.nd-root .nd-relsingle__tracks {
  margin: 0;
  padding-left: 1.4em;
  columns: 2;
  column-gap: var(--nd-space-6);
  font-size: var(--nd-text-sm);
}
.nd-root .nd-relsingle__tracks li { margin: 3px 0; break-inside: avoid; }

@media (max-width: 600px) {
  .nd-root .nd-relsingle__tracks { columns: 1; }
}
