/*
 * vanguard.css
 *
 * Sitewide surface-elevation layer. This file deliberately loads after the
 * foundation styles so removing its single <link> restores the previous UI.
 */

/* Font metric fallbacks keep the Google Fonts swap from moving the page. */
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Fraunces Fallback";
  src: local("Georgia");
  size-adjust: 95%;
  ascent-override: 96%;
  descent-override: 24%;
  line-gap-override: 0%;
}

:root,
body.editorial {
  --accent: #0d5ec8;
  --accent-bright: #2d84f8;
  --accent-wash: color-mix(in oklab, var(--accent) 5%, #fff);
  --surface-tray: color-mix(in oklab, var(--accent) 9%, #fff);
  --hairline: color-mix(in oklab, var(--accent) 14%, transparent);
  --shadow-tint: rgb(12 34 78 / 0.26);
  --focus-ring: var(--ink);
  --ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
  --dur-fast: 180ms;
  --dur-base: 320ms;
}

/* Inline icons share one optical box and inherit color from their context. */
.mash-icon {
  display: inline-block;
  inline-size: 1em;
  block-size: 1em;
  flex: none;
  vertical-align: -0.125em;
}

/* The legacy bundle used Font Awesome private-use glyphs for article metadata.
   Masks keep those generated icons after the icon-font dependency is removed. */
.content-meta .date::before,
.content-meta .author::before {
  content: "";
  display: inline-block;
  inline-size: 1em;
  block-size: 1em;
  margin-inline-end: var(--space-3xs);
  vertical-align: -0.125em;
  background-color: currentColor;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  mask-size: contain;
}

.content-meta .date::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M208 34h-26V24a6 6 0 0 0-12 0v10H86V24a6 6 0 0 0-12 0v10H48a14 14 0 0 0-14 14v160a14 14 0 0 0 14 14h160a14 14 0 0 0 14-14V48a14 14 0 0 0-14-14M48 46h26v10a6 6 0 0 0 12 0V46h84v10a6 6 0 0 0 12 0V46h26a2 2 0 0 1 2 2v34H46V48a2 2 0 0 1 2-2m160 164H48a2 2 0 0 1-2-2V94h164v114a2 2 0 0 1-2 2'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M208 34h-26V24a6 6 0 0 0-12 0v10H86V24a6 6 0 0 0-12 0v10H48a14 14 0 0 0-14 14v160a14 14 0 0 0 14 14h160a14 14 0 0 0 14-14V48a14 14 0 0 0-14-14M48 46h26v10a6 6 0 0 0 12 0V46h84v10a6 6 0 0 0 12 0V46h26a2 2 0 0 1 2 2v34H46V48a2 2 0 0 1 2-2m160 164H48a2 2 0 0 1-2-2V94h164v114a2 2 0 0 1-2 2'/%3E%3C/svg%3E");
}

.content-meta .author::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='m225.9 74.78-44.69-44.69a14 14 0 0 0-19.8 0L38.1 153.41a13.94 13.94 0 0 0-4.1 9.9V208a14 14 0 0 0 14 14h44.69a13.94 13.94 0 0 0 9.9-4.1L225.9 94.58a14 14 0 0 0 0-19.8M94.1 209.41a2 2 0 0 1-1.41.59H48a2 2 0 0 1-2-2v-44.69a2 2 0 0 1 .59-1.41L136 72.48 183.51 120ZM217.41 86.1 192 111.51 144.49 64l25.41-25.42a2 2 0 0 1 2.83 0l44.68 44.69a2 2 0 0 1 0 2.83'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='m225.9 74.78-44.69-44.69a14 14 0 0 0-19.8 0L38.1 153.41a13.94 13.94 0 0 0-4.1 9.9V208a14 14 0 0 0 14 14h44.69a13.94 13.94 0 0 0 9.9-4.1L225.9 94.58a14 14 0 0 0 0-19.8M94.1 209.41a2 2 0 0 1-1.41.59H48a2 2 0 0 1-2-2v-44.69a2 2 0 0 1 .59-1.41L136 72.48 183.51 120ZM217.41 86.1 192 111.51 144.49 64l25.41-25.42a2 2 0 0 1 2.83 0l44.68 44.69a2 2 0 0 1 0 2.83'/%3E%3C/svg%3E");
}

