@import url("tokens.css?v=41c747ef");

/* ============================================================================
   pgsoft-games.org — stylesheet
   ----------------------------------------------------------------------------
   Third pass, after owner review 2026-09-03. Their words: "too rough ... the
   image all blend together background, very smooth not extra bar or line, sweep
   animation and clean".

   What was actually wrong, visible in their screenshot:
     * the featured rail showed a raw native horizontal scrollbar
     * card artwork stopped at a hard rectangular edge against the card
     * cards were near-grey on near-grey, so they read as boxes, not surfaces
     * each heading carried a stubby dark dash that floated on its own
     * nothing moved

   Fixed here: artwork now dissolves into the card, the scrollbar is replaced by
   an edge fade, cards are much lighter than the ground and lit by a rim
   highlight instead of outlined, headings get a soft graded underline, and there
   is a light sweep on hover plus a scroll-reveal — both CSS-only, both disabled
   under prefers-reduced-motion, and neither load-bearing.

   The original brief called for flat square print furniture. The owner has now
   overridden that twice; divergence from site 1 is carried by palette, typeface,
   layout and elevation, all of which remain completely distinct.

   No filename, class prefix or component name is shared with pgslot-games.io.
   ============================================================================ */

*, *::before, *::after { box-sizing: border-box; }

