/* =========================================================================
   Sims Archives Dream Theme — Canonical Design System 70.3
   =========================================================================
   This is the single shared visual contract for every public template. It is
   enqueued once from inc/enqueue.php, after route-specific bundles. New pages
   must reuse these primitives instead of copying card, panel, heading, grid,
   button, tab or spacing rules into another stylesheet.

   Specificity contract
   --------------------
   Shared rules are prefixed with `body.sat-site` so they beat the historical
   theme bundle predictably without !important. Route bundles may add unique
   layout details, but common component geometry belongs here.

   1. Tokens and spacing
   2. Page shell
   3. Section headers and rhythm
   4. Grids and cards
   5. Surfaces, buttons, tabs, chips
   6. Type ramp
   7. Responsive matrix
   8. Performance
   9. Accessibility floors
   10. Content inset / edge-safety contract
   ========================================================================= */


/* ---------------------------------------------------------------- 1. Tokens */

:root {
  /* 70.2 compatibility aliases. The cleaned legacy bundle already uses
     these semantic tokens; define them once so older templates inherit the
     unified palette without invalid var() declarations. */
  --sa-blue-deep-rgb: 7, 13, 51;
  --sat-ink: var(--sat-text, #f7fbff);
  --sat-ink-soft: #dff4ff;
  --sat-ink-muted: var(--sat-muted, #b8c7d7);
  --sat-ink-rgb: 247, 251, 255;
  --sat-shadow-rgb: 0, 0, 0;
  --sat-text-muted: var(--sat-muted, #b8c7d7);
  --sat-surface-raised: rgba(var(--sa-blue-night-rgb), .84);
  --sat-accent-deep: var(--sa-blue-royal);
  --sat-radius-card: 24px;
  --sat-space-1: .25rem;
  --sat-space-2: .5rem;
  --sat-space-3: .75rem;
  --sat-space-4: 1rem;
  --sat-space-5: 1.5rem;
  --sat-space-6: 2rem;

  /* One horizontal inset contract for text-bearing surfaces. Media may stay
     flush to card edges, but copy never does. */
  --sat-surface-pad: clamp(1rem, 1.8vw, 1.45rem);
  --sat-card-pad: clamp(.9rem, 1.35vw, 1.12rem);
  --sat-dialog-pad: clamp(1rem, 2vw, 1.5rem);

  /* One gutter for the whole site. Every full-width block reads this instead
     of hard-coding 1rem / .75rem / clamp() per template. */
  --sat-gutter: clamp(1rem, 3.4vw, 2.75rem);

  /* The wide measure used by hubs (games archive, homepage rooms) and the
     narrow measure used by article/detail pages. */
  --sat-measure-wide: 1440px;
  --sat-measure: 1220px;

  /* Card sizing. Grids are auto-fill, so these mins define the column count at
     every width — one number per card family instead of a breakpoint ladder. */
  --sat-card-min: 268px;
  --sat-card-min-wide: 340px;
  --sat-card-min-tight: 168px;
  --sat-card-media-ratio: 16 / 9;

  /* Elevation, expressed once. Mobile drops to the flat step in section 7. */
  --sat-elev-1: 0 1px 0 rgba(var(--sat-ink-rgb), .05) inset,
                0 10px 28px rgba(var(--sat-shadow-rgb), .22);
  --sat-elev-2: 0 1px 0 rgba(var(--sat-ink-rgb), .06) inset,
                0 22px 60px rgba(var(--sat-shadow-rgb), .30);

  /* Surface recipe shared by cards and panels: a vertical gradient over blue
     night, so a card reads as glass on the page background instead of a flat
     patch of a slightly different blue. */
  --sat-surface: linear-gradient(180deg,
    rgba(var(--sa-blue-night-rgb), .92) 0%,
    rgba(var(--sa-blue-abyss-rgb), .88) 100%);
  --sat-surface-hover: linear-gradient(180deg,
    rgba(var(--sa-blue-night-rgb), .98) 0%,
    rgba(var(--sa-blue-abyss-rgb), .92) 100%);

  --sat-hairline: rgba(var(--sat-ink-rgb), .10);
  --sat-hairline-strong: rgba(var(--sa-lime-rgb), .34);

  /* Sticky offsets. The header measures itself into --sat-header-height; this
     is the fallback plus the scroll-margin every anchor target uses. */
  --sat-header-h: var(--sat-header-height, 76px);
  --sat-anchor-offset: calc(var(--sat-header-h) + 1rem);
}


/* ------------------------------------------------- 2. Page shell */

/* One measure and one gutter. The game page and other full-bleed templates opt
   out with max-width:none in theme.css, which this respects by only setting the
   inline padding here — width stays where each template put it. */
body.sat-site .sat-main {
  padding-inline: var(--sat-gutter);
  padding-block-end: clamp(3rem, 7vw, 6rem);
}

/* Wide hub blocks (homepage rooms, games archive) align to the same gutter as
   the narrow templates, so scrolling from one page to the next does not shift
   the left edge of the content. */
body.sat-site :where(.sat-grand-section, .sat-home-section, .sat-games-browse-shell, .sat-hub-nav) {
  width: min(100%, var(--sat-measure-wide));
  margin-inline: auto;
  padding-inline: 0;
}

body.sat-site .sat-main.sat-game-page > :where(section, nav, div) {
  min-width: 0;
}

/* Long single words (game codenames, file names) must never widen a grid. */
body.sat-site :where(h1, h2, h3, h4, .sat-card-title, .sat-games-browse-title) {
  overflow-wrap: anywhere;
  text-wrap: pretty;
}

/* Anchor targets clear the sticky header. */
body.sat-site :where([id]) {
  scroll-margin-block-start: var(--sat-anchor-offset);
}


/* --------------------------------------- 3. Section headers & rhythm */

/* Every page introduces its blocks the same way: lime kicker, display title,
   one muted line, optional link on the right. */
body.sat-site :where(.sat-section-head, .sat-grand-section-head, .sat-home-section-head) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--sat-space-3) var(--sat-space-4);
  margin-block: 0 var(--sat-space-3);
  padding-block-end: var(--sat-space-2);
  border-block-end: 1px solid var(--sat-hairline);
}

body.sat-site :where(.sat-section-head, .sat-grand-section-head, .sat-home-section-head) > :where(p) {
  grid-column: 1;
  max-width: 62ch;
  margin: .35rem 0 0;
  color: var(--sat-muted);
}

body.sat-site :where(.sat-eyebrow, .sat-card-kicker, .sat-grand-section-kicker) {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  color: var(--sat-lime);
  font-size: .74rem;
  font-weight: 900;
  letter-spacing: .16em;
  text-transform: uppercase;
}

body.sat-site :where(.sat-grand-section-link, .sat-section-head a:last-child) {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  white-space: nowrap;
}

body.sat-site .sat-section-head-copy {
  min-width: 0;
}

body.sat-site .sat-section-head-copy > :first-child {
  margin-block-start: 0;
}

body.sat-site .sat-section-head-copy > :last-child {
  margin-block-end: 0;
}

body.sat-site .sat-section-description {
  max-width: 62ch;
  margin: .35rem 0 0;
  color: var(--sat-muted);
}

body.sat-site .sat-section-action {
  grid-column: 2;
  grid-row: 1;
  align-self: center;
}


/* ------------------------------------------- 4. One card grid, one card */

/* Auto-fill everywhere. This replaces ~30 breakpoint ladders: the column count
   now follows the available width, which is what makes tablet portrait,
   tablet landscape and split-screen behave without new media queries. */
body.sat-site :where(
  .sat-card-grid,
  .sat-post-grid,
  .sat-grid,
  .sat-home-article-grid,
  .sat-home-download-grid,
  .sat-games-modern-grid,
  .sat-article-wall,
  .sat-download-grid,
  .sat-credit-grid,
  .sat-character-grid,
  .sat-world-grid
) {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(var(--sat-card-min), 100%), 1fr));
  gap: var(--sat-space-3);
  align-items: stretch;
}