/* editorial.css loads after this layer and otherwise restores its dot marker. */
html body.editorial article.content .content-meta .author::before {
  content: "";
  margin-inline-end: var(--space-3xs);
}

/* Ensure the metric-adjusted fallback faces participate in the existing pair. */
html body.editorial :is(article.content, div.intro, div.content) {
  font-family: "Inter", "Inter Fallback", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

html body.editorial :is(
  article.content header h1,
  .content-body h2,
  div.content h2,
  .content-body h3,
  div.content h3,
  div.copy-holder > h1,
  div.copy-holder > h1 + h2
) {
  font-family: "Fraunces", "Fraunces Fallback", Georgia, "Times New Roman", serif;
}

/* Existing nested surfaces become one concentric tray/core treatment. */
article.content:not(.frosted-glass) {
  --surface-radius-outer: calc(var(--radius-lg) + var(--radius-lg));
  border-radius: var(--surface-radius-outer);
  background: color-mix(in oklab, var(--accent) 3%, #fff);
  box-shadow:
    0 0 0 1px var(--hairline),
    0 var(--space-m) var(--space-xl) calc(-1 * var(--space-s)) var(--shadow-tint);
}

/* The homepage shell controls its inset so the nested curves cannot drift. */
body#home article.content:not(.frosted-glass) {
  --surface-inset: var(--space-s);
  padding: var(--surface-inset);
}

body#home article.content > .frosted-glass {
  border-radius: calc(var(--surface-radius-outer) - var(--surface-inset));
}

.frosted-glass {
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.62);
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* Pages where content and frosted-glass are the same node use one surface. */
article.content.frosted-glass,
body#games .content.frosted-glass {
  border-radius: var(--radius-lg);
  box-shadow:
    0 0 0 1px var(--hairline),
    inset 0 1px 0 rgb(255 255 255 / 0.62),
    0 var(--space-m) var(--space-xl) calc(-1 * var(--space-s)) var(--shadow-tint);
}

/* The LCP image shares the site's paper-surface edge treatment but never moves. */
body#home .home-hero-img {
  border-radius: var(--radius-lg);
  box-shadow:
    0 0 0 1px var(--hairline),
    0 var(--space-m) var(--space-xl) calc(-1 * var(--space-s)) var(--shadow-tint);
  transition: none;
  transform: none;
}

/* The editorial prose rules reach the hero: a figure margin under the image and
   an underline border on the link push the anchor box 23px past the container,
   which clips anything pinned to its bottom edge. Match the boxes first. */
body#home .home-hero-img a {
  position: relative;
  display: block;
  line-height: 0;
  border-bottom: 0;
  text-decoration: none;
}

body#home .home-hero-img img {
  margin-bottom: 0;
}

/* The hero owns the whole first screen and is a link, so it has to look like
   one. The badge rides the anchor rather than the image, which keeps the <img>
   the largest paint and leaves the LCP candidate untouched. Its label tracks
   the A/B destination through the attribute the test already writes. */
body#home .home-hero-img a::after {
  position: absolute;
  inset-inline-end: var(--space-s);
  inset-block-end: var(--space-s);
  padding: var(--space-2xs) var(--space-s);
  border-radius: 999px;
  font-size: var(--step--1);
  font-weight: 600;
  line-height: var(--leading-tight);
  color: #fff;
  background: var(--accent);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.26),
    0 var(--space-2xs) var(--space-m) calc(-1 * var(--space-2xs)) var(--shadow-tint);
  transition: transform var(--dur-fast) var(--ease-spring);
}

body#home .home-hero-img a[data-ab-destination="online-game"]::after {
  content: "Play free ↗";
}

body#home .home-hero-img a[data-ab-destination="app-store"]::after {
  content: "Get the app ↗";
}

body#home .home-hero-img a:hover::after {
  transform: translateY(calc(-1 * var(--space-3xs)));
}

