/* ==========================================================================
   ROYALTY CASINO PRAGUE — "Neon Royale"
   60% warm marble white · 30% violet/blue neon atmosphere · 10% gold+magenta
   ========================================================================== */

:root {
  /* Core */
  --bg-base: #F3EFE6;        /* warm marble white */
  --bg-dark: #1A1230;        /* deep violet-black, sparingly */
  --neon-violet: #6B3FA0;    /* dominant LED cove glow */
  --neon-blue: #4A3FD4;      /* secondary neon accent */
  --neon-magenta: #D62E8C;   /* Haig's Bar signage accent — bar section only */
  --gold: #C9A227;           /* stanchions, chips, script wordmark */
  --gold-deep: #A8861D;      /* gold on light bg (AA-safe hairlines/hover) */
  --felt-green: #1F5C4A;     /* table felt accent */

  /* Rug motif palette — dividers + footer strip */
  --rug-blue: #5B7FA6;
  --rug-coral: #D89A96;
  --rug-ochre: #C9A66B;

  /* Text */
  --ink: #221A33;            /* on light */
  --ink-soft: #4A4160;       /* secondary on light */
  --ink-inverse: #F8F5EE;    /* on dark/violet */
  --ink-inverse-dim: #CFC7E0;

  /* Type */
  --sans: "Poppins", system-ui, sans-serif;
  --script: "Playfair Display", serif;
  --body: "Inter", system-ui, sans-serif;

  /* Shape & rhythm */
  --radius: 6px;
  --radius-sm: 4px;
  --container: 1200px;
  --hairline-gold: 1px solid rgba(168, 134, 29, 0.45);
  --hairline-light: 1px solid rgba(34, 26, 51, 0.14);
  --hairline-inverse: 1px solid rgba(248, 245, 238, 0.18);
}

/* --- reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg-base);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, video { max-width: 100%; display: block; }
a { color: inherit; }
h1, h2, h3, h4 { font-family: var(--sans); line-height: 1.15; margin: 0 0 0.5em; }
p { margin: 0 0 1em; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.visually-hidden:focus {
  width: auto; height: auto; clip: auto; z-index: 200;
  background: var(--bg-dark); color: var(--ink-inverse); padding: 12px 20px;
}

.container { max-width: var(--container); margin: 0 auto; padding: 0 24px; }
.section { padding: 96px 0; position: relative; }

/* --- typography helpers ---------------------------------------------------- */
.eyebrow {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--neon-violet);
  margin: 0 0 14px;
}
.eyebrow--script {
  font-family: var(--script);
  font-style: italic;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
  font-size: 22px;
}
h2 { font-size: clamp(30px, 4.4vw, 46px); font-weight: 600; letter-spacing: -0.01em; }
h3 { font-size: 22px; font-weight: 600; }
.lead { font-size: 19px; color: var(--ink-soft); max-width: 640px; }
.sec-head { max-width: 720px; margin-bottom: 48px; }

/* --- buttons ---------------------------------------------------------------
   Gold fill on dark sections, gold outline on light. Flat, 1px hairline,
   no drop shadows — marble/glass material language. */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--sans); font-weight: 600; font-size: 15px;
  letter-spacing: 0.04em;
  padding: 14px 28px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
  border: 1px solid transparent;
}
.btn svg { width: 18px; height: 18px; flex: none; }
.btn--gold { /* on dark */
  background: var(--gold);
  color: var(--bg-dark);
  border-color: rgba(248, 245, 238, 0.25);
}
.btn--gold:hover { background: #DDB53A; }
.btn--outline { /* on light */
  background: transparent;
  color: var(--ink);
  border-color: var(--gold-deep);
}
.btn--outline:hover { background: rgba(201, 162, 39, 0.12); }
.btn--ghost-dark { /* secondary on dark */
  background: transparent;
  color: var(--ink-inverse);
  border-color: rgba(248, 245, 238, 0.4);
}
.btn--ghost-dark:hover { border-color: var(--gold); color: var(--gold); }
/* Glass secondary, for use over moving footage (the hero). The hairline is a
   masked gradient ring rather than a flat border, so the edge catches light at
   top and bottom and disappears at the sides — reads as a glass lip, not a box.
   NB: the standard `mask` is declared alongside `-webkit-mask`; with only the
   webkit one, Firefox skips the cut-out and paints a solid slab. */
.btn--glass {
  background: rgba(255, 255, 255, 0.01);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  color: var(--ink-inverse);
  border: none;
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.1);
  position: relative;
  overflow: hidden;
}
.btn--glass::before {
  content: ""; position: absolute; inset: 0;
  border-radius: inherit;
  padding: 1.4px;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.45) 0%, rgba(255, 255, 255, 0.15) 20%,
    rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0) 60%,
    rgba(255, 255, 255, 0.15) 80%, rgba(255, 255, 255, 0.45) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}
.btn--glass:hover { color: var(--gold); }

/* --- header ---------------------------------------------------------------- */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  padding: 14px 0;
  transition: background-color 0.25s ease, box-shadow 0.25s ease, padding 0.25s ease;
  color: var(--ink-inverse);
}
.site-header.scrolled, .site-header.nav-open, .site-header.solid {
  background: rgba(243, 239, 230, 0.96);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--ink);
  border-bottom: var(--hairline-gold);
  padding: 10px 0;
}
.header-inner { display: flex; align-items: center; gap: 28px; }
.brand { display: inline-flex; align-items: baseline; gap: 8px; text-decoration: none; }
.brand__block {
  font-family: var(--sans); font-weight: 700; font-size: 19px;
  letter-spacing: 0.28em;
}
.brand__script {
  font-family: var(--script); font-style: italic; font-weight: 600;
  font-size: 21px; color: var(--gold); letter-spacing: 0.01em;
  transform: translateY(1px);
}
.site-header.scrolled .brand__script, .site-header.solid .brand__script { color: var(--gold-deep); }
.nav { display: flex; gap: 26px; margin-left: auto; }
.nav a {
  font-family: var(--sans); font-weight: 500; font-size: 14px;
  letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
  padding: 6px 2px; border-bottom: 2px solid transparent;
  transition: border-color 0.2s ease;
}
.nav a:hover { border-bottom-color: var(--gold); }
.header-right { display: flex; align-items: center; gap: 18px; }
.lang-switch { display: flex; gap: 6px; font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em; }
.lang-switch a { text-decoration: none; opacity: 0.6; padding: 2px 3px; }
.lang-switch a:hover { opacity: 1; }
.lang-switch a[aria-current="true"] { opacity: 1; color: var(--gold); font-weight: 600; }
.site-header.scrolled .lang-switch a[aria-current="true"],
.site-header.solid .lang-switch a[aria-current="true"] { color: var(--gold-deep); }
.header-call {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--sans); font-weight: 600; font-size: 14px;
  text-decoration: none;
}
.header-call svg { width: 16px; height: 16px; }
.nav-toggle {
  display: none; background: none; border: 0; color: inherit;
  width: 42px; height: 42px; cursor: pointer; padding: 8px;
}
.nav-toggle svg { width: 100%; height: 100%; }