html {
  overflow-x: clip;              /* clip, not hidden: keeps position:sticky alive */
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  position: relative;
  overflow-x: clip;
  margin: 0;
  background: linear-gradient(180deg, var(--stone) 0%, var(--stone-deep) 100%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--face-body);
  font-size: var(--t-base);
  font-weight: var(--w-body);
  line-height: var(--lh-body);
  letter-spacing: 0;             /* Thai: never negative tracking */
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

/* A wide, very soft pool of light behind the upper page. This is what stops the
   ground reading as flat grey, and it makes raised cards look lit rather than
   pasted on. Fixed, and never interactive. */
body::before {
  content: "";
  position: fixed;
  inset: -20vh 0 auto 0;
  height: 130vh;
  background: radial-gradient(72% 55% at 50% 0%, var(--stone-glow) 0%, transparent 72%);
  opacity: 0.9;
  pointer-events: none;
  z-index: 0;
}
body > * { position: relative; z-index: 1; }

img { max-width: 100%; height: auto; display: block; }
[hidden] { display: none !important; }

:focus-visible {
  outline: 2px solid var(--oxblood);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-to {
  position: absolute; left: -9999px;
  background: var(--oxblood); color: var(--cream);
  padding: var(--s-xs) var(--s-sm);
  border-radius: var(--corner-sm);
  z-index: 99;
}
.skip-to:focus { left: var(--s-sm); top: var(--s-sm); }

/* Visually hidden but still announced. A measured figure and an advertised
   ceiling are distinguished here by colour and position, which assistive tech
   cannot see, so each number carries its own spoken label. */
.said {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.column {
  width: 100%;
  max-width: var(--col, var(--column));
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.column--wide { --col: var(--column-wide); }

/* ── Scroll reveal ──────────────────────────────────────────────────────────
   Scroll-driven, so it needs no JavaScript and cannot leave content stranded:
   where animation-timeline is unsupported the @supports block never applies and
   everything renders normally. */
@keyframes rise {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .slab > .column,
    .strip > .column,
    .band__grid,
    .figures {
      animation: rise linear both;
      animation-timeline: view();
      animation-range: entry 5% cover 20%;
    }
  }
}

/* ── Masthead ───────────────────────────────────────────────────────────────
   Frosted and raised. Not sticky, and no burger: on a phone the nav becomes a
   scrollable strip, so every link is reachable with zero JavaScript. */
.mast {
  position: relative;
  background: linear-gradient(180deg,
    oklch(91% 0.016 72 / 0.92) 0%, oklch(87% 0.018 70 / 0.88) 100%);
  backdrop-filter: blur(10px) saturate(1.1);
  box-shadow: var(--sheen), 0 1px 0 oklch(100% 0 0 / 0.3),
              0 10px 30px oklch(44% 0.032 56 / 0.16);
  z-index: 3;
}
/* The oxblood band is a graded element, not a flat border, so it reads as part
   of the masthead rather than a line stuck underneath it. */
.mast::after {
  content: "";
  display: block;
  height: 4px;
  background: linear-gradient(90deg,
    var(--oxblood-deep) 0%, var(--oxblood) 42%, var(--gap-bar) 100%);
}
.mast__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-md);
  padding-block: var(--s-sm);
}
.mast__logo {
  display: inline-flex;
  align-items: center;
  gap: var(--s-xs);
  text-decoration: none;
  flex: 0 0 auto;
}
.mast__logo img { height: 2rem; width: auto; }
.mast__fallback {
  font-family: var(--face-display);
  font-weight: var(--w-display);
  font-size: var(--t-md);
}

.mast__nav { padding-bottom: var(--s-2xs); }
.mast__list {
  list-style: none;
  margin: 0; padding: 0;
  display: flex;
  align-items: stretch;
  gap: var(--s-2xs);
  overflow-x: auto;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.mast__list::-webkit-scrollbar { display: none; }
/* Fade the trailing edge so a phone user can see the strip continues. The
   featured rail uses the same device; a hidden scrollbar with no cue is how the
   header CTA went unnoticed in the first place. */
@media (max-width: 46rem) {
  .mast__list {
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 2.5rem), transparent 100%);
  }
}
.mast__list a {
  display: inline-flex;
  align-items: center;
  min-height: 2.9rem;
  padding: var(--s-2xs) var(--s-sm);
  border-radius: 999px;
  font-family: var(--face-display);
  font-size: var(--t-sm);
  font-weight: var(--w-body-strong);
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;           /* clickable text must never wrap */
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.mast__list a[aria-current="page"] {
  color: var(--oxblood);
  background: oklch(100% 0 0 / 0.6);
  box-shadow: var(--sheen), 0 1px 3px oklch(46% 0.030 58 / 0.14);
}
@media (hover: hover) {
  .mast__list a:hover { color: var(--ink); background: oklch(100% 0 0 / 0.45); }
}

/* ── Opener ─────────────────────────────────────────────────────────────── */
.opener { padding-block: var(--s-xl) var(--s-lg); }
.opener__eyebrow {
  display: inline-block;
  font-size: var(--t-xs);
  font-weight: var(--w-body-strong);
  letter-spacing: 0.05em;
  color: var(--oxblood);
  background: oklch(100% 0 0 / 0.55);
  box-shadow: var(--sheen), 0 1px 3px oklch(46% 0.030 58 / 0.12);
  padding: 0.4em 0.9em;
  border-radius: 999px;
  margin: 0 0 var(--s-sm);
}
.opener h1 {
  font-family: var(--face-display);
  font-size: var(--t-display);
  font-weight: var(--w-display);
  line-height: var(--lh-display);
  margin: 0 0 var(--s-md);
  max-width: 34ch;
  overflow-wrap: break-word;     /* long Thai compounds must break, not overflow */
}
.opener__stand {
  font-size: var(--t-md);
  color: var(--ink-soft);
  max-width: 60ch;
  margin: 0 0 var(--s-lg);
}

/* The two figures — the site's whole argument, so the strongest surface on the
   page. Glass sitting in the light pool, not an opaque slab. */
.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  grid-template-rows: auto auto auto;   /* label / value / note */
  gap: var(--s-xs) var(--s-md);
  align-items: start;
  padding: var(--s-md) var(--s-md) calc(var(--s-md) + 2px);
  background: linear-gradient(155deg,
    oklch(99% 0.006 80 / 0.94) 0%, oklch(95% 0.010 74 / 0.82) 100%);
  backdrop-filter: blur(6px);
  border-radius: var(--corner);
  box-shadow: var(--sheen), var(--e3);
}
.figures__cell {
  min-width: 0;
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  align-content: start;
}
/* Older engines without subgrid: keep the cell a normal stack. */
@supports not (grid-template-rows: subgrid) {
  .figures__cell { grid-row: auto; grid-template-rows: none; }
}
.figures__label {
  display: block;
  font-size: var(--t-xs);
  font-weight: var(--w-body-strong);
  color: var(--ink-faint);
  line-height: 1.4;
  align-self: end;
}
.figures__v {
  font-family: var(--face-figure);
  font-size: var(--t-figure);
  line-height: 1.05;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  display: block;
  /* Never break a number. "100,000x" split across two lines reads as a
     different figure entirely, which is how this was reported. */
  white-space: nowrap;
  align-self: end;
}
.figures__v--measured   { color: var(--measured); }
.figures__v--advertised { color: var(--advertised); }
.figures__note {
  display: block;
  font-size: var(--t-sm);
  color: var(--ink-faint);
  line-height: 1.5;
  align-self: start;
}
.figures__gap {
  font-family: var(--face-figure);
  font-size: var(--t-figure);
  line-height: 1.05;
  color: var(--oxblood);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  display: block;
  white-space: nowrap;
  align-self: end;
}

/* ── Chip CTA ───────────────────────────────────────────────────────────── */
.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2xs);
  min-height: 3rem;
  padding: var(--s-xs) var(--s-md);
  font-family: var(--face-display);
  font-size: var(--t-sm);
  font-weight: var(--w-body-strong);
  color: var(--oxblood);
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  border: 0;
  border-radius: 999px;
  box-shadow: var(--sheen), var(--e1);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease-out);
}
@media (hover: hover) {
  .chip:hover { box-shadow: var(--sheen), var(--e2); transform: translateY(-2px); }
}
.chip:active { transform: translateY(0); box-shadow: var(--inset); }
.chip--solid {
  color: var(--cream);
  background: linear-gradient(180deg, var(--oxblood) 0%, var(--oxblood-deep) 100%);
  box-shadow: var(--sheen), 0 3px 16px oklch(42% 0.130 25 / 0.42);
}
@media (hover: hover) {
  .chip--solid:hover { box-shadow: var(--sheen), 0 7px 24px oklch(42% 0.130 25 / 0.5); }
}
@media (prefers-reduced-motion: reduce) {
  .chip:hover { transform: none; }
}