/* The homepage grid now uses quiet paper cards instead of cyan gradients. */
body#home .feature-card {
  position: relative;
  border: 0;                               /* depth is the ring, not a border */
  border-radius: var(--radius-lg);
  background: var(--accent-wash);
  background-clip: padding-box;
  box-shadow:
    0 0 0 var(--space-3xs) var(--surface-tray),
    0 0 0 calc(var(--space-3xs) + 1px) var(--hairline),
    0 var(--space-s) var(--space-l) calc(-1 * var(--space-s)) var(--shadow-tint);
  transition: none;
}

body#home .feature-card:hover {
  transform: none;
  background: var(--accent-wash);
  box-shadow:
    0 0 0 var(--space-3xs) var(--surface-tray),
    0 0 0 calc(var(--space-3xs) + 1px) var(--hairline),
    0 var(--space-s) var(--space-l) calc(-1 * var(--space-s)) var(--shadow-tint);
}

body#home .feature-card .icon {
  display: inline-grid;
  place-items: center;
  inline-size: calc(var(--space-xl) + var(--space-2xs));
  aspect-ratio: 1;
  padding: 0;
  border-radius: 999px;
  color: var(--accent);
  background: color-mix(in oklab, var(--accent) 10%, #fff);
  box-shadow: inset 0 0 0 1px var(--hairline);
}

body#home .feature-card .text {
  color: var(--ink);
  text-wrap: pretty;
}

/* The bolded phrase is what the card is about, so it carries the scan cue. */
body#home .feature-card:not(.primary-feature-card) .text strong {
  color: var(--accent);
  font-weight: 600;
}

/* Signature element: the only filled card and the only orchestrated motion. */
body#home .primary-feature-card,
body#home .primary-feature-card:hover {
  color: #fff;
  background: var(--accent);
  box-shadow:
    0 0 0 var(--space-3xs) color-mix(in oklab, var(--accent) 18%, #fff),
    0 0 0 calc(var(--space-3xs) + 1px) color-mix(in oklab, var(--accent) 42%, transparent),
    0 var(--space-s) var(--space-l) calc(-1 * var(--space-s)) var(--shadow-tint);
}

/* Eight co-equal cards is eight decisions. Spanning the grid puts the free
   game in a tier of its own and leaves the other seven as a link shelf. */
body#home .primary-feature-card {
  --arrow-size: calc(var(--space-l) - var(--space-2xs));
  --arrow-inset: var(--space-m);
  grid-column: 1 / -1;
  align-items: center;
  /* Derived from the arrow so the gutter and the glyph cannot drift apart. */
  padding-inline-end: calc(var(--arrow-inset) * 2 + var(--arrow-size));
  transition: transform var(--dur-base) var(--ease-spring);
}

body#home .primary-feature-card .text {
  font-size: var(--step-1);
}

body#home .primary-feature-card:hover {
  transform: translateY(calc(-1 * var(--space-3xs)));
}

body#home .primary-feature-card .icon {
  color: #fff;
  background: rgb(255 255 255 / 0.14);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.26);
}

body#home .primary-feature-card .text,
body#home .primary-feature-card .text strong {
  color: #fff;
}

/* On the full-width banner the arrow centres against the right edge, in the
   gutter reserved by padding-inline-end so no line of text runs under it. */
body#home .primary-feature-card::after {
  content: "↗";
  position: absolute;
  inset-inline-end: var(--arrow-inset);
  inset-block: 0;
  block-size: var(--arrow-size);
  margin-block: auto;
  display: inline-grid;
  place-items: center;
  inline-size: var(--arrow-size);
  aspect-ratio: 1;
  border-radius: 999px;
  color: #fff;
  background: rgb(255 255 255 / 0.14);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.26);
  transition: transform var(--dur-fast) var(--ease-spring);
}

body#home .primary-feature-card:hover::after {
  transform: translate(var(--space-3xs), calc(-1 * var(--space-3xs))) scale(1.05);
}

/* At one column the blue fill already marks the tier, so the arrow gives its
   gutter back rather than squeezing the copy onto five lines. */
@media (max-width: 37.5rem) {
  body#home .primary-feature-card {
    padding-inline-end: var(--space-s);
  }

  body#home .primary-feature-card::after {
    content: none;
  }
}