/* --- hero ------------------------------------------------------------------ */
.hero {
  position: relative; min-height: 100svh;
  display: flex; align-items: flex-end;
  color: var(--ink-inverse);
  overflow: hidden;
  background: var(--bg-dark);
}
.hero__media { position: absolute; inset: 0; }
.hero__media video, .hero__media img.hero__poster {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
/* Populated frame → stronger violet scrim across the bottom two-thirds */
.hero__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg,
      rgba(26, 18, 48, 0.30) 0%,
      rgba(26, 18, 48, 0.10) 22%,
      rgba(46, 26, 82, 0.42) 55%,
      rgba(26, 18, 48, 0.88) 100%);
}
.hero__inner { position: relative; width: 100%; padding-bottom: 96px; padding-top: 160px; }
.hero__kicker {
  font-family: var(--sans); font-size: 13px; font-weight: 600;
  letter-spacing: 0.3em; text-transform: uppercase;
  color: var(--ink-inverse-dim); margin-bottom: 18px;
}
.hero__lockup { margin: 0 0 10px; }
.hero__lockup .block {
  display: block;
  font-family: var(--sans); font-weight: 700;
  font-size: clamp(44px, 9vw, 108px);
  letter-spacing: 0.22em; text-indent: 0.22em; /* optically re-center wide tracking */
  line-height: 1;
}
.hero__lockup .script {
  display: block;
  font-family: var(--script); font-style: italic; font-weight: 500;
  font-size: clamp(38px, 7vw, 84px);
  color: var(--gold);
  margin-top: 2px;
  line-height: 1.1;
}
.hero__tagline { max-width: 560px; font-size: 18px; color: var(--ink-inverse-dim); margin-bottom: 30px; }
.hero__cta { display: flex; gap: 14px; flex-wrap: wrap; }

/* --- hero: 3D scroll --------------------------------------------------------
   site-neon.js writes a single 0→1 progress value into --hp; every depth
   offset below is derived from it, so the whole feel is tunable here without
   touching JS. At --hp:0 the section renders exactly as the static version,
   apart from the 1.08 background scale (see below).

   Depth reads from three cues stacked together:
     1. the footage drifts DOWN while the copy rises  → opposed motion
     2. each copy line rises at its own rate          → separation
     3. the copy block tilts away on rotateX          → the actual 3D part
   Text is vector, so it stays razor-sharp through the tilt; the 720p clip
   deliberately gets NO translateZ, which would force an upscale and soften it. */
.hero {
  perspective: 1200px;
  perspective-origin: 50% 60%;
  --hp: 0;
}
/* 1.08 buys ~4vh of bleed on every edge so the drift can never expose one. */
.hero__media {
  transform: scale(1.08) translateY(calc(var(--hp) * 4vh));
  will-change: transform;
}
/* Deepens the scrim as the section leaves — invisible at rest (opacity 0). */
.hero__scrim::after {
  content: ""; position: absolute; inset: 0;
  background: var(--bg-dark);
  opacity: calc(var(--hp) * 0.45);
}
.hero__inner {
  transform: translateY(calc(var(--hp) * -5vh)) rotateX(calc(var(--hp) * 7deg));
  transform-origin: 50% 100%;
  opacity: calc(1 - var(--hp) * 1.15);
  will-change: transform, opacity;
}
.hero__kicker  { transform: translateY(calc(var(--hp) * -1.5vh)); }
.hero__lockup  { transform: translateY(calc(var(--hp) * -3vh)); }
.hero__tagline { transform: translateY(calc(var(--hp) * -4.5vh)); }
.hero__cta     { transform: translateY(calc(var(--hp) * -6vh)); }

/* Bloom on the lockup so it holds against the moving footage. */
.hero__lockup .block {
  text-shadow: 0 0 80px rgba(248, 245, 238, 0.30), 0 0 160px rgba(248, 245, 238, 0.10);
}
.hero__lockup .script {
  text-shadow: 0 0 60px rgba(201, 162, 39, 0.45), 0 0 130px rgba(201, 162, 39, 0.18);
}

/* --- trust bar --------------------------------------------------------------
   Thin strip under the hero, gold hairline top & bottom. */
.trust-bar {
  border-top: var(--hairline-gold);
  border-bottom: var(--hairline-gold);
  background: var(--bg-base);
  padding: 14px 0;
}
.trust-bar__inner {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 12px 34px;
  font-family: var(--sans); font-size: 14px;
}
.trust-item { display: inline-flex; align-items: center; gap: 9px; color: var(--ink-soft); }
.trust-item strong { color: var(--ink); font-weight: 600; }
.trust-item svg { width: 17px; height: 17px; color: var(--gold-deep); flex: none; }
.trust-badge {
  font-weight: 700; font-size: 13px; letter-spacing: 0.02em;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius-sm);
  padding: 3px 9px;
}

/* --- rug divider ------------------------------------------------------------
   Watercolor-blob motif of the signature rug, 10–15% opacity, CSS/SVG only. */
.rug-divider { display: block; width: 100%; height: 90px; }
.rug-divider--flip { transform: scaleX(-1); }

/* --- games bento ------------------------------------------------------------ */
.bento {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 300px;
  gap: 18px;
}
.game-card {
  position: relative; overflow: hidden;
  border-radius: var(--radius);
  border: var(--hairline-light);
  color: var(--ink-inverse);
  text-decoration: none;
  background: var(--bg-dark);
}
.game-card--tall { grid-row: span 2; }
.game-card--wide { grid-column: span 2; }
/* The feature tile carries a 4:3 room shot across the full container width.
   On one 300px row the box is ~1152x300 and object-fit: cover keeps barely a
   third of the photo's height; two rows brings the box to ~1152x618 so most
   of the room is in frame. cover is kept rather than contain — it fills the
   tile and never distorts, it only decides how much is cropped. */
.game-card--feature { grid-row: span 2; }
/* Bias the crop below centre: the ceiling is the least interesting band and
   the tables are what the tile is about. */