body.sat-site :where(.sat-game-media-grid, .sat-media-mini-grid, .sat-gallery-grid) {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(var(--sat-card-min-tight), 100%), 1fr));
  gap: var(--sat-space-2);
}

/* Grid children may not overflow their track. */
body.sat-site :where(.sat-card-grid, .sat-post-grid, .sat-grid, .sat-games-modern-grid) > * {
  min-width: 0;
  height: 100%;
}

/* One card. Same surface, same radius, same hairline, same hover — whichever
   template emitted it. */
body.sat-site :where(.sat-card, .sat-games-browse-card, .sat-article-card, .sat-download-card, .sat-credit-card) {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--sat-hairline);
  border-radius: var(--sat-radius-card);
  background: var(--sat-surface);
  box-shadow: var(--sat-elev-1);
  transition: transform .28s ease, box-shadow .28s ease, border-color .28s ease, background .28s ease;
}

/* Media boxes reserve their space before the image arrives: no layout shift,
   and every card in a row is the same height. */
body.sat-site :where(.sat-card-media, .sat-article-card-media, .sat-download-card-media, .sat-games-browse-cover) {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: var(--sat-card-media-ratio);
  background: rgba(var(--sa-blue-abyss-rgb), .55);
}

body.sat-site :where(.sat-card-media, .sat-article-card-media, .sat-download-card-media, .sat-games-browse-cover) > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Game and character covers are portrait; state it once. */
body.sat-site :where(.sat-games-browse-cover, .sat-card--cover .sat-card-media) {
  aspect-ratio: 3 / 4;
}

