/* Appsinity Games store - pixel skin.
   Loads after the page's own styles and only ever overrides, so deleting the <link> from
   Games/store.html restores the previous look exactly. */

:root {
  --bg: #05060b;
  --panel: #0d1020;
  --panel2: #151a2e;
  --line: #2a3150;
  --line2: #454f7c;
  --text: #f2f4ff;
  --muted: #98a2c4;
  --soft: #6b7396;
  --radius: 0px;
  --px-shadow: 5px 5px 0 #000;
  --px-plate: #0d1020;
}

html, body {
  font-family: "Pixelify Sans", "Press Start 2P", ui-monospace, monospace !important;
  letter-spacing: .01em;
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeSpeed;
  background: var(--bg);
}

/* No anti-aliased edges anywhere: the whole skin depends on hard pixel boundaries.
   The universal rule loses to the page's own `!important` class rules in its mobile block, so the same
   classes are named here as well - equal specificity plus this sheet loads last, which settles it. */
* { border-radius: 0 !important; text-shadow: none; }
.hero, .cat, .quickPage, .empty, .filterPanel, .searchPanel, .notificationPanel,
.profilePanel, .gameContextMenu, .storeAccountMenu, .footerMenu, .badge, .new,
.storeFooter, .footerVersion, .cardImage, .cardMedia, .skel, .skeletonCat,
.notificationIcon { border-radius: 0 !important; }
/* Faces are the one exception: a person cropped into a square reads as a bug, not as the skin. */
.accountAvatar, .miniAvatar, .profileHead img { border-radius: 50% !important; }

/* ---------- the controls themselves stay curved ----------
   Plates, cards and panels are square; anything you press is rounded, so the hard pixel frame reads as
   the surface style and the buttons still read as affordances. */
.primary, .ghost, .heroCtas a, .heroCtas button, .view, .filterBtn, .filterChip, .filterApply,
.filterReset, .footerSelect, .rowArrow, .backTop, .socials a, .nav a, .nav button,
.accountMenuItem, .gameContextMenu button, .profileMenu a, .profileMenu button,
.footerMenu button, .catalogSwitch a { border-radius: 16px !important; }
.search, .search input { border-radius: 18px !important; }
.catalogSwitch { border-radius: 20px !important; }
.iconBtn, .dot, .catI { border-radius: 999px !important; }
/* Game cards carry the same corner language as the controls, one size up because the plate is bigger.
   .card already clips its artwork, so only the frame needs the radius. */
.card, .skeletonCard { border-radius: 18px !important; }
.primary:hover, .view:hover, .filterApply:hover, .nav .active { border-radius: 16px !important; }

/* ---------- pixelated artwork ----------
   Chromium rasterises an element at its layout size and then resamples the transform, so a box drawn at
   a fraction of its slot and scaled back up with nearest-neighbour gives true pixel blocks - no canvas, no
   CORS problem with the CDN art. */
/* .mosaic and .heroShowcase are deliberately left out: they own the hero stage as absolutely positioned
   boxes, and giving them position:relative would collapse the art into nothing. */
.cardArt, .brand, .catI, .iconBtn, .accountAvatar, .miniAvatar,
.searchResult, .notificationIcon, .profileHead, .footerBrand, .socials a { position: relative; }

/* Only artwork that owns a media box may be shrunk and scaled back up: a percentage inside a grid row
   resolves against the whole row, which is how the search-result thumbs ended up painted over the list. */
.cardArt img, .tile img, .heroShowcase video {
  position: absolute !important;
  left: 0 !important; top: 0 !important;
  width: 33.334% !important; height: 33.334% !important;
  transform: scale(3) !important;
  transform-origin: 0 0 !important;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  object-fit: cover !important;
  filter: saturate(1.18) contrast(1.06);
}

.tile img, .heroShowcase video { width: 25% !important; height: 25% !important; transform: scale(4) !important; }

/* Row avatars and tray icons keep their own box and just get the nearest-neighbour resample.
   Faces are excluded: a cartoon portrait resampled hard reads as broken, not pixel-art. */
.searchResult img, .notificationIcon img {
  image-rendering: pixelated;
}

.brand img, .footerBrand img, .catI svg, .footIcon svg, .catalogSwitchIcon svg { image-rendering: pixelated; }

/* Dragging a text selection across a row paints the selection colour over every image box the range
   crosses, so the artwork flashes solid blue while he is only trying to select the text beside it.
   Artwork is a click target, never a selection range; titles and stats stay selectable. */
img, video { -webkit-user-select: none; user-select: none; -webkit-user-drag: none; }