/* This heading introduces the page's second revenue action, so it reads as a
   section, not a label. Eyebrow scale is reserved for genuinely subordinate
   headings; hierarchy here follows intent rather than uniformity. */
body#home h3:has(+ .stores) {
  margin: var(--space-xl) 0 var(--space-s);
  font-family: "Fraunces", "Fraunces Fallback", Georgia, "Times New Roman", serif;
  font-size: var(--step-2);
  font-style: normal;
  font-weight: 500;
  line-height: var(--leading-tight);
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--ink);
  text-wrap: balance;
}

body#home .feature-grid-section h3 {
  color: var(--accent);
}

/* Navigation uses one contrast-safe action color. */
.top-navigation {
  border-bottom-color: var(--accent);
  box-shadow:
    0 0 0 1px var(--hairline),
    0 var(--space-2xs) var(--space-m) calc(-1 * var(--space-s)) var(--shadow-tint);
}

.top-navigation a,
.hamburger-menu {
  color: var(--accent);
  transition: none;
}

.top-navigation a:hover,
.top-navigation a:focus,
.top-navigation a.active,
.hamburger-menu:hover {
  color: var(--accent);
  background-color: var(--accent-wash);
  border-bottom-color: var(--accent);
}

.top-navigation a:active {
  background-color: color-mix(in oklab, var(--accent) 10%, #fff);
}

/* Sitewide surface holdouts get the same navy-tinted material language. */
:is(.game-card, .app-card, .storeItem, .printable-item, .classic-card),
body#games .game-card {
  border-radius: var(--radius-lg);
  box-shadow:
    0 0 0 1px var(--hairline),
    0 var(--space-s) var(--space-l) calc(-1 * var(--space-s)) var(--shadow-tint);
}

/* App cards stay planted while their icon moves. Game and store cards lift as
   one object, with a deeper shadow state that follows the raised surface. */
.app-card,
.app-card:hover {
  transform: none;
}

:is(.game-card, .storeItem) {
  transition: transform var(--dur-base) var(--ease-spring);
}

:is(.game-card, .storeItem):hover,
body#games .game-card:hover {
  transform: translateY(calc(-1 * var(--space-3xs)));
  box-shadow:
    0 0 0 1px var(--hairline),
    0 var(--space-m) var(--space-xl) calc(-1 * var(--space-s)) var(--shadow-tint);
}

.storeItem.primary,
.storeItem.secondary {
  border: 0;
  background: var(--accent-wash);
}

/* Only the artless card gets a gradient; the rest keep their photography. */
body#games .game-card-image {
  background-color: var(--accent);
}

body#games .game-card-image-cootie-catcher {
  background-image: linear-gradient(135deg, var(--accent), var(--accent-bright));
}

body#games .game-card h3 {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* The apps grid is a <ul> inside div.content, so the editorial prose rules
   reach into the cards: list markers, link underlines, and the display <h2>
   with its accent rule. Insulate the shelf from the article first. */
body.editorial div.content ul.apps-grid > li.app-card {
  margin-top: 0;
  padding: var(--space-m);                 /* restated so the list indent loses */
}

body.editorial div.content ul.apps-grid > li.app-card::before {
  content: none;
}

/* The whole card is one link, so the prose underline and the hover rule would
   both draw a line across it. The icon lift is the hover signal instead. */
body.editorial div.content .app-card-link,
body.editorial div.content .app-card-link:hover {
  text-decoration: none;
  border-bottom-color: transparent;
}

body.editorial div.content h2.app-name {
  margin: 0 0 var(--space-2xs);
  font-size: var(--step-1);
  font-style: normal;
  font-weight: 600;
  line-height: var(--leading-tight);
  letter-spacing: -0.01em;
  text-wrap: balance;
}

body.editorial div.content h2.app-name::before {
  content: none;
}

/* A white core keeps the vivid icons from fighting a tinted card; the depth
   comes from the accent tray ring instead. */
.app-card,
.app-card:hover {
  background: #fff;
  box-shadow:
    0 0 0 var(--space-3xs) var(--surface-tray),
    0 0 0 calc(var(--space-3xs) + 1px) var(--hairline),
    0 var(--space-s) var(--space-l) calc(-1 * var(--space-s)) var(--shadow-tint);
}