/* ── Slabs. Separated by surface and space; not one hairline in the body. ── */
.slab { padding-block: var(--s-xl); }
.slab--rule { padding-block: var(--s-xl); }   /* legacy alias, draws nothing */
.slab--tint {
  background: linear-gradient(180deg,
    oklch(100% 0 0 / 0.36) 0%, oklch(100% 0 0 / 0.10) 100%);
}
/* Darkened from oklch(65%/60%) after the pre-deploy review measured body copy on
   this band at 1.7-2.6:1. It is a mid-tone ground carrying near-white text, which
   is the one combination that looks acceptable on a bright monitor indoors and
   goes unreadable on a phone outdoors -- and two of the three bands using it are
   the pages' core arguments. Darkening the ground rather than lightening the text,
   because the text is already near white. */
.slab--sunk {
  background:
    radial-gradient(80% 100% at 20% 0%, oklch(38% 0.036 56) 0%, transparent 60%),
    linear-gradient(180deg, oklch(34% 0.032 58) 0%, oklch(28% 0.036 54) 100%);
  box-shadow: var(--inset);
  color: oklch(96% 0.008 70);
}
.slab--sunk .copy h2 { color: oklch(99% 0.006 80); }
.slab--sunk .copy p  { color: oklch(92% 0.010 70); }
.slab--sunk .points > li {
  background: linear-gradient(155deg,
    oklch(100% 0 0 / 0.16) 0%, oklch(100% 0 0 / 0.06) 100%);
  backdrop-filter: blur(4px);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.24),
              0 12px 30px oklch(28% 0.030 50 / 0.30);
}
.slab--sunk .points > li::before { color: oklch(89% 0.075 42); }
.slab--sunk .points h3 { color: oklch(99% 0.006 80); }
.slab--sunk .points p  { color: oklch(90% 0.010 70); }

/* ── Prose ──────────────────────────────────────────────────────────────── */
.copy { max-width: 68ch; }
.copy h2 {
  font-family: var(--face-display);
  font-size: var(--t-lg);
  font-weight: var(--w-display);
  line-height: var(--lh-tight);
  margin: var(--s-lg) 0 var(--s-sm);
  overflow-wrap: break-word;
}
.copy h2:first-child { margin-top: 0; }
/* Was a stubby dark dash that read as a stray mark. Now a soft graded rule that
   fades out — wider, lighter, and clearly attached to the heading above it. */
.copy h2::after {
  content: "";
  display: block;
  width: min(11rem, 42%);
  height: 3px;
  margin-top: var(--s-xs);
  border-radius: 2px;
  background: linear-gradient(90deg,
    var(--oxblood) 0%, oklch(58% 0.140 35 / 0.5) 55%, transparent 100%);
}
.slab--sunk .copy h2::after {
  background: linear-gradient(90deg,
    oklch(89% 0.075 42) 0%, oklch(89% 0.075 42 / 0.4) 55%, transparent 100%);
}
.copy h3 {
  font-family: var(--face-display);
  font-size: var(--t-md);
  font-weight: var(--w-body-strong);
  margin: var(--s-md) 0 var(--s-xs);
}
.copy p { margin: 0 0 var(--s-sm); }
.copy ul, .copy ol { margin: 0 0 var(--s-sm); padding-inline-start: 1.4em; }
.copy li { margin-bottom: var(--s-2xs); }
.copy b, .copy strong { font-weight: var(--w-body-strong); }

/* In-content links are emphatic from the start: on site 1 they were ink-coloured
   with a hairline underline and the owner could not find them on the page. */
.copy a:not([class]) {
  color: var(--oxblood);
  font-weight: var(--w-body-strong);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  border-radius: 3px;
  transition: background var(--dur) var(--ease);
}
@media (hover: hover) {
  .copy a:not([class]):hover { background: oklch(100% 0 0 / 0.55); }
}
.slab--sunk .copy a:not([class]) { color: oklch(91% 0.080 45); }

/* ── Featured rail ──────────────────────────────────────────────────────────
   The native scrollbar is gone. Both ends of the rail fade out under a mask,
   which is what tells the reader it continues — cleaner than a scrollbar, and
   the thing the owner specifically asked for ("not extra bar or line"). */
.strip { padding-block: var(--s-lg) var(--s-xl); }
.strip__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-sm);
  margin-bottom: var(--s-md);
}
.strip__head h2 {
  font-family: var(--face-display);
  font-size: var(--t-lg);
  font-weight: var(--w-display);
  margin: 0;
}
.strip__head h2::after {
  content: "";
  display: block;
  width: min(11rem, 60%);
  height: 3px;
  margin-top: var(--s-xs);
  border-radius: 2px;
  background: linear-gradient(90deg,
    var(--oxblood) 0%, oklch(58% 0.140 35 / 0.5) 55%, transparent 100%);
}
.strip__hint { font-size: var(--t-xs); color: var(--ink-faint); }
.strip__rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(15rem, 17.5rem);
  gap: var(--s-sm);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: var(--s-2xs) var(--gutter) var(--s-lg);
  margin-inline: calc(var(--gutter) * -1);
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* fade both ends; the gutter keeps the first card clear of the fade */
  mask-image: linear-gradient(90deg,
    transparent 0,
    #000 var(--gutter),
    #000 calc(100% - var(--gutter) * 1.8),
    transparent 100%);
}
.strip__rail::-webkit-scrollbar { display: none; }