body.sat-site :where(.sat-card-body, .sat-article-card-body, .sat-games-browse-card-copy) {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: .5rem;
  padding: var(--sat-card-pad);
}

/* Hover is a pointer affordance, not a mobile one: no sticky :hover states on
   touch, and no repaint cost where it cannot be triggered. */
@media (hover: hover) and (pointer: fine) {
  body.sat-site :where(.sat-card, .sat-games-browse-card, .sat-article-card, .sat-download-card):hover {
    transform: translateY(-3px);
    border-color: var(--sat-hairline-strong);
    background: var(--sat-surface-hover);
    box-shadow: var(--sat-elev-2);
  }
}


/* ------------------------------------- 5. Surfaces, buttons, tabs, chips */

body.sat-site :where(.sat-panel, .sat-fact-card) {
  background: var(--sat-surface);
  box-shadow: var(--sat-elev-1);
}

/* Primary action: lime on ink, the one high-contrast element per block. */
body.sat-site :where(.sat-button) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 44px;
  padding: .68rem 1.25rem;
  border: 1px solid var(--sat-hairline);
  background: rgba(var(--sat-ink-rgb), .07);
  color: var(--sat-ink);
  text-decoration: none;
  transition: background .22s ease, border-color .22s ease, color .22s ease, transform .22s ease;
}

body.sat-site :where(.sat-button--primary, .sat-button.is-primary, .sat-button--buy) {
  border-color: transparent;
  background: linear-gradient(180deg, var(--sa-lime-bright), var(--sa-lime));
  color: var(--sa-lime-ink);
  font-weight: 900;
}