.game-card--feature .game-card__media img { object-position: center 58%; }
.game-card__media { position: absolute; inset: 0; }
.game-card__media img, .game-card__media video {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 0.5s ease;
}
.game-card:hover .game-card__media img,
.game-card:hover .game-card__media video { transform: scale(1.035); }
.game-card__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(185deg, rgba(26,18,48,0) 32%, rgba(26,18,48,0.55) 68%, rgba(26,18,48,0.92) 100%);
}
.game-card__body { position: absolute; inset: auto 0 0 0; padding: 24px 26px; }
.game-card__body h3 {
  display: inline-block;
  font-size: 24px; margin-bottom: 6px;
  border-bottom: 2px solid transparent;
  transition: border-color 0.25s ease;
  padding-bottom: 3px;
}
.game-card:hover .game-card__body h3 { border-bottom-color: var(--gold); }
.game-card__body p { font-size: 15px; color: var(--ink-inverse-dim); margin: 0; max-width: 46ch; }
.game-card__tag {
  position: absolute; top: 18px; left: 20px;
  font-family: var(--script); font-style: italic; font-weight: 500;
  font-size: 19px; color: var(--gold);
  text-shadow: 0 1px 14px rgba(26, 18, 48, 0.8);
}

/* --- the floor (editorial) --------------------------------------------------- */
.floor__grid {
  display: grid; grid-template-columns: minmax(320px, 5fr) 7fr;
  gap: 56px; align-items: center;
}
.floor__media { border-radius: var(--radius); overflow: hidden; border: var(--hairline-light); }
.floor__features { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-top: 26px; }
.floor__feature {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--sans); font-size: 14px; font-weight: 500; color: var(--ink-soft);
}
.floor__feature svg { width: 17px; height: 17px; color: var(--neon-violet); flex: none; }
.gallery-strip {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 14px; margin-top: 56px;
}
.gallery-strip figure {
  margin: 0; border-radius: var(--radius); overflow: hidden;
  border: var(--hairline-light); aspect-ratio: 3 / 4; background: var(--bg-dark);
}
.gallery-strip figure:nth-child(2n) { transform: translateY(20px); }
.gallery-strip img { width: 100%; height: 100%; object-fit: cover; }

/* --- Haig's Bar ---------------------------------------------------------------
   The ONLY section that uses magenta — reads as a distinct sub-brand. */
.bar { background: var(--bg-dark); color: var(--ink-inverse); overflow: hidden; }
.bar .eyebrow { color: var(--neon-magenta); }
.bar__grid {
  display: grid; grid-template-columns: 7fr 5fr;
  gap: 56px; align-items: center;
}
/* Box is reserved at the clip's 16:9 before any media loads. The poster
   (3:2) and the clip (16:9) disagree, and Chrome sizes a <video> from its
   poster until playback starts — without this the section collapsed 66px
   the moment the clip autoplayed on scroll-in. */
.bar__media {
  position: relative; border-radius: var(--radius); overflow: hidden;
  aspect-ratio: 16 / 9; background: var(--bg-dark);
}
.bar__media video, .bar__media img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.bar__media img { display: none; } /* fallback — shown only when the clip is hidden */
.bar__media::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border: 1px solid rgba(214, 46, 140, 0.35); border-radius: var(--radius);
}
.bar__script {
  font-family: var(--script); font-style: italic; font-weight: 600;
  font-size: clamp(34px, 4.6vw, 52px);
  color: var(--neon-magenta);
  text-shadow: 0 0 26px rgba(214, 46, 140, 0.45);
  margin-bottom: 12px; line-height: 1.1;
}
.bar__text p { color: var(--ink-inverse-dim); }
.bar__features { display: grid; gap: 12px; margin: 26px 0 0; padding: 0; list-style: none; }
.bar__features li { display: flex; align-items: center; gap: 12px; font-size: 15px; }
.bar__features svg { width: 18px; height: 18px; color: var(--neon-magenta); flex: none; }
.bar__shelf { margin: 18px 0 0; border-radius: var(--radius); overflow: hidden; opacity: 0.92; }

/* --- visit (hours & location) ------------------------------------------------ */
.visit__card {
  background: var(--bg-dark); color: var(--ink-inverse);
  border-radius: var(--radius);
  padding: 56px;
  display: grid; grid-template-columns: 5fr 4fr 5fr; gap: 44px;
  align-items: start;
}
.visit__card .eyebrow { color: var(--ink-inverse-dim); }
.visit__card h2 { color: var(--ink-inverse); font-size: clamp(26px, 3vw, 36px); }
.info-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; }
.info-row { display: flex; gap: 14px; }
.info-row__icon { color: var(--gold); flex: none; margin-top: 3px; }
.info-row__icon svg { width: 19px; height: 19px; }
.info-row__label {
  display: block; font-family: var(--sans); font-size: 12px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-inverse-dim);
  margin-bottom: 3px;
}
.info-row__value { font-size: 15px; }
.info-row__value a { color: var(--ink-inverse); text-decoration-color: var(--gold); }
.visit__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.visit__map { border-radius: var(--radius); overflow: hidden; min-height: 300px; }
.visit__map iframe { width: 100%; height: 100%; min-height: 300px; border: 0; display: block; }
/* Same reservation as .bar__media — poster and clip are both 3:4 and the box
   is fixed before either loads, so scroll-in playback cannot reflow the card. */
.visit__photo {
  position: relative; border-radius: var(--radius); overflow: hidden;
  aspect-ratio: 3 / 4; background: var(--bg-dark);
}
.visit__photo video, .visit__photo img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.visit__photo img { display: none; } /* fallback — shown only when the clip is hidden */

/* --- responsible gambling ------------------------------------------------------ */
.responsible { background: rgba(107, 63, 160, 0.07); }
.responsible__grid { display: grid; grid-template-columns: 5fr 7fr; gap: 56px; }
.responsible h2 { color: var(--neon-violet); }
.rg-note {
  border-left: 3px solid var(--neon-violet);
  padding: 14px 20px; font-size: 15px; color: var(--ink-soft);
  background: rgba(243, 239, 230, 0.7); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.rg-list { margin: 0; padding-left: 20px; display: grid; gap: 8px; font-size: 15px; color: var(--ink-soft); }
.rg-help { display: flex; flex-direction: column; gap: 8px; font-size: 15px; }
.rg-help a { color: var(--neon-violet); font-weight: 500; }
.responsible__col + .responsible__col { margin-top: 30px; }

/* --- footer -------------------------------------------------------------------- */
.rug-strip {
  height: 5px;
  background: linear-gradient(90deg,
    var(--rug-blue) 0 22%, var(--rug-coral) 22% 40%, var(--rug-ochre) 40% 58%,
    var(--rug-blue) 58% 76%, var(--rug-coral) 76% 100%);
}
.site-footer { background: var(--bg-dark); color: var(--ink-inverse-dim); padding: 72px 0 36px; font-size: 15px; }
.footer-top {
  display: grid; grid-template-columns: 5fr 3fr 4fr; gap: 44px;
  padding-bottom: 44px; border-bottom: var(--hairline-inverse);
}
.site-footer .brand__block { color: var(--ink-inverse); font-size: 17px; }
.footer-about p { margin-top: 16px; max-width: 44ch; }
.footer-col h4 {
  font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-inverse); margin-bottom: 16px;
}
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.footer-col a { text-decoration: none; }
.footer-col a:hover { color: var(--gold); }
.footer-social { display: flex; gap: 14px; margin-top: 18px; }
.footer-social a { color: var(--ink-inverse-dim); }
.footer-social a:hover { color: var(--gold); }
.footer-social svg { width: 20px; height: 20px; }
.footer-rg {
  display: flex; align-items: center; gap: 14px;
  margin: 32px 0 14px; color: var(--ink-inverse);
}
.footer-rg .trust-badge { border-color: var(--ink-inverse); }
.license-line { font-size: 13px; opacity: 0.75; max-width: 74ch; }
.footer-bottom {
  display: flex; flex-wrap: wrap; gap: 12px 28px; justify-content: space-between;
  margin-top: 28px; padding-top: 24px; border-top: var(--hairline-inverse);
  font-size: 13px;
}
.footer-legal { display: flex; gap: 22px; }
.footer-legal a { text-decoration: none; }
.footer-legal a:hover { color: var(--gold); }
.footer-meta { margin: 0; }