.cut {
  position: relative;
  scroll-snap-align: start;
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  border-radius: var(--corner);
  box-shadow: var(--sheen), var(--e2);
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  isolation: isolate;
  transition: box-shadow var(--dur-slow) var(--ease),
              transform var(--dur-slow) var(--ease-out);
}
/* The artwork dissolves into the card instead of stopping at a hard edge — the
   "blend together" the owner asked for. The gradient is painted in the card's
   own colour, so there is no seam at any card height. */
.cut__art {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--stone-sunk);
}
.cut__art img {
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scale(1.02);
  transition: transform var(--dur-slow) var(--ease-out);
}
.cut__art::after {
  content: "";
  position: absolute;
  inset: auto 0 -1px 0;
  height: 48%;
  background: linear-gradient(180deg,
    oklch(97.5% 0.008 78 / 0) 0%,
    oklch(97.5% 0.008 78 / 0.5) 44%,
    oklch(97.5% 0.008 78 / 0.95) 80%,
    var(--card) 100%);
  pointer-events: none;
}
.cut__fallback {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  font-family: var(--face-display);
  font-size: var(--t-lg);
  color: var(--ink-faint);
  background: linear-gradient(150deg, var(--stone-raised), var(--stone-sunk));
}
/* The sweep: a soft band of light crossing the card on hover. Decorative only,
   sits above the art but below nothing clickable. */
.cut::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(105deg,
    transparent 30%, oklch(100% 0 0 / 0.5) 48%, transparent 66%);
  transform: translateX(-120%);
  opacity: 0;
  pointer-events: none;
  z-index: 2;
}
.cut__body {
  padding: 0 var(--s-sm) var(--s-sm);
  margin-top: calc(var(--s-md) * -1);   /* pull the text up into the faded art */
  display: grid;
  gap: var(--s-2xs);
  position: relative;
  z-index: 1;
}
.cut__name {
  font-family: var(--face-display);
  font-size: var(--t-md);
  font-weight: var(--w-body-strong);
  line-height: var(--lh-tight);
  transition: color var(--dur) var(--ease);
}
.cut__en { font-size: var(--t-xs); color: var(--ink-faint); }
.cut__figure {
  font-family: var(--face-figure);
  font-size: var(--t-figure-s);
  line-height: 1;
  font-weight: 600;
  color: var(--measured);
  font-variant-numeric: tabular-nums;
}
.cut__against { font-size: var(--t-xs); color: var(--ink-faint); }

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .cut:hover { transform: translateY(-6px); box-shadow: var(--sheen), var(--e3); }
  .cut:hover .cut__art img { transform: scale(1.07); }
  .cut:hover .cut__name { color: var(--oxblood); }
  .cut:hover::after { animation: sweep var(--dur-slow) var(--ease-out) forwards; }
}
@media (hover: hover) and (prefers-reduced-motion: reduce) {
  .cut:hover { box-shadow: var(--sheen), var(--e3); }
  .cut:hover .cut__name { color: var(--oxblood); }
}
@keyframes sweep {
  0%   { transform: translateX(-120%); opacity: 0; }
  35%  { opacity: 1; }
  100% { transform: translateX(120%); opacity: 0; }
}