@media (hover: hover) and (pointer: fine) {
  body.sat-site .sat-button:hover {
    border-color: var(--sat-hairline-strong);
    background: rgba(var(--sa-lime-rgb), .14);
    color: var(--sat-ink);
  }
  body.sat-site :where(.sat-button--primary, .sat-button.is-primary, .sat-button--buy):hover {
    background: linear-gradient(180deg, #CDF95C, var(--sa-lime-bright));
    color: var(--sa-lime-ink);
  }
}

/* Tab rails scroll instead of wrapping into an unreadable stack, on every page
   that has tabs (game page, galleries, downloads, articles, SIMusics). */
body.sat-site :where(.sat-tabs, .sat-game-media-tabs, .sat-hub-nav-list, .sat-type-tabs) {
  display: flex;
  gap: .5rem;
  overflow-x: auto;
  padding: .45rem;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}

body.sat-site :where(.sat-tabs, .sat-game-media-tabs, .sat-hub-nav-list, .sat-type-tabs)::-webkit-scrollbar {
  display: none;
}

body.sat-site :where(.sat-tab, .sat-game-media-tab) {
  flex: 0 0 auto;
  scroll-snap-align: start;
  border: 1px solid transparent;
}

body.sat-site :where(.sat-tab.is-active, .sat-game-media-tab.is-active, .sat-tab[aria-selected="true"]) {
  border-color: var(--sat-hairline-strong);
  background: rgba(var(--sa-lime-rgb), .16);
  color: var(--sat-ink);
}

body.sat-site :where(.sat-chip-list) {
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
}

/* Mobile-only controls start hidden in the shared stylesheet. Responsive route
   rules reveal them; templates never carry repeated inline display styles. */
body.sat-site :where(.sat-mobile-filter-open, .sat-game-mobile-tabs-wrap) {
  display: none;
}


/* ---------------------------------------------- 6. Hero & heading ramp */

/* One ramp for every hero title, so /games/, a game page, a gallery and the
   homepage all open at the same visual weight. */
body.sat-site :where(
  .sat-game-hero h1,
  .sat-archive-hero h1,
  .sat-single-header h1,
  .sat-detail-copy h1,
  .sat-cine-hero h1,
  .sat-site-hero h1
) {
  font-size: clamp(2.1rem, 5.2vw, 4.15rem);
  line-height: .94;
  letter-spacing: -.045em;
}

body.sat-site :where(.sat-grand-section-head h2, .sat-section-head h2, .sat-home-section-head h2) {
  font-size: clamp(1.6rem, 3.4vw, 2.9rem);
  line-height: 1;
  letter-spacing: -.04em;
}

body.sat-site :where(.sat-game-summary, .sat-archive-hero p, .sat-detail-copy > p) {
  max-width: 58ch;
  color: var(--sat-ink-soft);
}

/* Hero fact rows and stat chips: one pill, one measure. */
body.sat-site :where(.sat-hero-facts, .sat-hero-actions) {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  align-items: center;
}


/* -------------------------------------------- 7. Responsive matrix */

/* Tablet portrait — 1 to 2 columns, wider gutter than a phone, and the
   two-column detail layouts collapse. */
@media (min-width: 768px) and (max-width: 1023px) {
  :root {
    --sat-card-min: 240px;
    --sat-card-min-tight: 150px;
  }
  body.sat-site :where(.sat-two-col, .sat-games-browse-layout) {
    grid-template-columns: 1fr;
  }
  body.sat-site :where(.sat-games-browse-sidebar) {
    position: static;
  }
}

/* Tablet landscape / small laptop — three comfortable columns. */
@media (min-width: 1024px) and (max-width: 1279px) {
  :root { --sat-card-min: 262px; }
  body.sat-site :where(.sat-games-browse-layout) {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Phone portrait. Flat elevation, no blur, one column of real cards. */
@media (max-width: 767px) {
  :root {
    --sat-gutter: .9rem;
    --sat-card-min: 100%;
    --sat-card-min-tight: 46%;
    --sat-elev-1: 0 6px 18px rgba(var(--sat-shadow-rgb), .20);
    --sat-elev-2: 0 8px 22px rgba(var(--sat-shadow-rgb), .24);
  }
  /* backdrop-filter is the single most expensive thing on a phone GPU and it
     is invisible at this size. */
  body.sat-site :where(.sat-site-header, .sat-tabs, .sat-panel, .sat-breadcrumb-shell, .sat-pocket-bar) {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  body.sat-site :where(.sat-section-head, .sat-grand-section-head, .sat-home-section-head) {
    grid-template-columns: minmax(0, 1fr);
  }
  body.sat-site :where(.sat-grand-section-link, .sat-section-head a:last-child),
  body.sat-site .sat-section-action {
    grid-column: 1;
    grid-row: auto;
  }
  body.sat-site :where(.sat-two-col, .sat-three-col, .sat-games-browse-layout) {
    grid-template-columns: 1fr;
  }
  /* Safe area on notched phones. */
  body.sat-site .sat-main {
    padding-inline: max(var(--sat-gutter), env(safe-area-inset-left));
  }
}

/* Phone LANDSCAPE — the case the alpha never covered. A 360px-tall viewport
   cannot afford a 70vh hero, a sticky header and a sticky tab rail at once.
   Keyed on height, so it also fixes small windows and split screen. */
@media (orientation: landscape) and (max-height: 560px) {
  :root {
    --sat-gutter: 1rem;
    --sat-card-min: 220px;
    --sat-card-min-tight: 140px;
  }

  /* Heroes become banners: capped height, no min-height fights, smaller type. */
  body.sat-site :where(.sat-game-hero, .sat-archive-hero, .sat-cine-hero, .sat-site-hero, .sat-detail-hero) {
    min-height: 0;
    max-height: none;
    padding-block: 1.4rem 1.8rem;
  }
  body.sat-site :where(
    .sat-game-hero h1, .sat-archive-hero h1, .sat-cine-hero h1,
    .sat-single-header h1, .sat-detail-copy h1, .sat-site-hero h1
  ) {
    font-size: clamp(1.5rem, 4.4vh, 2.2rem);
    line-height: 1;
  }
  body.sat-site :where(.sat-game-hero-visual, .sat-cine-hero-visual, .sat-archive-hero-visual) {
    max-height: 62svh;
  }
  body.sat-site :where(.sat-game-cover--hero) {
    max-width: 160px;
    min-height: 0;
  }
  body.sat-site :where(.sat-game-summary, .sat-archive-hero p) {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* Only one thing may be sticky at a time on a short viewport. */
  body.sat-site .sat-site-header {
    position: relative;
    padding-block: .5rem;
  }
  body.sat-site .sat-tabs,
  body.sat-site.single-sims_game .sat-tabs {
    position: relative;
    margin-block: .6rem;
  }
  body.sat-site :where(.sat-games-browse-sidebar, .sat-store-filters) {
    position: static;
  }

  /* Mobile v2 chrome: the pocket bar eats a third of a landscape screen. */
  body.sat-site .sat-pocket-bar {
    display: none;
  }

  /* Menus, dialogs and the lightbox scroll inside the viewport instead of
     being clipped by it. */
  body.sat-site :where(.sat-primary-nav, .sat-mobile-nav, .sat-games-filter-dialog-form, dialog) {
    max-height: calc(100svh - 1rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  /* Landscape is the good orientation for the gallery viewer: keep the image
     and its details side by side. */
  body.sat-site :where(.sat-lightbox-layout, .sa-lightbox-layout) {
    grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
  }
  body.sat-site :where(.sa-simusics-floating, .sat-floating-mini-player) {
    max-width: min(420px, 60vw);
    padding-block: .4rem;
  }
}

/* Very small landscape (older phones, 320px tall): drop decoration entirely. */
@media (orientation: landscape) and (max-height: 430px) {
  body.sat-site :where(.sat-game-cover--hero, .sat-hero-orbit, .sat-game-logo) {
    display: none;
  }
  body.sat-site :where(.sat-game-hero, .sat-archive-hero, .sat-cine-hero) {
    padding-block: 1rem 1.2rem;
  }
}


/* ------------------------------------------------- 8. Performance */

/* Paint budget: below-the-fold blocks are skipped until they approach the
   viewport, on every device — the alpha only did this under 767px. The
   intrinsic sizes keep the scrollbar honest. */
@supports (content-visibility: auto) {
  body.sat-site :where(.sat-main > section:nth-of-type(n+3), .sat-grand-section:nth-of-type(n+3)) {
    content-visibility: auto;
    contain-intrinsic-size: auto 640px;
  }
  body.sat-site :where(
    .sat-card-grid > *:nth-child(n+9),
    .sat-games-modern-grid > *:nth-child(n+9),
    .sat-article-wall > *:nth-child(n+9),
    .sat-game-media-grid > *:nth-child(n+13)
  ) {
    content-visibility: auto;
    contain-intrinsic-size: auto 340px;
  }
  body.sat-site .sat-site-footer {
    content-visibility: auto;
    contain-intrinsic-size: auto 520px;
  }
}

/* Isolate card and panel repaints from the rest of the page. */
body.sat-site :where(.sat-card, .sat-article-card, .sat-games-browse-card, .sat-panel) {
  contain: layout paint style;
}

/* No image may shift the layout. */
body.sat-site :where(img, video, iframe) {
  max-width: 100%;
}

body.sat-site :where(iframe) {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
  border: 0;
}


/* --------------------------------------------- 9. Accessibility floors */

/* The skip link existed but was parked off-screen with no focus state, so it
   was unreachable. This is the only !important pair in the layer: it has to
   beat .sat-skip-link{position:absolute;left:-9999px}. */
body.sat-site .sat-skip-link:focus,
body.sat-site .sat-skip-link:focus-visible {
  position: fixed !important;
  left: 1rem !important;
  top: 1rem;
  z-index: 999;
  padding: .75rem 1.15rem;
  border-radius: 999px;
  background: var(--sa-lime);
  color: var(--sa-lime-ink);
  font-weight: 900;
}

/* Muted text is the site's most common contrast failure at small sizes. */
@media (max-width: 767px) {
  :root { --sat-ink-muted: #C2D0EE; }
}

/* Every interactive target reaches 44px on touch, including the ones the
   design-system layer did not enumerate. */
@media (pointer: coarse) {
  body.sat-site :where(
    .sat-button, .sat-tab, .sat-game-media-tab, .sat-menu a,
    .sat-chip-list a, .page-numbers, .sat-icon-button, .sat-pagination a
  ) {
    min-height: 44px;
    min-width: 44px;
  }
}

/* Respect the user's reduced-motion choice for the hover lift too. */
@media (prefers-reduced-motion: reduce) {
  body.sat-site :where(.sat-card, .sat-games-browse-card, .sat-article-card):hover {
    transform: none;
  }
}


/* ------------------------------------------------ 10. Content inset contract
   Borders are never allowed to touch text. Media remains edge-to-edge, while
   every text-bearing card, panel, dialog and info surface gets one shared
   horizontal inset. This is intentionally last so old template patches cannot
   accidentally collapse the breathing room. */
body.sat-site :where(
  .sat-panel.is-static,
  .sat-fact-card,
  .sat-empty,
  .sat-notice,
  .sat-download-panel,
  .sat-character-story-card,
  .sat-character-identity-card,
  .sat-character-appearances-section,
  .sat-character-media-section,
  .sat-credit-story-card,
  .sat-credit-identity-card,
  .sat-article-side-panel,
  .sat-article-filter-note,
  .sat-games-filter-panel,
  .sat-games-filter-dialog-head,
  .sat-games-filter-dialog-foot,
  .sat-mobile-filter-dialog-body,
  .sat-manual-language-edition,
  .sat-sysreq-platform-card,
  .sat-sysreq-tier-card,
  .sat-sysreq-console-card
) {
  padding-inline: var(--sat-surface-pad);
}

body.sat-site :where(
  .sat-games-filter-dialog-form,
  .sat-mobile-filter-dialog,
  .sat-buy-modal-card,
  .sat-character-lightbox-dialog,
  .sat-download-lightbox-dialog,
  .sat-gv3-lightbox-dialog
) {
  --sat-local-dialog-pad: var(--sat-dialog-pad);
}

body.sat-site :where(
  .sat-card-body,
  .sat-article-card-body,
  .sat-download-card-body,
  .sat-games-browse-card-copy,
  .sat-magazine-card-copy,
  .sat-wallpaper-card-copy,
  .sat-game-credit-card-copy,
  .sat-character-appearance-copy,
  .sat-store-copy,
  .sat-store-article-copy,
  .sat-store-download-copy,
  .sat-store-game-copy,
  .sat-store-music-copy
) {
  min-width: 0;
  padding-inline: var(--sat-card-pad);
}

/* Text blocks own their vertical rhythm; the surface owns the inset. */
body.sat-site :where(
  .sat-rich-text,
  .sat-card-body,
  .sat-article-card-body,
  .sat-download-card-body,
  .sat-games-browse-card-copy,
  .sat-character-story-card,
  .sat-credit-story-card,
  .sat-article-side-panel,
  .sat-empty
) > :first-child {
  margin-block-start: 0;
}

body.sat-site :where(
  .sat-rich-text,
  .sat-card-body,
  .sat-article-card-body,
  .sat-download-card-body,
  .sat-games-browse-card-copy,
  .sat-character-story-card,
  .sat-credit-story-card,
  .sat-article-side-panel,
  .sat-empty
) > :last-child {
  margin-block-end: 0;
}

/* Long titles, URLs and archive metadata can wrap; they must never push copy
   through a border or widen a grid track. */
body.sat-site :where(
  p, li, dd, dt, figcaption,
  .sat-rich-text,
  .sat-card-body,
  .sat-article-card-body,
  .sat-download-card-body,
  .sat-games-browse-card-copy,
  .sat-section-head-copy
) {
  min-width: 0;
  overflow-wrap: anywhere;
}

@media (max-width: 767px) {
  :root {
    --sat-surface-pad: .95rem;
    --sat-card-pad: .85rem;
    --sat-dialog-pad: .95rem;
  }
}