/* The link is the real flex context, which is what lets the store badges land
   on a common baseline no matter how long the description runs. */
.app-card {
  align-items: stretch;
  text-align: left;
}

.app-card-link {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  border-radius: var(--radius);            /* rounds the focus ring to match */
}

.app-description {
  color: var(--ink);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  text-wrap: pretty;
}

/* Trim the store badge so the icon stays the heaviest thing in the card. */
.app-download-btn {
  margin-top: auto;
}

.app-download-btn img {
  height: var(--space-l);
}

/* Signature moment for this page: the icon is the only thing that moves, and
   its shadow tracks the PNG alpha so the squircle mask stays intact. */
.app-icon {
  filter: drop-shadow(0 var(--space-2xs) var(--space-s) var(--shadow-tint));
  transition: transform var(--dur-base) var(--ease-spring);
}

.app-card-link:hover .app-icon {
  transform: translateY(calc(-1 * var(--space-3xs))) scale(1.03);
}

/* Replace the remaining purple and green actions with the blue system. */
body#PlayMASH #playButton,
.download-button,
.mash-categories-page .cta-btn-primary {
  color: #fff;
  background: var(--accent);
  border-color: transparent;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.26),
    0 var(--space-s) var(--space-l) calc(-1 * var(--space-s)) var(--shadow-tint);
  transition: transform var(--dur-base) var(--ease-spring);
}

body.editorial .content .download-button {
  color: #fff;
  text-decoration: none;
  transition: transform var(--dur-base) var(--ease-spring);
}

body#PlayMASH #playButton {
  font-family: "Inter", "Inter Fallback", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

body#PlayMASH #playButton:hover,
.download-button:hover {
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.26),
    0 var(--space-s) var(--space-l) calc(-1 * var(--space-s)) var(--shadow-tint);
}

body.editorial .content .download-button:hover {
  color: #fff;
  text-decoration: none;
}

.download-button::before {
  content: none;
}

.download-button:hover .pdf-icon {
  animation: none;
}

.mash-categories-page .classic-card,
.mash-categories-page .cta-block {
  border-color: transparent;
  background: var(--accent-wash);
  box-shadow:
    0 0 0 1px var(--hairline),
    0 var(--space-s) var(--space-l) calc(-1 * var(--space-s)) var(--shadow-tint);
}

.mash-categories-page .classic-card h3 {
  color: var(--accent);
}

.mash-categories-page .category-section h2 {
  border-bottom-color: var(--accent);
}

body.editorial .mash-categories-page .cta-btn-secondary {
  color: var(--accent);
  border-color: var(--accent);
  background: #fff;
}

/* Dark ink remains legible on white, washed, and filled-blue surfaces. */
:is(a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: var(--space-3xs);
}

@media (prefers-reduced-motion: reduce) {
  body#home .home-hero-img a:hover::after,
  body#home .primary-feature-card:hover,
  body#home .primary-feature-card:hover::after,
  body#PlayMASH #playButton:hover,
  .download-button:hover,
  .app-card-link:hover .app-icon,
  .game-card:hover,
  .storeItem:hover {
    transform: none;
  }
}

@media print {
  html,
  body {
    background-image: none !important;
    background-color: #fff !important;
  }

  article.content,
  .frosted-glass,
  .feature-card,
  .game-card,
  .app-card,
  .storeItem,
  .printable-item,
  .classic-card,
  .home-hero-img,
  .top-navigation {
    background: #fff !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }

  body#home .feature-card,
  .app-card {
    border: 1px solid #000;
  }

  .app-icon {
    filter: none !important;
  }

  body#home .feature-card .icon,
  body#home .primary-feature-card::after {
    color: #000;
    background: transparent;
    box-shadow: none;
  }

  /* The hero badge is a screen affordance; paper has nothing to click. The
     attribute selector matches the specificity of the rules that set it. */
  body#home .home-hero-img a[data-ab-destination]::after {
    content: none;
  }

  body#home .primary-feature-card .text,
  body#home .primary-feature-card .text strong {
    color: #000;
  }
}