/* --- age gate -------------------------------------------------------------------- */
.age-gate {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(26, 18, 48, 0.92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.age-gate[hidden] { display: none; }
.age-gate__card {
  background: var(--bg-base); color: var(--ink);
  border-radius: var(--radius); border-top: 4px solid var(--gold);
  max-width: 480px; padding: 44px 40px; text-align: center;
}
.age-gate__card h2 { font-size: 26px; }
.age-gate__sub { color: var(--ink-soft); font-size: 15px; }
.age-gate__actions { display: flex; gap: 12px; justify-content: center; margin-top: 26px; flex-wrap: wrap; }
.age-gate__no {
  background: none; border: 0; color: var(--ink-soft);
  font-family: var(--sans); font-size: 14px; cursor: pointer; text-decoration: underline;
}
.age-gate.blocked .age-gate__actions { display: none; }

/* --- legal pages ------------------------------------------------------------------ */
.legal-body { color: var(--ink-soft); font-size: 16px; line-height: 1.7; }
.legal-body h2 { font-size: 22px; margin-top: 1.6em; color: var(--ink); }
.legal-body a { color: var(--neon-violet); }

/* --- reveal ------------------------------------------------------------------------ */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.7s ease, transform 0.7s ease; }
.reveal[data-d="2"] { transition-delay: 0.1s; }
.reveal[data-d="3"] { transition-delay: 0.2s; }
.reveal.in { opacity: 1; transform: none; }

/* --- reduced motion ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .game-card__media img, .game-card__media video { transition: none; }
  video[data-motion] { display: none; }  /* posters take over */
  .bar__media img { display: block; }
  .visit__photo img { display: block; }
  /* hero 3D scroll off — flat, exactly the pre-parallax composition */
  .hero { perspective: none; }
  .hero__media, .hero__inner,
  .hero__kicker, .hero__lockup, .hero__tagline, .hero__cta { transform: none; }
  .hero__inner { opacity: 1; }
  .hero__scrim::after { opacity: 0; }
}

/* --- breakpoints: 1440 is the container cap; 1024 / 768 / 375 below ------------------ */
@media (max-width: 1024px) {
  .section { padding: 72px 0; }
  .floor__grid, .bar__grid, .responsible__grid { grid-template-columns: 1fr; gap: 36px; }
  .visit__card { grid-template-columns: 1fr 1fr; padding: 40px; }
  .visit__photo { display: none; }
  .gallery-strip { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 768px) {
  body { font-size: 16px; }
  .nav {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; gap: 0;
    background: rgba(243, 239, 230, 0.98); color: var(--ink);
    border-bottom: var(--hairline-gold);
    padding: 12px 24px 20px;
  }
  .nav.open { display: flex; }
  .nav a { padding: 13px 2px; border-bottom: var(--hairline-light); }
  .nav-toggle { display: block; }
  .header-call span { display: none; }
  .bento { grid-template-columns: 1fr; grid-auto-rows: 260px; }
  .game-card--tall { grid-row: span 1; }
  .game-card--tall.game-card--video { grid-row: span 2; } /* keep video tiles roomy */
  /* One column here, so a single 260px row is already ~4:3 and the room shot
     fits almost exactly. Keeping the desktop two-row span would make the box
     portrait and crop the photo's width in half instead. */
  .game-card--feature { grid-row: span 1; }
  .game-card--feature .game-card__media img { object-position: center 50%; }
  .visit__card { grid-template-columns: 1fr; padding: 32px 24px; }
  .gallery-strip { grid-template-columns: repeat(2, 1fr); }
  .gallery-strip figure:nth-child(2n) { transform: none; }
  .hero__inner { padding-bottom: 72px; }
  .section { padding: 60px 0; }
  .rug-divider { height: 60px; }
  .footer-top { grid-template-columns: 1fr; gap: 32px; }
}

@media (max-width: 480px) {
  .container { padding: 0 18px; }
  .header-inner { gap: 14px; }
  .header-call { display: none; }
  .trust-bar__inner { gap: 10px 20px; font-size: 13px; }
  .hero__lockup .block { letter-spacing: 0.14em; text-indent: 0.14em; }
  .visit__actions .btn { width: 100%; justify-content: center; }
}

/* ==========================================================================
   GAMES SHOWCASE — full-bleed equipment carousel between trust bar and bento
   Three product renders occupy centre / left / right slots. Roles live in
   data-role on each figure and every dimension of the move is expressed
   here, so the JS only ever relabels roles — the feel is tuned in one place.
   Section colour rides on --sc-bg, which the controller rewrites; because
   background-color resolves through that custom property it still animates.
   ========================================================================== */
.showcase {
  position: relative;
  overflow: hidden;
  height: 100svh;
  min-height: 620px;
  isolation: isolate;
  color: var(--ink-inverse);
  background-color: var(--sc-bg, var(--neon-violet));
  transition: background-color 650ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* film grain, matching the density used on the hero scrim */
.showcase::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 50;
  pointer-events: none;
  opacity: 0.4;
  background-repeat: repeat;
  background-size: 200px 200px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.08'/%3E%3C/svg%3E");
}

/* Oversized ghost word the renders overlap. Poppins 700 rather than a fourth
   webfont family loaded for a single word. */
.showcase__ghost {
  position: absolute;
  inset-inline: 0;
  top: 16%;
  z-index: 2;
  margin: 0;
  text-align: center;
  white-space: nowrap;
  user-select: none;
  pointer-events: none;
  font-family: var(--sans);
  font-weight: 700;
  font-size: clamp(72px, 20vw, 320px);
  line-height: 1;
  letter-spacing: -0.04em;
  text-transform: uppercase;
  color: var(--ink-inverse);
}

.showcase__stage { position: absolute; inset: 0; z-index: 3; }

/* The centre slot is height:92% scaled 1.68 about its own centre, so the
   rendered box runs from -0.313 to 1.233 of the section height. The renders
   carry matching transparent padding — see hero-royale/README.md — which is
   what keeps the object inside the visible band at that scale. */
.showcase__item {
  position: absolute;
  margin: 0;
  aspect-ratio: 0.6 / 1;
  will-change: transform, filter, opacity;
  transition:
    transform 650ms cubic-bezier(0.4, 0, 0.2, 1),
    filter    650ms cubic-bezier(0.4, 0, 0.2, 1),
    opacity   650ms cubic-bezier(0.4, 0, 0.2, 1),
    left      650ms cubic-bezier(0.4, 0, 0.2, 1),
    bottom    650ms cubic-bezier(0.4, 0, 0.2, 1),
    height    650ms cubic-bezier(0.4, 0, 0.2, 1);
}
.showcase__item img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: bottom center;
}