/* ---------- hard plates ---------- */
.card, .quickPage, .cat, .view, .empty, .hero, .search, .catalogSwitch, .iconBtn, .filterBtn,
.footerSelect, .skeletonCard, .skeletonCat, .badge, .filterChip, .new, .footerVersion, .socials a,
.backTop, .primary, .metric {
  border: 3px solid var(--line) !important;
  background: var(--px-plate);
}

.card, .quickPage, .cat, .skeletonCard, .skeletonCat { box-shadow: var(--px-shadow); }
.card:hover, .quickPage:hover, .cat:hover {
  border-color: var(--line2) !important;
  box-shadow: 8px 8px 0 #000;
  transform: translate(-3px, -3px);
}

.top { border-bottom: 3px solid var(--line) !important; height: 68px; }
.shell { --gutter: 26px; padding-top: 20px; }
.hero { border-width: 3px !important; }
.hero::after { border: 3px solid rgba(255, 255, 255, .07); background: none; }
.hero::before { background: linear-gradient(90deg, #05060b 0%, rgba(5, 6, 11, .97) 34%, rgba(5, 6, 11, .74) 54%, rgba(5, 6, 11, .2) 78%, rgba(5, 6, 11, .05) 100%); }

/* ---------- type scale, pixel faces ---------- */
.brand, .section .head h2, .footHead, .filterGroupTitle, .status, .cardTitle { font-family: "Pixelify Sans", monospace; }
.brand { font-weight: 700; letter-spacing: .06em; }
.hero h1 { font-family: "Press Start 2P", monospace; font-size: clamp(1.15rem, 1.9vw, 2.1rem) !important; line-height: 1.5 !important; font-weight: 400 !important; }
.hero p { font-size: 16px; line-height: 1.7; color: #c3cbe6; }
.section .head h2 { font-size: 13px !important; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.head h2 { border-left-width: 6px !important; padding-left: 12px !important; }
.nav a, .nav button, .view, .badge, .new, .cat strong, .quickPage strong, .cardTitle, .primary, .ghost,
.filterChip, .accountMenuItem, .gameContextMenu button, .profileMenu a, .profileMenu button, .footerSelect,
.footerMenu button, .search input, .searchResultTitle, .notificationText b, .footLinks a, .legalLinks a {
  font-weight: 700;
  letter-spacing: .04em;
}
.cardTitle { font-size: 16px !important; }
.cardSub, .metaStat, .searchResultMeta, .notificationText p, .quickPage span, .cat > span:not(.catI) { font-size: 13px; color: var(--muted); }
.badge, .new, .footerVersion { font-size: 9px !important; letter-spacing: .12em; text-transform: uppercase; }
.badge { background: #1b2140 !important; border: 3px solid #000 !important; color: #fff !important; padding: 4px 7px !important; }
.new { background: #2a3150 !important; }

/* ---------- controls ---------- */
.primary {
  background: var(--purple) !important; color: #fff !important; border: 3px solid #000 !important;
  box-shadow: 4px 4px 0 #000; font-size: 14px;
}
.primary:hover { transform: translate(-2px, -2px); box-shadow: 7px 7px 0 #000; }
.primary:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 #000; }
.ghost { font-size: 14px; border-bottom: 3px solid transparent !important; }
.ghost:hover { border-bottom-color: var(--purple) !important; }
.nav .active { background: #1b2140 !important; box-shadow: inset 0 -4px 0 var(--purple) !important; color: #fff !important; }
.nav a:hover, .nav button:hover { background: #151a2e; }
/* Pixelify Sans is wider than Inter, so at laptop widths the row used to cut "Top Charts" in half - it now
   scrolls silently like the mobile header does instead. */
.nav { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.nav::-webkit-scrollbar { display: none; }
.nav a, .nav button { font-size: 12.5px; padding: 0 10px; }
.iconBtn { background: var(--px-plate); color: #dfe4f5; }
.iconBtn:hover { border-color: var(--purple) !important; }
.dot { width: 10px; height: 10px; background: var(--purple); box-shadow: 0 0 0 3px #000; }
.search { background: #080a14 !important; }
.search:focus-within { border-color: var(--purple) !important; box-shadow: 4px 4px 0 #000; }
.search kbd { border: 2px solid var(--line2) !important; background: #151a2e; color: #b9c1da; }
.catalogSwitch { background: #080a14; gap: 0 !important; padding: 0 !important; }
.catalogSwitch a { border: 0; border-right: 3px solid var(--line); }
.catalogSwitch a:last-child { border-right: 0; }
.catalogSwitch a.active { background: var(--purple) !important; color: #fff !important; box-shadow: inset 0 -4px 0 rgba(0, 0, 0, .45); }
.filterChip { background: #10142a !important; }
.filterChip.active { background: #241a45 !important; border-color: var(--purple) !important; box-shadow: 4px 4px 0 #000; }
.filterChipBox { border: 3px solid #4a4f7e !important; background: #080a14 !important; }
.filterChipBox::after { box-shadow: none; background: var(--purple); }
.filterApply { background: var(--purple) !important; border: 3px solid #000 !important; }
.filterReset { border: 3px solid var(--line2) !important; background: #0d1020 !important; }
.view { background: #0d1020 !important; color: #dfe4f5 !important; padding: 8px 14px !important; }
.view:hover { border-color: var(--purple) !important; color: #fff !important; }
.catI { background: #1b2140 !important; border: 3px solid var(--line); color: #cfd6ee; }
.quickPage b { color: var(--purple); }

/* ---------- popovers: hard plates, no blur ---------- */
.filterPanel, .searchPanel, .notificationPanel, .profilePanel, .gameContextMenu, .storeAccountMenu, .footerMenu {
  border: 3px solid var(--line2) !important;
  background: #0b0e1c !important;
  box-shadow: 8px 8px 0 rgba(0, 0, 0, .85) !important;
  filter: none !important;
  backdrop-filter: none !important;
}
.filterPanel { border-color: var(--purple) !important; }
.notificationItem, .searchResult, .profileMenuGroup + .profileMenuGroup, .accountSummary,
.gameContextHead, .filterHead, .notificationHead, .filterFoot, .searchPanelHead {
  border-color: var(--line) !important; border-width: 3px !important;
}
.gameContextDivider { background: var(--line) !important; height: 3px !important; }
.gameContextMenu button:hover, .accountMenuItem:hover, .searchResult:hover,
.profileMenu a:hover, .profileMenu button:hover, .footerMenu button:hover, .footerMenu button.active {
  background: #241a45 !important; color: #fff !important;
}
.profileName, .gameContextTitle, .notificationText b, .searchResultTitle { color: #fff; }
.profileHead img { border: 3px solid var(--purple) !important; box-shadow: 0 0 0 3px #000 !important; }
.accountAvatar, .miniAvatar { background: var(--purple) !important; border: 3px solid #000; }

/* ---------- footer ---------- */
.storeFooter { border-top: 3px solid var(--line) !important; }
.footerBottom { border-top: 3px solid var(--line) !important; }
.socials a { background: #10142a; box-shadow: 3px 3px 0 #000; }
.socials a:hover { border-color: var(--purple) !important; transform: translate(-2px, -2px); box-shadow: 5px 5px 0 #000; }
.backTop { background: #10142a; box-shadow: 3px 3px 0 #000; }
.backTop:hover { transform: translate(-2px, -2px); box-shadow: 5px 5px 0 #000; }
.footerVersion { background: var(--purple) !important; border: 3px solid #000 !important; }

/* ---------- loading blocks sweep in hard blocks ---------- */
@keyframes pixelSweep { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.skel, body.loading .hero h1, body.loading .hero p, body.loading .metric strong, body.loading .metric span {
  background: repeating-linear-gradient(90deg, #10142a 0 10px, #1b2140 10px 20px) !important;
  background-size: 240% 100% !important;
  animation: pixelSweep 1.7s linear infinite !important;
}
.skeletonCard, .skeletonCat { border: 3px solid var(--line) !important; background: #080a14 !important; }

/* ---------- motion ----------
   Pixel is the look, not the frame rate: the timing functions are the page's own eased ones, and the only
   change is one notch more duration so a hover reads as motion rather than a jump. */
* { transition-duration: .26s !important; }
.tile { animation-duration: 44s !important; }
/* Matches the 44s cycle; the page staggers .t1-.t6 six seconds apart for its own 36s. */
.tile.t2 { animation-delay: 7.3s !important; } .tile.t3 { animation-delay: 14.7s !important; }
.tile.t4 { animation-delay: 22s !important; } .tile.t5 { animation-delay: 29.3s !important; }
.tile.t6 { animation-delay: 36.7s !important; }
html.page-leaving .shell, html.page-leaving main, html.page-enter .shell, html.page-enter main { filter: none !important; }

/* ---------- CRT scanlines, deliberately faint ---------- */
body::after {
  content: "";
  position: fixed; inset: 0;
  z-index: 9999;
  pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(0, 0, 0, .22) 0 1px, transparent 1px 3px);
  opacity: .5;
  mix-blend-mode: multiply;
}

@media (prefers-reduced-motion: reduce) {
  .skel, body.loading .hero h1, body.loading .hero p { animation: none !important; }
  body::after { display: none; }
}

@media (max-width: 700px) {
  .top { height: auto; }
  .hero h1 { font-size: 1.05rem !important; }
  .tile img, .heroShowcase video { width: 30%; height: 30%; transform: scale(3.4); }
  body::after { display: none; }
}

/* ---------- phone header ----------
   The inline #appsinity-mobile-polish block already wants the search bar on its own full-width row, but
   `.search` is nested inside `.actions`: `grid-column` is inert in that flex row and `width:100%` resolved
   against the cluster's own content width, so the bar ended ~20px past the screen edge at 390px. Taking
   `.actions` out of the box model lets its children join the header's flex line directly, so the bar can
   wrap under the brand + icon cluster at every width the polish block targets. */
@media (max-width: 760px) {
  .top { display: flex !important; flex-wrap: wrap !important; align-items: center !important; gap: 8px !important; height: auto !important; }
  .brand { flex: 0 1 auto !important; min-width: 0 !important; font-size: 17px !important; }
  .brand img { width: 32px !important; height: 32px !important; flex: 0 0 32px !important; }
  .actions { display: contents !important; }
  .catalogSwitch { margin-left: auto !important; min-width: 0 !important; flex: 0 0 auto !important; }
  .catalogSwitch a { padding: 0 8px !important; }
  .notifyWrap, .profileWrap { flex: 0 0 auto !important; }
  .iconBtn { width: 36px !important; height: 36px !important; flex: 0 0 36px !important; }
  .search { order: 9 !important; flex: 1 1 100% !important; width: auto !important; min-width: 0 !important; height: 40px !important; }
  .search input { display: block !important; min-width: 0 !important; }
  .search kbd { display: none !important; }
  .filterBtn { width: 30px !important; height: 30px !important; flex: 0 0 30px !important; }
  .nav { order: 10 !important; flex: 1 1 100% !important; width: 100% !important; }
}

/* Press Start 2P is a 1:1 bitmap face, so the 9-letter wordmark costs ~150px. The header row has to carry
   it plus the catalog switch and both icon buttons, and it wrapped the avatar onto its own line at 390px. */
@media (max-width: 560px) {
  .brand { font-size: 14px !important; gap: 7px !important; }
  .catalogSwitch a { padding: 0 6px !important; gap: 4px !important; }
}

@media (max-width: 430px) {
  .brand { font-size: 0 !important; gap: 0 !important; }
}

/* ---------- narrow laptops, 1200-1580px ----------
   Measured at 1280px: `.cats` cards are 141px wide, and the icon (37px) + 15px gap + 18px side padding leaves
   ~53px for the label — "Platformer" needs 92px, "Adventure" 85px, "Simulation" 83px, so three of seven
   category names spilled out of their own card. Seven columns only pays off once the section is ~1420px wide
   (viewport ~1560px), so below that go four and let the labels breathe. */
@media (min-width: 1201px) and (max-width: 1580px) {
  .cats { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
}

/* The quick-link arrow is the literal text "->", and a hyphen is a line-break opportunity: on the two cards
   whose description wraps, it split into a stacked `-` over `>` (measured 48px tall against 24px on the card
   whose text fit on one line). Titles were ragged for the same reason the row uses `align-items: flex-end` —
   the shorter text block sat 18px lower than its neighbours. */
.quickPage { align-items: flex-start !important; }
.quickPage > span { min-width: 0 !important; }
.quickPage b { flex: 0 0 auto !important; white-space: nowrap !important; align-self: flex-end !important; }

/* ---------- legal fine print: never pixel ---------- */
/* Consent sentences, footer copyright and policy links are legal text. Pixelify Sans is a bitmap face and
   small legal copy in it is hard to read and looks unserious, so these lines keep the system font even on
   pages that wear the pixel skin. */
.auth-note, .legalText, .legalText div, .legalLinks, .legalLinks a,
.check span, .finish-check span, .noteBox, .wp-disclaimer, .privacy-note,
.disclaimer, .finePrint, .fine-print, .footnote, small {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif !important;
  letter-spacing: normal !important;
}
.auth-note a, .legalLinks a { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- numbers: never pixel ---------- */
/* Same reasoning as the fine print, only more urgent: a rating and an install count are the two things on a card
   a player actually reads, and both pixel faces wreck digits. Press Start 2P is cut on an 8px grid, so "4.7"
   becomes three grey blocks; Pixelify Sans bold at 13px fuses "1,234" into a single shape. Smoothing is already
   off, which keeps the stems sharp but cannot give these faces the counters their digits need. The tracking and
   the uppercase go too, because a number column that rattles is unreadable even in a good face. */
.metaStat, .searchResultMeta, .footerVersion {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace !important;
  letter-spacing: 0 !important;
  font-variant-numeric: tabular-nums;
}
.footerVersion { font-size: 11px !important; text-transform: none !important; }