/* ── Metrics band ───────────────────────────────────────────────────────── */
.band {
  background:
    radial-gradient(120% 140% at 15% 0%, var(--gap-bar) 0%, transparent 55%),
    linear-gradient(180deg, var(--oxblood) 0%, var(--oxblood-deep) 100%);
  color: var(--cream);
  padding-block: var(--s-lg);
  box-shadow: inset 0 1px 0 oklch(64% 0.130 30 / 0.55),
              0 16px 44px oklch(40% 0.100 30 / 0.26);
}
.band__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: var(--s-md);
}
.band__cell { min-width: 0; }
.band__v {
  display: block;
  font-family: var(--face-figure);
  font-size: var(--t-figure-s);
  line-height: 1;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.band__l {
  display: block;
  font-size: var(--t-sm);
  margin-top: var(--s-2xs);
  color: oklch(91% 0.024 40);
}

/* ── The ledger ─────────────────────────────────────────────────────────── */
.ledger-wrap {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  background: var(--card);
  border-radius: var(--corner);
  box-shadow: var(--sheen), var(--e3);
  scrollbar-width: thin;
  scrollbar-color: var(--oxblood) var(--card-quiet);
}
.ledger-wrap::-webkit-scrollbar { height: 10px; }
.ledger-wrap::-webkit-scrollbar-track { background: var(--card-quiet); }
.ledger-wrap::-webkit-scrollbar-thumb {
  background: var(--oxblood);
  border-radius: 999px;
  border: 2px solid var(--card-quiet);
}
.ledger {
  width: 100%;
  min-width: 46rem;              /* scrolls sideways inside its own panel */
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.ledger caption {
  caption-side: top;
  text-align: start;
  padding: var(--s-sm) var(--s-md);
  font-size: var(--t-sm);
  color: var(--ink-faint);
  background: linear-gradient(180deg, var(--card) 0%, var(--card-quiet) 100%);
  border-radius: var(--corner) var(--corner) 0 0;
}
.ledger th, .ledger td {
  padding: var(--s-xs) var(--s-sm);
  text-align: start;
  vertical-align: middle;
  border: 0;
}
.ledger thead th {
  font-family: var(--face-display);
  font-size: var(--t-xs);
  font-weight: var(--w-body-strong);
  color: var(--cream);
  background: linear-gradient(180deg, var(--oxblood) 0%, var(--oxblood-deep) 100%);
  position: sticky; top: 0;
  white-space: nowrap;
  z-index: 1;
}
.ledger tbody tr { background: var(--card); transition: background var(--dur) var(--ease); }
.ledger tbody tr:nth-child(even) { background: var(--card-quiet); }
@media (hover: hover) {
  .ledger tbody tr:hover { background: oklch(94% 0.028 42); }
}
.ledger__rank {
  font-family: var(--face-figure);
  font-size: var(--t-base);
  color: var(--ink-faint);
  width: 3.25rem;
}
.ledger__game { min-width: 13rem; }
.ledger__game a {
  font-family: var(--face-display);
  font-weight: var(--w-body-strong);
  color: var(--ink);
  text-decoration: none;
}
@media (hover: hover) {
  .ledger__game a:hover {
    color: var(--oxblood);
    text-decoration: underline;
    text-underline-offset: 3px;
  }
}
.ledger__en { display: block; font-size: var(--t-xs); color: var(--ink-faint); }
.ledger__thumb {
  width: 2.75rem; height: 2.75rem;
  object-fit: cover;
  border-radius: var(--corner-sm);
  box-shadow: 0 2px 6px oklch(46% 0.030 58 / 0.22);
  flex: 0 0 auto;
}
.ledger__cellflex { display: flex; align-items: center; gap: var(--s-xs); min-width: 0; }
.ledger__num {
  font-family: var(--face-figure);
  font-size: var(--t-base);
  white-space: nowrap;
}
.ledger__num--measured   { color: var(--measured); font-weight: 600; }
.ledger__num--advertised { color: var(--advertised); }
.ledger__none { color: var(--ink-faint); font-size: var(--t-sm); }

.ledger__gapcell { min-width: 8.5rem; }
.gap { display: flex; align-items: center; gap: var(--s-xs); }
.gap__track {
  flex: 1 1 auto;
  height: 0.6rem;
  min-width: 3rem;
  background: var(--stone-sunk);
  border-radius: 999px;
  box-shadow: var(--inset);
  overflow: hidden;
}
.gap__fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--oxblood) 0%, var(--gap-bar) 100%);
  box-shadow: var(--sheen);
}
.gap__x {
  font-family: var(--face-figure);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--oxblood);
  white-space: nowrap;
}

/* ── Gallery ────────────────────────────────────────────────────────────── */
.shelf {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
  gap: var(--s-sm);
}
.entry {
  display: flex;
  gap: var(--s-sm);
  align-items: center;
  padding: var(--s-sm);
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  border-radius: var(--corner-sm);
  box-shadow: var(--sheen), var(--e1);
  text-decoration: none;
  color: inherit;
  min-width: 0;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease-out);
}
.entry__art {
  width: 4.5rem; height: 4.5rem;
  flex: 0 0 auto;
  background: var(--stone-sunk);
  border-radius: var(--corner-sm);
  box-shadow: 0 2px 8px oklch(46% 0.030 58 / 0.24);
  overflow: hidden;
}
.entry__art img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
.entry__body { min-width: 0; display: grid; gap: 2px; }
.entry__name {
  font-family: var(--face-display);
  font-size: var(--t-base);
  font-weight: var(--w-body-strong);
  line-height: var(--lh-tight);
  overflow-wrap: break-word;
  transition: color var(--dur) var(--ease);
}
.entry__en { font-size: var(--t-xs); color: var(--ink-faint); }
.entry__nums {
  display: flex; flex-wrap: wrap; gap: var(--s-xs);
  font-size: var(--t-xs); color: var(--ink-soft);
  margin-top: var(--s-2xs);
}
.entry__nums b {
  font-family: var(--face-figure);
  font-weight: 600;
  color: var(--measured);
}
@media (hover: hover) {
  .entry:hover { transform: translateY(-3px); box-shadow: var(--sheen), var(--e2); }
  .entry:hover .entry__name { color: var(--oxblood); }
  .entry:hover .entry__art img { transform: scale(1.08); }
}
@media (hover: hover) and (prefers-reduced-motion: reduce) {
  .entry:hover { transform: none; }
  .entry:hover .entry__art img { transform: none; }
}

/* ── Numbered explainer points ─────────────────────────────────────────── */
.points {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  gap: var(--s-sm);
  counter-reset: pt;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}