.showcase__item[data-role="center"] {
  left: 50%; bottom: 0; height: 92%;
  transform: translateX(-50%) scale(1.68);
  filter: none; opacity: 1; z-index: 20;
}
.showcase__item[data-role="left"],
.showcase__item[data-role="right"] {
  bottom: 12%; height: 28%;
  transform: translateX(-50%) scale(1);
  filter: blur(2px); opacity: 0.85; z-index: 10;
}
.showcase__item[data-role="left"]  { left: 30%; }
.showcase__item[data-role="right"] { left: 70%; }
.showcase__item[data-role="back"] {
  left: 50%; bottom: 12%; height: 22%;
  transform: translateX(-50%) scale(1);
  filter: blur(4px); opacity: 1; z-index: 5;
}

.showcase__panel {
  position: absolute;
  left: clamp(18px, 5vw, 96px);
  bottom: clamp(24px, 6vh, 80px);
  z-index: 60;
  max-width: 340px;
}
.showcase__slide-copy[hidden] { display: none; }
.showcase__copy h2 {
  margin: 0 0 0.5em;
  font-size: clamp(19px, 2.2vw, 26px);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--ink-inverse);
}
.showcase__copy p {
  margin: 0 0 1.3em;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink-inverse-dim);
}

.showcase__nav { display: flex; gap: 12px; }
.showcase__btn {
  width: 60px; height: 60px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  border: 2px solid rgba(248, 245, 238, 0.9);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-inverse);
  cursor: pointer;
  transition: transform 150ms, background-color 150ms;
}
.showcase__btn svg { width: 24px; height: 24px; }
.showcase__btn:hover { transform: scale(1.08); background-color: rgba(248, 245, 238, 0.14); }
.showcase__btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

.showcase__cta {
  position: absolute;
  right: clamp(18px, 4vw, 64px);
  bottom: clamp(24px, 6vh, 80px);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  font-family: var(--sans);
  font-weight: 700;
  font-size: clamp(17px, 2.6vw, 40px);
  line-height: 1;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-inverse);
  opacity: 0.95;
  transition: opacity 200ms;
}
.showcase__cta:hover { opacity: 1; }
.showcase__cta svg { width: 0.7em; height: 0.7em; }
.showcase__cta:focus-visible { outline: 2px solid var(--gold); outline-offset: 4px; }

@media (max-width: 900px) {
  .showcase__cta { font-size: clamp(16px, 4vw, 26px); }
}

@media (max-width: 639px) {
  .showcase { min-height: 560px; }
  .showcase__ghost { top: 14%; font-size: clamp(60px, 24vw, 150px); }
  .showcase__item[data-role="center"] {
    height: 60%; bottom: 22%;
    transform: translateX(-50%) scale(1.25);
  }
  .showcase__item[data-role="left"],
  .showcase__item[data-role="right"] { height: 16%; bottom: 32%; }
  .showcase__item[data-role="left"]  { left: 20%; }
  .showcase__item[data-role="right"] { left: 80%; }
  .showcase__copy p { display: none; }
  .showcase__btn { width: 48px; height: 48px; }
  .showcase__btn svg { width: 20px; height: 20px; }
}

/* Reduced motion: the carousel still works, it just cuts between states. */
@media (prefers-reduced-motion: reduce) {
  .showcase,
  .showcase__item,
  .showcase__btn,
  .showcase__cta { transition: none; }
}

/* ==========================================================================
   SPOTLIGHT HERO — two plates of one table, revealed by a pointer-following
   light. Port of ../hero-spotlight.

   The mask is declared here as a radial-gradient driven by --sx/--sy, so the
   controller's only per-frame job is writing two custom properties. The
   earlier canvas approach (draw gradient, toDataURL, hand the PNG to
   mask-image) cost ~9.2ms of main thread and a ~290KB data URI per frame at
   desktop sizes — for the identical result.
   ========================================================================== */
.hero-spot {
  position: relative;
  height: 100svh;
  min-height: 600px;
  overflow: hidden;
  isolation: isolate;
  background: #05070A;
  color: var(--ink-inverse);
}

.hero-spot__base,
.hero-spot__reveal {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  pointer-events: none;
}
/* Hand-off to the cardfall below. The photo used to stop dead against the
   next section's violet, which read as a hard horizontal seam; this fades the
   plate down to the hero's own base colour, and the cardfall starts from that
   same value, so the two sections meet on one colour instead of an edge.
   z-index 3 keeps it above the photo layers (1, 2) and below the copy (5). */
.hero-spot::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 38%;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(5, 7, 10, 0) 0%,
    rgba(5, 7, 10, 0.45) 42%,
    rgba(5, 7, 10, 0.85) 74%,
    #05070A 100%
  );
}

.hero-spot__base { z-index: 1; background-image: url("img/hero/table-dark.webp"); }
.hero-spot__reveal {
  z-index: 2;
  background-image: url("img/hero/table-lit.webp");
  --sr: 260px;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-image: radial-gradient(circle var(--sr) at var(--sx, -999px) var(--sy, -999px),
    rgba(0,0,0,1) 0%, rgba(0,0,0,1) 40%, rgba(0,0,0,.75) 60%,
    rgba(0,0,0,.4) 75%, rgba(0,0,0,.12) 88%, rgba(0,0,0,0) 100%);
  mask-image: radial-gradient(circle var(--sr) at var(--sx, -999px) var(--sy, -999px),
    rgba(0,0,0,1) 0%, rgba(0,0,0,1) 40%, rgba(0,0,0,.75) 60%,
    rgba(0,0,0,.4) 75%, rgba(0,0,0,.12) 88%, rgba(0,0,0,0) 100%);
}

.hero-spot__head {
  position: absolute;
  top: 14%;
  left: 0;
  right: 0;
  z-index: 5;
  padding: 0 20px;
  text-align: center;
  pointer-events: none;
}
.hero-spot__kicker {
  margin: 0 0 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(248, 245, 238, 0.75);
}
.hero-spot__lockup { margin: 0; line-height: 0.95; }
.hero-spot__lockup .script,
.hero-spot__lockup .block { display: block; }
.hero-spot__lockup .script {
  font-family: var(--script);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(44px, 8.5vw, 116px);
  letter-spacing: -0.03em;
}
.hero-spot__lockup .block {
  margin-top: -0.06em;
  font-family: var(--sans);
  font-weight: 600;
  font-size: clamp(44px, 8.5vw, 116px);
  letter-spacing: -0.05em;
}