.points > li {
  counter-increment: pt;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-sm);
  align-items: start;
  padding: var(--s-md);
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  border-radius: var(--corner);
  box-shadow: var(--sheen), var(--e2);
}
.points > li::before {
  content: counter(pt, decimal-leading-zero);
  font-family: var(--face-figure);
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1;
  color: var(--oxblood);
}
.points h3 {
  font-family: var(--face-display);
  font-size: var(--t-md);
  font-weight: var(--w-body-strong);
  margin: 0 0 var(--s-2xs);
}
.points p { margin: 0; color: var(--ink-soft); }

/* ── Q&A ────────────────────────────────────────────────────────────────── */
.qa { display: grid; gap: var(--s-sm); }
.qa__item {
  padding: var(--s-md);
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  border-radius: var(--corner);
  box-shadow: var(--sheen), var(--e1);
}
.qa__q {
  font-family: var(--face-display);
  font-size: var(--t-md);
  font-weight: var(--w-body-strong);
  margin: 0 0 var(--s-2xs);
}
.qa__a { margin: 0; color: var(--ink-soft); max-width: 68ch; }

/* ── Footer ─────────────────────────────────────────────────────────────── */
.colophon {
  background:
    radial-gradient(90% 120% at 12% 0%, oklch(30% 0.050 35) 0%, transparent 60%),
    linear-gradient(180deg, var(--ink) 0%, oklch(17% 0.020 40) 100%);
  color: oklch(86% 0.010 60);
  padding-bottom: var(--s-lg);
}
.colophon::before {
  content: "";
  display: block;
  height: 4px;
  margin-bottom: var(--s-xl);
  background: linear-gradient(90deg,
    var(--oxblood-deep) 0%, var(--oxblood) 42%, var(--gap-bar) 100%);
}
.colophon__line {
  font-family: var(--face-display);
  font-size: var(--t-md);
  color: var(--cream);
  margin: 0 0 var(--s-md);
  max-width: 54ch;
}
.colophon__meta {
  display: flex; flex-wrap: wrap; gap: var(--s-sm) var(--s-md);
  align-items: center;
  font-size: var(--t-sm);
  padding-top: var(--s-sm);
}
.colophon a { color: oklch(90% 0.024 60); text-decoration: underline; text-underline-offset: 2px; }
.colophon__age {
  font-family: var(--face-display);
  font-weight: var(--w-body-strong);
  color: var(--cream);
  background: var(--oxblood);
  border-radius: 999px;
  padding: 3px var(--s-xs);
}
.colophon__disclaim {
  font-size: var(--t-xs);
  color: oklch(72% 0.010 60);
  margin: var(--s-md) 0 0;
  max-width: 74ch;
}

/* ── Breadcrumb ─────────────────────────────────────────────────────────── */
.trail { font-size: var(--t-xs); color: var(--ink-faint); padding-block: var(--s-sm); }
.trail a { color: var(--ink-soft); }

/* ── Coarse pointers get bigger targets ─────────────────────────────────── */
@media (pointer: coarse) {
  .mast__list a { min-height: 3.1rem; }
  .chip { min-height: 3.25rem; }
}

/* ── Featured rail controls ─────────────────────────────────────────────────
   Added after the owner reported "desktop cannot sweep, mobile version can".
   Hiding the scrollbar left a mouse user with nothing to grab. These are
   inserted by js/rail.js, so they only ever appear when they actually work. */
.strip__nav {
  display: flex;
  gap: var(--s-2xs);
  margin-inline-start: var(--s-sm);
  flex: 0 0 auto;
}
.strip__btn {
  width: 2.75rem; height: 2.75rem;
  display: grid; place-items: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  color: var(--oxblood);
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  box-shadow: var(--sheen), var(--e1);
  cursor: pointer;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease-out),
              opacity var(--dur) var(--ease);
}
.strip__btn svg { width: 1.15rem; height: 1.15rem; display: block; }
@media (hover: hover) {
  .strip__btn:hover:not(:disabled) {
    transform: translateY(-2px);
    box-shadow: var(--sheen), var(--e2);
  }
}
.strip__btn:active:not(:disabled) { transform: translateY(0); box-shadow: var(--inset); }
.strip__btn:disabled { opacity: 0.35; cursor: default; box-shadow: var(--sheen); }
@media (prefers-reduced-motion: reduce) {
  .strip__btn:hover:not(:disabled) { transform: none; }
}
/* Bigger touch targets, and the buttons are redundant on touch anyway. */
@media (pointer: coarse) {
  .strip__btn { width: 3rem; height: 3rem; }
}

/* The head has to allow the controls to sit on the right without squashing the
   heading, so it wraps rather than compressing. */
.strip__head { flex-wrap: wrap; row-gap: var(--s-xs); }

/* While dragging, suppress the snap and the text cursor so the rail follows the
   pointer exactly instead of fighting it. */
.strip__rail.is-dragging {
  scroll-snap-type: none;
  cursor: grabbing;
  user-select: none;
}
.strip__rail.is-dragging .cut { pointer-events: none; }

/* ── Game page hero ─────────────────────────────────────────────────────────
   Art beside the title on a wide screen, stacked on a phone. The artwork keeps
   the same blend-into-the-surface treatment as the cards on the homepage rather
   than sitting in a hard rectangle. */
.hero {
  display: grid;
  gap: var(--s-md) var(--s-lg);
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 46rem) {
  .hero { grid-template-columns: 22rem 1fr; }
}
.hero__art {
  position: relative;
  border-radius: var(--corner);
  overflow: hidden;
  background: var(--stone-sunk);
  box-shadow: var(--sheen), var(--e3);
  aspect-ratio: 4 / 3;
}
.hero__art img { width: 100%; height: 100%; object-fit: cover; }
/* A soft vignette rather than a hard edge, matching the cards. */
.hero__art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 90% at 50% 30%,
    transparent 55%, oklch(40% 0.030 56 / 0.22) 100%);
  pointer-events: none;
}
.hero__text { min-width: 0; }
.hero__text h1 {
  font-family: var(--face-display);
  font-size: var(--t-xl);
  font-weight: var(--w-display);
  line-height: var(--lh-display);
  margin: 0 0 var(--s-2xs);
  overflow-wrap: break-word;
}
.hero__en {
  font-size: var(--t-sm);
  color: var(--ink-faint);
  margin: 0 0 var(--s-xs);
}
.hero__alias {
  font-size: var(--t-sm);
  color: var(--ink-soft);
  margin: 0 0 var(--s-sm);
}

/* ── Spec table on a game page ──────────────────────────────────────────────
   Two columns, so it must NOT inherit the league table's 46rem minimum — that
   would force a pointless sideways scroll on a phone. */
.ledger--spec {
  min-width: 0;
  width: 100%;
}
.ledger--spec th[scope="row"] {
  font-family: var(--face-body);
  font-size: var(--t-sm);
  font-weight: var(--w-body-strong);
  color: var(--ink-soft);
  width: 38%;
  vertical-align: top;
  white-space: normal;
}
.ledger--spec td { vertical-align: top; }
.ledger--spec tbody tr:nth-child(even) { background: var(--card-quiet); }
.ledger--spec strong {
  font-family: var(--face-figure);
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--measured);
}
.ledger--spec .ledger__num--advertised {
  font-family: var(--face-figure);
  font-size: var(--t-md);
}

/* ── Licences and certifications ────────────────────────────────────────────
   Only bodies that could be traced to a supporting line in the research reach
   this list; the verification pass removed the rest. */
.certs {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  gap: var(--s-sm);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}
.certs > li {
  display: grid;
  gap: var(--s-2xs);
  padding: var(--s-md);
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  border-radius: var(--corner);
  box-shadow: var(--sheen), var(--e1);
}
.cert__body {
  font-family: var(--face-display);
  font-size: var(--t-md);
  font-weight: var(--w-body-strong);
  color: var(--oxblood);
}
.cert__detail { font-size: var(--t-sm); color: var(--ink-soft); }

/* ── Company timeline ───────────────────────────────────────────────────────
   A single continuous line down the year column, drawn on the list rather than
   per item, so it reads as one thread and never leaves an orphan dash. */
.marks {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  gap: 0;
}
.marks > li {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: var(--s-sm);
  align-items: baseline;
  padding-block: var(--s-sm);
  position: relative;
}
.marks > li + li { box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.45); }
.mark__year {
  font-family: var(--face-figure);
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--oxblood);
  font-variant-numeric: tabular-nums;
}
.mark__text { color: var(--ink-soft); }
@media (max-width: 30rem) {
  .marks > li { grid-template-columns: 1fr; gap: var(--s-2xs); }
}

/* ── Jackpot status ─────────────────────────────────────────────────────────
   A "no jackpot" verdict must not look like a warning, and a real jackpot must
   not look like a promise. Both are plain facts about how a game is built, so
   the three states are distinguished by hue and weight, not by alarm colours.
   Each pill also carries its meaning as text, never colour alone. */
.jp {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2xs);
  padding: 0.35em 0.85em;
  border-radius: 999px;
  font-family: var(--face-display);
  font-size: var(--t-sm);
  font-weight: var(--w-body-strong);
  line-height: 1.3;
  box-shadow: var(--sheen), 0 1px 3px oklch(46% 0.030 58 / 0.14);
}
/* a genuine prize pool or prize tier */
.jp--real   { color: oklch(30% 0.090 150); background: oklch(92% 0.045 150); }
/* a collection meter the game itself presents as a prize tier */
.jp--meter  { color: oklch(34% 0.080 250); background: oklch(93% 0.035 250); }
/* no jackpot — the correct answer for most PG Soft slots, stated neutrally */
.jp--none   { color: var(--ink-soft);      background: oklch(91% 0.008 70); }
/* sources conflict or are silent */
.jp--unsure { color: oklch(38% 0.060 70);  background: oklch(93% 0.030 80); }

.jp__tiers {
  display: block;
  font-family: var(--face-figure);
  font-size: var(--t-sm);
  color: var(--ink-soft);
  margin-top: var(--s-2xs);
}
.jp__what { color: var(--ink-soft); }

/* The jackpot table is three columns of mostly prose, so it needs a narrower
   minimum than the numeric league table and its own column widths. */