.hero-spot__left {
  position: absolute;
  bottom: 56px;
  left: clamp(20px, 4vw, 56px);
  z-index: 5;
  max-width: 280px;
}
.hero-spot__left p {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.6;
  color: rgba(248, 245, 238, 0.8);
}

.hero-spot__right {
  position: absolute;
  bottom: 40px;
  left: 20px;
  right: 20px;
  z-index: 5;
}
.hero-spot__right p {
  margin: 0 0 18px;
  font-size: 0.9rem;
  line-height: 1.6;
  color: rgba(248, 245, 238, 0.8);
}
.hero-spot__cta { display: flex; flex-wrap: wrap; gap: 12px; }

@media (min-width: 641px) {
  .hero-spot__right {
    left: auto;
    right: clamp(20px, 4vw, 56px);
    bottom: 84px;
    max-width: 300px;
  }
}
@media (max-width: 640px) {
  .hero-spot__left { display: none; }
  .hero-spot__reveal { --sr: 170px; }
  .hero-spot__head { top: 12%; }
  .hero-spot__cta .btn { flex: 1 1 auto; justify-content: center; }
}

/* Entry choreography — mirrors the prototype's timing. */
@keyframes heroReveal {
  0% { opacity: 0; transform: translateY(28px); filter: blur(12px); }
  100% { opacity: 1; transform: translateY(0); filter: blur(0); }
}
@keyframes heroFadeUp {
  0% { opacity: 0; transform: translateY(20px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes heroZoom {
  0% { transform: scale(1.12); }
  100% { transform: scale(1); }
}
.hero-anim {
  opacity: 0;
  animation-fill-mode: forwards;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.hero-reveal { animation-name: heroReveal; animation-duration: 1.1s; }
.hero-fade { animation-name: heroFadeUp; animation-duration: 1s; }
.hero-spot__zoom { animation: heroZoom 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards; }

@media (prefers-reduced-motion: reduce) {
  .hero-anim, .hero-spot__zoom { animation: none; opacity: 1; }
}

/* ==========================================================================
   ROULETTE SIMULATOR — dark felt panel on the light section ground
   Free demo: no stakes, no balance, nothing to win. The wheel is drawn as
   SVG sectors at build time from one pocket-order list, so the graphic and
   the win check cannot drift apart.
   ========================================================================== */
.roul {
  display: grid;
  grid-template-columns: minmax(280px, 440px) 1fr;
  gap: clamp(28px, 5vw, 64px);
  align-items: center;
  padding: clamp(28px, 4vw, 56px);
  border-radius: 18px;
  background: radial-gradient(120% 120% at 20% 0%, #2A1F45 0%, var(--bg-dark) 60%);
  color: var(--ink-inverse);
  border: var(--hairline-inverse);
}

.roul__stage { position: relative; width: 100%; aspect-ratio: 1; margin: 0 auto; }
.roul__svg { width: 100%; height: 100%; display: block; }
.roul__flat { position: absolute; inset: 0; }

/* The WebGL bowl mounts here and, once it reports a live context, the script
   sets .is-3d on .roul — which retires the flat wheel and shows the drag hint.
   Until then (no WebGL, reduced motion, script never runs) the SVG plays. */
.roul__gl { position: absolute; inset: 0; display: none; touch-action: pan-y; }
.roul.is-3d .roul__flat { display: none; }
.roul.is-3d .roul__gl { display: block; }

.roul__wheelcol { min-width: 0; }
.roul__drag {
  margin: 14px 0 0;
  text-align: center;
  font-size: 0.8rem;
  color: var(--ink-inverse-dim);
}

/* Rotating the wheel by -index*(360/37) brings that pocket under the pointer. */
.roul__wheel {
  width: 100%;
  height: 100%;
  transform: rotate(0deg);
  will-change: transform;
  transition: transform 5s cubic-bezier(0.12, 0.68, 0.1, 1);
}

/* The ball rides its own layer, orbiting the other way and coming to rest at
   the top — which is where the winning pocket has just arrived. */
.roul__orbit {
  position: absolute;
  inset: 0;
  transform: rotate(0deg);
  will-change: transform;
  transition: transform 5s cubic-bezier(0.15, 0.72, 0.12, 1);
}
.roul__ball {
  position: absolute;
  top: 5.5%;
  left: 50%;
  width: 4.4%;
  aspect-ratio: 1;
  margin-left: -2.2%;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, #fff 0%, #E6E1D5 45%, #A8A296 100%);
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.55);
}

.roul__pointer {
  position: absolute;
  top: -2px;
  left: 50%;
  z-index: 3;
  width: 0;
  height: 0;
  margin-left: -11px;
  border-left: 11px solid transparent;
  border-right: 11px solid transparent;
  border-top: 20px solid var(--gold);
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.5));
}

.roul__panel { min-width: 0; }
.roul__lead {
  margin: 0 0 22px;
  color: var(--ink-inverse-dim);
  font-size: 1rem;
  line-height: 1.65;
}

.roul__bets { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 22px; }
.roul__bet {
  padding: 10px 18px;
  border-radius: 999px;
  border: 1px solid rgba(248, 245, 238, 0.28);
  background: rgba(248, 245, 238, 0.06);
  color: var(--ink-inverse);
  font-family: var(--sans);
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 150ms, border-color 150ms, transform 150ms;
}
.roul__bet:hover { background: rgba(248, 245, 238, 0.14); transform: translateY(-1px); }
.roul__bet:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.roul__bet[aria-pressed="true"] {
  background: var(--gold);
  border-color: var(--gold);
  color: #201802;
  font-weight: 600;
}

.roul__spin { margin-bottom: 20px; }
/* aria-disabled, not disabled — see the note in site-neon.js. The button keeps
   focus and stays in the tab order while the ball is running. */
.roul__spin[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }

.roul__result {
  margin: 0 0 6px;
  min-height: 1.6em;
  font-family: var(--sans);
  font-size: 1.05rem;
  font-weight: 600;
}
.roul__result .num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2em;
  padding: 0.15em 0.45em;
  margin-right: 0.5em;
  border-radius: 6px;
  font-variant-numeric: tabular-nums;
}
.num--red { background: #A81E32; }
.num--black { background: #141118; border: 1px solid rgba(248, 245, 238, 0.25); }
.num--green { background: #1F7A4D; }

.roul__tally { margin: 0 0 18px; font-size: 0.85rem; color: var(--ink-inverse-dim); }

.roul__history { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; }
.roul__history-label {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 245, 238, 0.55);
}
.roul__history-list { display: flex; gap: 6px; flex-wrap: wrap; }
.roul__history-list .num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.9em;
  padding: 0.1em 0.35em;
  border-radius: 5px;
  font-size: 0.8rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.roul__note {
  margin: 0;
  padding-top: 16px;
  border-top: var(--hairline-inverse);
  font-size: 0.78rem;
  line-height: 1.5;
  color: rgba(248, 245, 238, 0.6);
}

@media (max-width: 860px) {
  .roul { grid-template-columns: 1fr; }
  .roul__stage { max-width: 380px; }
}
@media (max-width: 480px) {
  .roul__spin { width: 100%; justify-content: center; }
}

/* The wheel still resolves a number and reports it; it just stops turning. */
@media (prefers-reduced-motion: reduce) {
  .roul__wheel,
  .roul__orbit,
  .roul__bet { transition: none; }
}

/* ==========================================================================
   CARDFALL — scroll-scrubbed field of levitating cards
   A tall section with a sticky viewport-height stage. Scroll position inside
   the section drives the scene; see the cardfall block in site-neon.js.
   ========================================================================== */
.cardfall {
  position: relative;
  height: 240vh;                 /* the scrub distance — not visible height */
  background: var(--bg-dark);
}
/* The gradient lives on the sticky child, not the section. Two reasons: on a
   240vh box the bloom would stretch over the whole scroll and never be seen,
   and the sticky's top edge is exactly where the hero ends — so starting it
   on the hero's own #05070A is what makes the seam disappear. Once pinned it
   reads as a vignette, which suits the falling cards. */
.cardfall__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: grid;
  place-items: center;
  background:
    radial-gradient(115% 80% at 50% 58%, #322455 0%, rgba(50, 36, 85, 0) 72%),
    /* The hero's darks are cool — the blue rim light off the felt — so the
       first stops stay blue-black and only then warm into the house violet.
       Jumping straight to violet is what made the two sections read as two
       different palettes butted together. */
    linear-gradient(to bottom,
      #05070A 0%,
      #070C16 11%,
      #0C0A1C 24%,
      #140E28 42%,
      var(--bg-dark) 66%,
      var(--bg-dark) 100%);
}
@supports (height: 100svh) {
  .cardfall__sticky { height: 100svh; }
}
.cardfall__gl { position: absolute; inset: 0; }
.cardfall__copy {
  position: relative;
  z-index: 1;
  text-align: center;
  padding: clamp(28px, 5vw, 56px) clamp(20px, 5vw, 48px);
  color: var(--ink-inverse);
  pointer-events: none;
}
/* Near-white card faces drift straight behind near-white display type. This
   scrim keeps the line readable whatever passes under it, without putting an
   opaque slab on the scene. */
.cardfall__copy::before {
  content: "";
  position: absolute;
  inset: -8% -6%;
  z-index: -1;
  background: radial-gradient(60% 60% at 50% 50%, rgba(16, 10, 28, 0.82) 0%, rgba(16, 10, 28, 0.55) 45%, transparent 78%);
}
/* The section's own ground is dark, so the eyebrow takes gold rather than the
   violet it wears on the light marble sections. */
.cardfall__copy .eyebrow { color: var(--gold); }
.cardfall__line {
  margin: 0;
  font-family: var(--script);
  font-style: italic;
  font-size: clamp(2.2rem, 7vw, 4.6rem);
  line-height: 1.04;
  letter-spacing: -0.01em;
  text-shadow: 0 6px 28px rgba(10, 6, 18, 0.75);
}
.cardfall__line--2 { color: var(--gold); }
.cardfall__sub {
  margin: 26px 0 0;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-inverse-dim);
  text-shadow: 0 2px 12px rgba(10, 6, 18, 0.8);
}

/* The tall height is the DEFAULT, not something JS grows into. Gating it on a
   class added after a dynamic import meant the common path — module loads
   fine — was the path that reflowed: the section gained 1.4 screens under a
   visitor who was already inside it. It is only collapsed when we know at
   paint (media query) or synchronously at script time (.is-flat, set before
   the visitor can scroll this far) that there will be no cards at all. */
.cardfall.is-flat { height: 100vh; }
@supports (height: 100svh) {
  .cardfall.is-flat { height: 100svh; }
}
@media (prefers-reduced-motion: reduce) {
  .cardfall { height: 100vh; }
  .cardfall__sticky { position: relative; }
}

/* The instruction only makes sense when something is actually falling. */
.cardfall__sub { visibility: hidden; }
.cardfall.is-live .cardfall__sub { visibility: visible; }

/* ==========================================================================
   BLACKJACK — same dark felt panel as the roulette, same no-stakes rule
   ========================================================================== */
.bj {
  display: grid;
  grid-template-columns: 1fr minmax(280px, 420px);
  gap: clamp(28px, 5vw, 64px);
  align-items: center;
  padding: clamp(28px, 4vw, 56px);
  border-radius: 18px;
  background: radial-gradient(120% 120% at 80% 0%, #2A1F45 0%, var(--bg-dark) 60%);
  color: var(--ink-inverse);
  border: var(--hairline-inverse);
}

.bj__felt {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(20px, 4vw, 36px);
  padding: clamp(20px, 3vw, 32px);
  border-radius: 14px;
  /* Table baize, kept deep rather than bright — this is a floor, not a felt swatch. */
  background:
    radial-gradient(90% 120% at 50% 0%, rgba(255, 255, 255, 0.06) 0%, transparent 60%),
    linear-gradient(180deg, #123829 0%, #0C271C 100%);
  border: 1px solid rgba(201, 162, 39, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.bj__tablecol { min-width: 0; }
.bj__row { min-width: 0; }
/* Lives outside the felt so it survives the swap to the 3D table. */
.bj__scores {
  display: flex;
  justify-content: center;
  gap: clamp(20px, 5vw, 44px);
  margin: 14px 0 0;
}
.bj__score { display: inline-flex; align-items: center; gap: 9px; }
.bj__who {
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(248, 245, 238, 0.62);
}
.bj__total {
  min-width: 30px;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(248, 245, 238, 0.12);
  border: 1px solid rgba(248, 245, 238, 0.2);
  font-size: 0.78rem;
  font-weight: 600;
  text-align: center;
}
.bj__hand {
  display: flex;
  gap: 10px;
  min-height: 104px;
  flex-wrap: wrap;
}

/* --- the cards --- */
.bjcard {
  width: 72px;
  aspect-ratio: 5 / 7;
  perspective: 700px;
  /* --i is the card's position in the hand; it staggers the deal. */
  animation: bj-deal 420ms cubic-bezier(0.16, 0.82, 0.24, 1) backwards;
  animation-delay: calc(var(--i, 0) * 110ms);
}
.bjcard__inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 480ms cubic-bezier(0.3, 0.7, 0.2, 1);
}
.bjcard.is-down .bjcard__inner { transform: rotateY(180deg); }

.bjcard__face,
.bjcard__back {
  position: absolute;
  inset: 0;
  border-radius: 7px;
  backface-visibility: hidden;
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.45);
}
.bjcard__face {
  background: linear-gradient(160deg, #FFFDF8 0%, #F2EDE2 100%);
  border: 1px solid rgba(20, 17, 24, 0.18);
  color: #141118;
}
.bjcard__face.is-red { color: #B01E33; }
.bjcard__back {
  transform: rotateY(180deg);
  background:
    repeating-linear-gradient(45deg, rgba(201, 162, 39, 0.22) 0 2px, transparent 2px 7px),
    repeating-linear-gradient(-45deg, rgba(201, 162, 39, 0.22) 0 2px, transparent 2px 7px),
    linear-gradient(160deg, #34255A 0%, #221639 100%);
  border: 1px solid rgba(201, 162, 39, 0.5);
  box-shadow: inset 0 0 0 3px rgba(201, 162, 39, 0.35), 0 6px 14px rgba(0, 0, 0, 0.45);
}

.bjcard__corner {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
  font-size: 0.72rem;
  font-weight: 600;
}
.bjcard__corner i { font-style: normal; font-size: 0.66rem; margin-top: 1px; }
.bjcard__corner--tl { top: 5px; left: 5px; }
.bjcard__corner--br { bottom: 5px; right: 5px; transform: rotate(180deg); }
.bjcard__pip {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 1.85rem;
  opacity: 0.92;
}

@keyframes bj-deal {
  from { opacity: 0; transform: translate(38px, -26px) rotate(9deg) scale(0.94); }
  to   { opacity: 1; transform: none; }
}

/* --- panel --- */
.bj__panel { min-width: 0; }
.bj__lead {
  margin: 0 0 22px;
  color: var(--ink-inverse-dim);
  font-size: 1rem;
  line-height: 1.65;
}
.bj__actions { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; }
.bj__btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.bj__btn--ghost {
  background: rgba(248, 245, 238, 0.1);
  border: 1px solid rgba(248, 245, 238, 0.24);
  color: var(--ink-inverse);
}
.bj__btn--ghost:hover { background: rgba(248, 245, 238, 0.18); }
.bj__btn--ghost[aria-disabled="true"]:hover { background: rgba(248, 245, 238, 0.1); }
.bj__result {
  min-height: 2.4em;
  margin: 0 0 14px;
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.5;
}
.bj__tally { margin: 0 0 18px; font-size: 0.85rem; color: var(--ink-inverse-dim); }
.bj__note {
  margin: 0;
  padding-top: 16px;
  border-top: var(--hairline-inverse);
  font-size: 0.78rem;
  line-height: 1.5;
  color: rgba(248, 245, 238, 0.6);
}

@media (max-width: 860px) {
  .bj { grid-template-columns: 1fr; }
  .bj__felt { order: -1; }
}
@media (max-width: 480px) {
  .bjcard { width: 58px; }
  .bjcard__pip { font-size: 1.45rem; }
  .bj__hand { min-height: 84px; }
  .bj__actions .bj__btn { flex: 1 1 auto; justify-content: center; }
}

/* The hand still deals and still reports; the cards just appear in place. */
@media (prefers-reduced-motion: reduce) {
  .bjcard { animation: none; }
  .bjcard__inner { transition: none; }
}

/* ==========================================================================
   3D CARD TABLES — blackjack and poker
   The DOM felt is the baseline and stays playable on its own. When table3d.js
   reports a WebGL context the section gets .is-3d, which retires the flat
   felt and shows the canvas in the same box. Same contract as the roulette.
   ========================================================================== */
.bj__stage,
.pk__stage {
  position: relative;
  min-width: 0;
  border-radius: 14px;
  overflow: hidden;
}
.bj__gl,
.pk__gl {
  display: none;
  width: 100%;
  aspect-ratio: 4 / 3;
  /* The page keeps the vertical axis so a finger can still scroll past the
     table; the module only reads horizontal drag on touch. */
  touch-action: pan-y;
}
.bj.is-3d .bj__felt,
.pk.is-3d .pk__felt { display: none; }
.bj.is-3d .bj__gl,
.pk.is-3d .pk__gl { display: block; }

/* ==========================================================================
   POKER — five-card draw, same felt panel and same no-stakes rule
   ========================================================================== */
.pk {
  display: grid;
  grid-template-columns: 1fr minmax(280px, 420px);
  gap: clamp(28px, 5vw, 64px);
  align-items: center;
  padding: clamp(28px, 4vw, 56px);
  border-radius: 18px;
  background: radial-gradient(120% 120% at 20% 0%, #2A1F45 0%, var(--bg-dark) 60%);
  color: var(--ink-inverse);
  border: var(--hairline-inverse);
}
.pk__tablecol { min-width: 0; }
.pk__felt {
  padding: clamp(20px, 3vw, 32px);
  border-radius: 14px;
  background:
    radial-gradient(90% 120% at 50% 0%, rgba(255, 255, 255, 0.06) 0%, transparent 60%),
    linear-gradient(180deg, #123829 0%, #0C271C 100%);
  border: 1px solid rgba(201, 162, 39, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.pk__hand { justify-content: center; }

/* A held card lifts and takes a gold edge, so the choice reads on the card
   itself and not only on the button below it. */
.bjcard.is-held .bjcard__inner { transform: translateY(-10px); }
.bjcard.is-held .bjcard__face {
  border-color: var(--gold);
  box-shadow: 0 10px 18px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(201, 162, 39, 0.75);
}

.pk__holds {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin-top: 16px;
}
.pk__hold {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 8px 4px;
  border-radius: 10px;
  border: 1px solid rgba(248, 245, 238, 0.22);
  background: rgba(248, 245, 238, 0.08);
  color: var(--ink-inverse);
  font-family: var(--sans);
  font-size: 0.72rem;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
.pk__hold:hover { background: rgba(248, 245, 238, 0.16); }
.pk__hold:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.pk__hold.is-on {
  background: rgba(201, 162, 39, 0.9);
  border-color: var(--gold);
  color: #1A1420;
  transform: translateY(-2px);
}
.pk__hold[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; }
.pk__hold[aria-disabled="true"]:hover { background: rgba(248, 245, 238, 0.08); }
.pk__holdslot {
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  opacity: 0.7;
}
.pk__panel { min-width: 0; }

@media (max-width: 860px) {
  .pk { grid-template-columns: 1fr; }
  .pk__tablecol { order: -1; }
}
@media (max-width: 480px) {
  .pk__hold { font-size: 0.62rem; padding: 7px 2px; }
  .pk__holdtxt { display: none; }   /* the number and the gold state carry it */
}