.ledger--jp { min-width: 40rem; }
.ledger--jp td:first-child { min-width: 12rem; }
.ledger--jp td:nth-child(2) { min-width: 11rem; white-space: nowrap; }
.ledger--jp .jp__what { min-width: 18rem; font-size: var(--t-sm); line-height: 1.6; }
.ledger--jp td { vertical-align: top; padding-block: var(--s-sm); }
.ledger--jp .jp__tiers { white-space: normal; }

/* ── Numbered stages ────────────────────────────────────────────────────────
   Used by the how-to-play section. Distinct from .points (the explainer cards on
   the homepage): stages are sequential and read top to bottom in one column, so
   the number sits in a filled disc on a connecting line rather than floating as
   a large figure. */
.stages {
  list-style: none;
  margin: 0; padding: 0;
  counter-reset: st;
  display: grid;
  gap: var(--s-sm);
  max-width: 68ch;
}
.stages > li {
  counter-increment: st;
  position: relative;
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  gap: var(--s-sm);
  align-items: start;
  padding: var(--s-md);
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  border-radius: var(--corner);
  box-shadow: var(--sheen), var(--e1);
}
.stages > li::before {
  content: counter(st);
  width: 2.5rem; height: 2.5rem;
  display: grid; place-items: center;
  border-radius: 999px;
  font-family: var(--face-figure);
  font-size: var(--t-base);
  font-weight: 600;
  color: var(--cream);
  background: linear-gradient(180deg, var(--oxblood) 0%, var(--oxblood-deep) 100%);
  box-shadow: var(--sheen), 0 2px 6px oklch(42% 0.130 25 / 0.35);
}
.stages h3 {
  font-family: var(--face-display);
  font-size: var(--t-md);
  font-weight: var(--w-body-strong);
  margin: 0 0 var(--s-2xs);
  line-height: var(--lh-tight);
}
.stages p { margin: 0; color: var(--ink-soft); }
@media (max-width: 26rem) {
  .stages > li { grid-template-columns: 2rem 1fr; padding: var(--s-sm); }
  .stages > li::before { width: 2rem; height: 2rem; font-size: var(--t-sm); }
}

/* ── Header CTA ─────────────────────────────────────────────────────────────
   Lives in the top deck, not in the scrolling nav strip. It was the strip's last
   item, which put it ~447px off-screen on a 375px phone behind a hidden
   scrollbar — the one commercial element on the site, unreachable from the header
   on every phone. Here it is always visible, at every width, with no JS. */
.mast__cta {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: var(--s-2xs) var(--s-sm);
  border-radius: 999px;
  font-family: var(--face-display);
  font-size: var(--t-sm);
  font-weight: var(--w-body-strong);
  color: var(--cream);
  background: linear-gradient(180deg, var(--oxblood) 0%, var(--oxblood-deep) 100%);
  box-shadow: var(--sheen), 0 2px 10px oklch(42% 0.130 25 / 0.42);
  text-decoration: none;
  white-space: nowrap;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease-out);
}
@media (hover: hover) {
  .mast__cta:hover {
    color: var(--cream);
    background: linear-gradient(180deg, var(--gap-bar) 0%, var(--oxblood) 100%);
    box-shadow: var(--sheen), 0 5px 18px oklch(42% 0.130 25 / 0.5);
    transform: translateY(-1px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .mast__cta:hover { transform: none; }
}

/* The top deck has three children now. On a narrow phone the logo and the CTA
   are the two that matter, so the update date yields — it is also printed in
   every table caption and in the footer, so nothing is lost. */
.mast__top { gap: var(--s-sm); }
@media (max-width: 34rem) {
  }
/* iPhone SE class, 320px. Measured: the lockup plus CTA needs 298px and only
   288px is available after the gutter — 10px over. The marks give up a little
   height rather than the CTA giving up legibility. */
@media (max-width: 22rem) {
  .mast__cta { padding-inline: var(--s-xs); font-size: var(--t-xs); }
  .mast__studio { height: 1.65rem; }
  .mast__top { gap: var(--s-xs); }
}
@media (pointer: coarse) {
  .mast__cta { min-height: 3rem; }
}

/* A single unclassified figure spans both comparison columns, because it belongs
   in neither. Tinted so it reads as a different KIND of row, not a missing value. */
.ledger__single {
  background: oklch(93% 0.020 80);
  box-shadow: var(--inset);
}
.ledger tbody tr:nth-child(even) .ledger__single { background: oklch(91% 0.022 78); }
.ledger__single .ledger__num { color: var(--ink); font-weight: 600; }
.ledger__single .ledger__none { display: block; font-size: var(--t-xs); line-height: 1.4; }

/* ── The site's own mark ────────────────────────────────────────────────────
   Replaces PG Soft's wordmark, which was being used as this site's logo on all
   52 pages while every page disclaimed affiliation. */

/* One element, so none of the multi-part furniture. The owner asked for the PG
   Soft logo alone: a drawn mark, PG Soft's mark and a line of Thai were three
   things competing in a space that needs one. */
.mast__logo { align-items: center; }
.mast__studio {
  height: 2rem;
  width: auto;
  flex: 0 0 auto;
}
