/* AUTO-GENERATED by propagate_theme.write_chrome_css_file — DO NOT EDIT BY HAND. */
/* Edit source CSS in project's index.html (chrome rules) then re-run propagate. */

:root {
  --primary-color: #FFD700;
  --accent-color: #FF4500;
  --background-dark: #140F05;
  --background-card: #221A0F;
  --text-primary: #FFFFFF;
  --text-secondary: #C0B4A2;
  --gradient-from: #FFD700;
  --gradient-to: #FF4500;
  --glow-color: #FFD700;
  --font-display: 'Montserrat', sans-serif;
  --font-body: 'Lato', sans-serif;
  --border-radius: 8px;
  --transition-slide: 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --primary_color: #E2B33C !important;
  --accent_color: #D93025 !important;
  --background_dark: #120F0A !important;
  --background_card: #1F1A14 !important;
  --text_primary: #FFFFFF !important;
  --text_secondary: rgba(255, 255, 255, 0.7) !important;
  --gradient_from: #FFD700 !important;
  --gradient_to: #FF5722 !important;
  --glow_color: #FFC107 !important;
}

.nav-dropdown li { position: relative; }
.nav-dropdown .nav-dropdown {
  top: 0;
  left: 100%;
  margin-left: -1px;
  border-top: 1px solid var(--accent-color, rgba(255,255,255,0.1));
}
.nav-dropdown li:has(> .nav-dropdown) > a {
  padding-right: 2rem;
  position: relative;
}
.nav-dropdown li:has(> .nav-dropdown) > a::after {
  content: "\25b8";
  position: absolute;
  right: 1rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.85em;
  opacity: 0.7;
}
@media (max-width: 768px) {
  .nav-dropdown .nav-dropdown {
    position: static;
    margin-left: 1rem;
    border-top: none;
  }
}

/* === canonical chrome (overrides legacy on conflict) === */
/* === canonical chrome (deterministic, byte-identical across pages) === */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--background-dark, #0a0a0a);
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  max-width: 1280px; margin: 0 auto; padding: 0.75rem 1.5rem;
  gap: 1rem;
}
.site-brand { display: inline-flex; align-items: center; gap: 0.5rem; text-decoration: none; }
.site-brand img, .site-brand .brand-logo img, .brand-logo img {
  display: block; height: auto !important; width: auto !important;
  max-height: 36px !important; max-width: 100% !important; object-fit: contain;
}
.site-brand__text { font-family: var(--font-display, sans-serif); font-weight: 700;
  color: var(--text-primary, #ffffff); font-size: 1.1rem; }

.site-nav { display: flex; align-items: center; gap: 1.25rem; }
.site-nav__list { display: flex; gap: 1rem; list-style: none; margin: 0; padding: 0; }
.site-nav__item { position: relative; }
.site-nav__link {
  display: inline-flex; align-items: center; gap: 0.25rem;
  color: var(--text-primary, #ffffff); text-decoration: none;
  font-weight: 500; padding: 0.5rem 0.25rem; font-size: 0.95rem;
}
.site-nav__link:hover, .site-nav__link:focus { color: var(--accent-color, #00e5ff); }

.nav-dropdown {
  display: none; position: absolute; top: 100%; left: 0;
  background: var(--background-card, #15151d); border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--border-radius, 8px); min-width: 220px;
  padding: 0.5rem; box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  list-style: none; margin: 0;
}
.site-nav__item:hover > .nav-dropdown,
.site-nav__item:focus-within > .nav-dropdown,
.site-nav__item[aria-expanded="true"] > .nav-dropdown { display: block; }
.nav-dropdown a {
  display: block; padding: 0.5rem 0.75rem; color: var(--text-primary, #ffffff);
  text-decoration: none; border-radius: 4px; font-size: 0.9rem;
}
.nav-dropdown a:hover, .nav-dropdown a:focus {
  background: rgba(255,255,255,0.06); color: var(--accent-color, #00e5ff);
}
/* Flat dropdowns (e.g. Promotions) are hard-capped in markup (_render_nav
   trims to _NAV_DD_MAX + a "View All (N) →" row); this max-height is only a
   safety net for legacy/unpatched markup so a long list scrolls instead of
   running past the viewport bottom where items can never be hovered. */
.nav-dropdown { max-height: min(70vh, 560px); overflow-y: auto; }
/* Flat dropdowns also need a WIDTH clamp: with no max-width, one long item
   (e.g. a full promo title) stretches the whole panel arbitrarily wide.
   max-content up to 420px → short menus stay tight, long titles wrap. */
.nav-dropdown:not(:has(.nav-dropdown__group)) {
  width: max-content;
  max-width: min(420px, calc(100vw - 2rem));
}
/* L1→L2 mega-menu: when a dropdown item (L1) carries an L2 sub-list, lay the
   columns side by side so the Games menu reads as category → providers.
   GRID (not flex): auto-fit columns give a predictable 3-4-across panel —
   the earlier flex version collapsed to one narrow clipped column when a
   synced/legacy stylesheet interfered with flex-wrap. Width is CAPPED to the
   viewport; per-column L3 lists are capped in markup (5 + "All X →"), so the
   panel's height is the tallest column, never the sum of all items. */
.nav-dropdown:has(.nav-dropdown__group) {
  display: none;
  min-width: auto;
  width: min(720px, calc(100vw - 2rem));
  max-width: none;
  max-height: none; overflow: visible;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 0.25rem 0.75rem;
  align-items: start;
}
.site-nav__item:hover > .nav-dropdown:has(.nav-dropdown__group),
.site-nav__item:focus-within > .nav-dropdown:has(.nav-dropdown__group),
.site-nav__item[aria-expanded="true"] > .nav-dropdown:has(.nav-dropdown__group) {
  display: grid;
}
.nav-dropdown__group { min-width: 0; }
.nav-viewall > a {
  font-size: 0.8rem; font-weight: 700; opacity: 0.85;
  color: var(--accent-color, #00e5ff);
}
.nav-dropdown__group > a {
  font-weight: 700; opacity: 0.95; cursor: default;
  border-bottom: 1px solid rgba(255,255,255,0.08); border-radius: 0;
}
.nav-subdropdown { list-style: none; margin: 0.25rem 0 0; padding: 0; }
.nav-subdropdown a {
  display: block; padding: 0.4rem 0.75rem; color: var(--text-secondary, #c8c8d0);
  text-decoration: none; border-radius: 4px; font-size: 0.85rem;
}
.nav-subdropdown a:hover, .nav-subdropdown a:focus {
  background: rgba(255,255,255,0.06); color: var(--accent-color, #00e5ff);
}
.nav-caret { font-size: 0.7em; opacity: 0.7; }

.site-header__ctas { display: flex; align-items: center; gap: 0.5rem; }
.site-header__cta-login, .site-header__cta-register {
  display: inline-block; padding: 0.5rem 1rem; border-radius: var(--border-radius, 6px);
  font-weight: 600; text-decoration: none; font-size: 0.9rem; transition: opacity 0.15s;
  text-transform: none; letter-spacing: normal; margin: 0; font-family: inherit; width: auto;
}
.site-header__cta-login { color: var(--text-primary, #fff); border: 1px solid rgba(255,255,255,0.2); }
.site-header__cta-register { color: var(--btn-primary-text, var(--background-dark, #0a0a0a));
  background: var(--accent-color, #00e5ff); }
.site-header__cta-login:hover, .site-header__cta-register:hover { opacity: 0.85; }

.nav-toggle {
  display: none; background: none; border: 0; cursor: pointer; padding: 0.5rem;
  color: var(--text-primary, #ffffff); font-size: 1.5rem; line-height: 1;
}

/* mobile drawer */
/* Canonical mobile drawer. The shared `.mobile-drawer` class can COLLIDE with
   LLM-authored page CSS that also styles `.mobile-drawer` — e.g. a slide-in
   `transform: translateX(100%)` + `width: min(300px,80vw)` toggled by a
   `[data-open]` attribute the canonical JS never sets. That leak shifts the
   overlay off-screen and shrinks it so the menu is CLIPPED / unreachable.
   We defensively reset the layout-critical props with !important so the
   canonical drawer is immune to whatever the page CSS declares. The canonical
   toggle is the `.is-open` class (see the inline JS below). */
.mobile-drawer {
  display: none; position: fixed; inset: 0 !important; z-index: 1000;
  transform: none !important; width: auto !important; max-width: none !important;
  height: auto !important;
}
.mobile-drawer.is-open { display: block !important; }
.mobile-drawer__backdrop {
  position: absolute; inset: 0; background: rgba(0,0,0,0.6);
}
.mobile-drawer__panel {
  position: absolute; top: 0; right: 0; bottom: 0; width: min(320px, 80vw);
  max-width: 90vw; transform: none !important; height: auto;
  background: var(--background-dark, #0a0a0a); padding: 1.5rem 1rem;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  box-shadow: -8px 0 24px rgba(0,0,0,0.4);
}
.mobile-drawer__close {
  display: block; background: none; border: 0; color: var(--text-primary, #fff);
  font-size: 1.75rem; cursor: pointer; margin-left: auto; padding: 0.25rem 0.5rem;
}
.mobile-drawer__list { list-style: none; margin: 1rem 0 0; padding: 0; }
.mobile-drawer__list a {
  display: block; padding: 0.75rem 0.5rem; color: var(--text-primary, #fff);
  text-decoration: none; border-bottom: 1px solid rgba(255,255,255,0.06);
}
.mobile-drawer__list ul {
  list-style: none; margin: 0; padding: 0 0 0.5rem 1rem;
}
.mobile-drawer__list ul a { font-size: 0.9rem; opacity: 0.85; padding: 0.5rem 0.5rem; }

@media (max-width: 880px) {
  .site-nav { display: none; }
  .nav-toggle { display: inline-flex; }
}

/* footer */
.site-footer {
  background: var(--background-dark, #0a0a0a);
  color: var(--text-secondary, #aaa);
  padding: 3rem 1.5rem 1.5rem;
  border-top: 1px solid rgba(255,255,255,0.08);
}
.footer-grid {
  display: grid; gap: 2rem; max-width: 1280px; margin: 0 auto;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.footer-col h3, .footer-col h4 {
  margin: 0 0 0.75rem; font-size: 0.95rem;
  color: var(--text-primary, #fff); font-family: var(--font-display, sans-serif);
}
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin: 0.4rem 0; }
.footer-col a {
  color: var(--text-secondary, #aaa); text-decoration: none; font-size: 0.875rem;
}
.footer-col a:hover { color: var(--accent-color, #00e5ff); }
.footer-brand { grid-column: 1 / -1; }
@media (min-width: 720px) { .footer-brand { grid-column: span 2; } }
/* Footer brand logo — keep natural aspect ratio, shrink proportionally, never
   upscale/stretch. !important + the `.brand-logo img` variant defeat LLM page
   CSS like `.footer-brand .brand-logo img { height: 48px }` that over-scales
   the logo (canonical CSS is spliced AFTER the page CSS, so it wins). */
.footer-brand img, .footer-brand .brand-logo img {
  display: block; height: auto !important; width: auto !important;
  max-height: 40px !important; max-width: 100% !important;
  object-fit: contain; margin-bottom: 0.75rem;
}
.footer-brand p { margin: 0; max-width: 50ch; font-size: 0.875rem; line-height: 1.6; }
.footer-payments { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.footer-payments img {
  display: block; max-height: 36px; width: auto;
  background: rgba(255,255,255,0.04); padding: 0.4rem; border-radius: 6px;
}
.footer-bottom {
  max-width: 1280px; margin: 2rem auto 0; padding-top: 1.5rem;
  border-top: 1px solid rgba(255,255,255,0.08);
  text-align: center; font-size: 0.8rem;
}

/* === layout centering guardrail (open-design body variance) ===
   The page body is LLM-authored, so a container sometimes provisions more
   track capacity than it has content — e.g. a 2-column `.card-grid` holding a
   single `.card` leaves the card pinned to the leading edge with an empty
   column beside it (reads as "not centered / broken" on desktop). When a
   grid/flex container has exactly ONE card child, center it. `justify-content`
   is a no-op on non-flex/grid elements, so applying this broadly is safe;
   `margin-inline:auto` also centers a lone block-flow card. The measurement
   pass (deterministic_fixes) handles cases this static net can't reach. */
*:has(> .card:only-child) { justify-content: center; }
.card:only-child { margin-inline: auto; }
.card-grid > .card:only-child,
.bento-grid > .card:only-child { max-width: 680px; }
/* A single-card grid must also COLLAPSE its empty fr tracks. `1fr 1fr` with one
   card keeps the card pinned to the left track — `justify-content` can't move a
   filled `1fr` track (it has no free space). Override to one centered, capped
   track so the lone card actually sits in the middle. */
.card-grid:has(> .card:only-child),
.bento-grid:has(> .card:only-child),
[class*="grid"]:has(> .card:only-child) {
  grid-template-columns: minmax(0, 680px) !important;
  justify-content: center !important;
}

/* === vertical-text readability guardrail (open-design body variance) ===
   Stage A sometimes commits to a "rotated vertical section title" motif
   (writing-mode: vertical-lr; transform: rotate(180deg)) and applies it to
   EVERY .section-title. On real, long titles that renders as an unreadable
   bottom-to-top strip AND reserves a tall empty column beside the content.
   Force titles/headings back to upright horizontal text so they are legible.
   Headings are near-universally horizontal, so a broad net is safe; a genuine
   deliberate vertical treatment can be reinstated by the vision design-QA.
   NOTE: the rotate(180deg) that pairs with vertical-lr often sits on a title
   WRAPPER (e.g. .rail-title-box), which matches [class*="title"] but NOT
   .section-title. Neutralizing writing-mode alone then leaves the wrapper
   rotated 180deg → horizontal-but-UPSIDE-DOWN text. So transform:none must
   cover the SAME broad selector set as writing-mode, not just .section-title. */
.section-title, [class*="section-title"],
h1, h2, h3, h4,
[class*="title"], [class*="heading"] {
  writing-mode: horizontal-tb !important;
  transform: none !important;
}

/* === side-rail header motif net (open-design body variance) ===
   Stage A sometimes lays a section header as a narrow grid rail (e.g. a
   320px column) whose flex holds a title box + intro SIDE-BY-SIDE, so each
   gets ~150px: once the title is de-rotated to horizontal it breaks
   one-letter-per-line and the intro collapses to an unreadable vertical
   thread. Stack the rail (title above intro) so each uses the full rail
   width; a title element then fits on its own line and the intro reads as a
   normal sidebar paragraph. flex-direction is a no-op on non-flex rails.
   IMPORTANT: POSITIVE match only — a header rail is a rail that DIRECTLY
   contains a heading/title; card scrollers (.rail-grid, .items-rail…) do
   not, so they keep their horizontal flow. (The previous exclusion-list
   approach broke every time the LLM invented a new container name —
   ".items-rail" slipped past grid/list/row/track/slider/scroll and got
   stacked into a giant vertical column.)
   Second positive cue: a header rail holds TEXT ONLY — a CARD named
   "*-rail" (tb9's a.card.prov-rail: logo img + h3 title) also directly
   contains a title, and releasing its width collapsed `flex:0 0 160px`
   pills into 40px slivers. Anything with a direct img/picture/logo child
   is a card, not a header rail — leave it alone. */
[class*="rail"]:has(> h1, > h2, > h3, > [class*="title"]):not(:has(> img, > picture, > [class*="img"], > [class*="logo"], > [class*="thumb"])) {
  flex-direction: column !important;
  align-items: stretch !important;
}
/* narrow title-spine columns (60px verticals holding a de-rotated title):
   release the width so the horizontal title isn't clipped off-viewport.
   min-width must stay `auto` (the flex content-based minimum), NOT 0: next to
   a huge-basis sibling (a 15-slide horizontal scroller, basis ~7000px),
   proportional shrink crushes a min-width:0 rail to ~50px and the de-rotated
   title slides under the cards (huc Promotions). `auto` floors the rail at
   its longest word, and the flexbox spec caps that content-based minimum by
   the max-width below, so the 7k long-intro rail still can't eat the row. */
[class*="rail"]:has(> h1, > h2, > h3, > [class*="title"]):not(:has(> img, > picture, > [class*="img"], > [class*="logo"], > [class*="thumb"])),
[class*="spine"]:has(> h1, > h2, > h3, > [class*="title"]):not(:has(> img, > picture, > [class*="img"], > [class*="logo"], > [class*="thumb"])) {
  width: auto !important;
  flex: initial !important;
  min-width: auto !important;
}
/* ...but never let a matched header rail EAT the content column. `width:auto`
   above gives the rail flex-basis:max-content; a real sidebar (`.side-rail`,
   25%) holding a title + a long intro then has a huge basis (the unwrapped
   paragraph), and flex shrink — proportional to basis — crushes the sibling
   content-pane into a sliver on the right, leaving the half-empty wide rail on
   the left (7k index: promotions/providers pinned right, the games rail showing
   one card). Cap the released rail to a sane sidebar width so the content
   column keeps its space (the cap is a max-violation, frozen before shrink is
   distributed; a genuinely narrow spine sizes below it and is untouched).
   Desktop-only — on mobile the rail stacks full-width, so no cap there. */
@media (min-width: 769px) {
  [class*="rail"]:has(> h1, > h2, > h3, > [class*="title"]):not(:has(> img, > picture, > [class*="img"], > [class*="logo"], > [class*="thumb"])),
  [class*="spine"]:has(> h1, > h2, > h3, > [class*="title"]):not(:has(> img, > picture, > [class*="img"], > [class*="logo"], > [class*="thumb"])) {
    max-width: min(30%, 380px) !important;
  }
}
[class*="rail-title"], [class*="title-box"] {
  width: auto !important;
  white-space: normal !important;
  writing-mode: horizontal-tb !important;
  transform: none !important;
}
/* === flex-section-without-spine net (subpage-chrome-sync leak) ===
   A shared Stage-A homepage design styles `.content-section { display:flex }`
   for a title-SPINE (`.side-rail`) + content two-column layout. Sub-pages
   inherit that foundation CSS, but a page whose body has NO spine child (e.g. an
   icon_grid brand page: title + intro + grid as DIRECT children) then lays those
   three in a horizontal ROW — and a `minmax(px,1fr)` grid (a flex item with
   min-width:auto that won't shrink) runs off the viewport (sa8 brand-sg). Stack ONLY flex sections whose DIRECT child is a grid (the actual failure
   shape) — a blanket "no spine → stack" destroyed every legitimate split
   hero (tb9: text + hero-mask pill got stacked at desktop). POSITIVE match: sections that DO contain a spine keep their row;
   flex-direction is a no-op on the normal block `.content-section`, so this is
   safe site-wide (the homepage's real spine sections are untouched). */
[class*="section"]:not(:has(> [class*="rail"], > [class*="spine"], > [class*="side"])):has(> [class*="grid"], > [style*="grid-template-columns"]) {
  flex-direction: column !important;
}
/* squeezed prose: a standalone intro/lead paragraph crushed into a sliver
   column renders one word per line — give it a sane minimum measure. Scoped to
   INTRO/LEAD prose only: a card DESCRIPTION (`.card-desc`, `.card-body` p) must
   NOT get a 36ch floor — inside a fixed-width slide/grid card it can't shrink,
   so the floor balloons the whole card past its cap and upscales the thumbnail
   (7k Featured Games slides blew up to ~450px, blurry images). Card overflow is
   handled by the line-clamp net, not a min-width. Cap to the container (100%),
   not the viewport, so the intro can never overflow a capped side-rail. */
p[class*="intro"], p[class*="lead"] {
  min-width: min(36ch, 100%);
}

/* === card description overflow net (open-design no-truncation rule) ===
   Descriptions reach the body UNTRUNCATED — the agent chooses a concise
   card length (or rewrites), and Python never char-cuts mid-sentence. To keep
   a grid tidy when a card's text still runs long, clamp .card-desc to a few
   lines with an ellipsis: the FULL text stays in the DOM (SEO + it also lives
   on the detail page), only the card's visible height is bounded. This is the
   deterministic "改 CSS" path; the agent may still write shorter itself. */
.card-desc {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Provider/category cards sometimes put a long (~900+ char) blurb in
   .provider-body / .card-content etc. with NO line-clamp → each card becomes a
   3000px-tall column of text (arcade-games-fisher). Clamp those long-text
   nodes the same way so provider grids stay readable. */
.provider-body, [class*="provider-body"], .provider-card p,
.provider-card [class*="body"], .provider-card [class*="desc"],
[data-source="game_brand"] [class*="body"], [data-source="game_brand"] p {
  display: -webkit-box !important;
  -webkit-line-clamp: 4 !important;
  line-clamp: 4 !important;
  -webkit-box-orient: vertical !important;
  overflow: hidden !important;
}

/* === mobile horizontal-overflow net (open-design body variance) ===
   Stage A content CSS sometimes hardcodes fixed pixel widths (width: 1400px,
   800px, 500px…) on boxes/tables/media. On a phone those exceed the viewport
   and force sideways scroll — the page reads as "not responsive" even though
   it has @media breakpoints (observed on brand-cq9). Clamp media + common
   containers to the viewport and stop the body from scrolling horizontally so
   nothing overflows the screen edge. */
html, body { max-width: 100%; overflow-x: hidden; }
img, svg, video, canvas, iframe, table, pre { max-width: 100%; }
img, svg, video { height: auto; }
.card, .card-grid, .bento-grid, [class*="grid"], [class*="row"] { max-width: 100%; }
/* viewport clamp on *-inner wrappers (geometry-qa-pipeline 4.3): a narrow
   column holding a de-rotated title (e.g. .hero-overlay / .armor-inner) can push
   its content box past the viewport edge (the left:-37px clip). Clamping every
   *-inner wrapper to the viewport is the permanent form of the geometry-QA
   viewport-clip patch that was hand-injected only into jeetwinsapp's geo-fix. */
[class*="inner"] { max-width: 100%; }
/* On phones, make fixed-width, multi-column content reflow instead of
   overflowing OR squishing. A blanket `* {min-width:0}` collapses flex/grid
   columns into unreadable vertical text strips, so instead: (a) stack multi-
   column grids to one column, (b) let flex rows wrap, (c) neutralize any
   vertical writing-mode (rotated text is unreadable on a phone), (d) clamp the
   common wide containers. Desktop (>768px) is untouched. */
@media (max-width: 768px) {
  /* stack multi-column grids into one column */
  .card-grid, .bento-grid, .footer-grid, .card-list,
  [style*="grid-template-columns"], [class*="grid"] {
    grid-template-columns: 1fr !important;
  }
  /* stack flex two-column sections. The culprit is a `.content-section` (or
     *-row / split / feature) whose `display:flex` comes from a CSS RULE (not an
     inline style), so attribute selectors miss it — match by common class
     patterns. flex-direction:column is a NO-OP on non-flex elements, so this
     broad net is safe; it makes the text column take the full width instead of
     being squeezed to ~200px beside a heading. */
  [class*="section"], [class*="row"], [class*="split"], [class*="feature"],
  [class*="editorial"], [class*="two"], [class*="cols"], [class*="flex"],
  [style*="display: flex"], [style*="display:flex"] {
    flex-direction: column !important;
    flex-wrap: wrap !important;
  }
  /* neutralize rotated/vertical text (unreadable on a phone) */
  [style*="writing-mode"], [class*="title"], [class*="heading"] {
    writing-mode: horizontal-tb !important;
    transform: none !important;
  }
  /* clamp wide containers + text bodies to the viewport */
  section, article, aside, [class*="container"], [class*="wrap"], [class*="body"] {
    max-width: 100% !important;
  }
}

/* === brand/provider logo net (open-design body variance) ===
   Brand logo ASSETS are mixed sizes (square 1024², wide 1151×625, 2048²…), so
   the provider grid renders uneven tiles. Unlike a character photo (where a
   crop amputates the subject → we pad), a LOGO must be CONTAINED in a uniform
   box: the whole mark stays visible, centered, never cropped. Scoped to the
   game_brand section so game/promo thumbnails keep their own object-fit.
   The logo is CONTAINED (whole mark visible, centered, never cropped); the box
   height is left to the card/grid layout rather than a hard-coded px value. */
[data-source="game_brand"] .card-img,
[data-source="game_brand"] .card img,
[data-source="game_brand"] img {
  width: 100%;
  object-fit: contain !important;
  object-position: center;
}
/* Provider/brand logo CARDS on category pages (e.g. cockfighting's "Featured
   Brands": DS88, R88) use `.provider-card`/`.provider-image-wrap`, not the
   game_brand data-source, and the LLM sometimes pins the logo to height:24px —
   tiny and lost inside a ~196px card, so it reads as "no image". Force the logo
   to fill its card box (contained, uncropped, clearly visible). */
/* `html body` prefix boosts specificity so this beats the page's own rules;
   the flex `.provider-image-wrap` was collapsing the square logo to ~24px, so
   un-flex the wrap and pin an explicit logo height. */
html body [class*="provider-image"], html body .provider-image-wrap {
  display: block !important;
  height: auto !important;
  text-align: center;
}
html body [class*="provider"] img, html body [class*="provider-image"] img,
html body .provider-card img {
  height: 72px !important;
  width: auto !important;
  max-width: 88% !important;
  object-fit: contain !important;
  display: inline-block !important;
  margin: 16px auto !important;
}

/* === brand-card logo box net (open-design body variance) ===
   Sub-page brand grids escape BOTH scopes above — the LLM invents per-page
   structures (article.card > .card-img-wrap, div.card > .card-media …) with
   no game_brand data-source and no provider-* class. The class-agnostic
   signal is STRUCTURAL: the card links to a brand-*.html page. Same logo
   treatment: CONTAIN in a centered box, never crop — logo assets are wildly
   mixed sizes (100×100 … 900×365) and object-fit:cover cropped them unevenly
   (tokentest sport.html 2026-07-23). Per the geometry-safe invariants the
   flexing cell gets NO hard height — the img's max-height bounds the box;
   the small min-height on the wrap is the documented contain-logo-box
   exception (keeps a slim wordmark from collapsing the row). */
.card:has(a[href^="brand-"]) [class*="img-wrap"],
.card:has(a[href^="brand-"]) [class*="card-media"],
article:has(a[href^="brand-"]) [class*="img-wrap"] {
  display: flex !important;
  align-items: center;
  justify-content: center;
  min-height: 96px;
  padding: 12px;
}
.card:has(a[href^="brand-"]) [class*="img-wrap"] img,
.card:has(a[href^="brand-"]) [class*="card-media"] img,
a[href^="brand-"].card img,
a[href^="brand-"] > img {
  max-width: 75% !important;
  max-height: 140px !important;
  width: auto !important;
  height: auto !important;
  object-fit: contain !important;
}

/* === item/catalog card thumbnail net (open-design body variance) ===
   The LLM sometimes styles card images with Tailwind utility classes
   (absolute / inset-0 / w-full / h-full / object-cover) but the page has NO
   Tailwind stylesheet loaded, so those classes are inert and the image renders
   unconstrained → giant, uneven cards (jvd live-games catalog). Force a sane
   fixed-height cover thumbnail for grid item cards. Scoped to item/games/
   game_type cards; game_brand LOGO cards keep their contain rule above. */
   NOTE: uniformity comes from ASPECT-RATIO, not a fixed pixel height — a
   hard `height: 200px` pinned the image to the top half of any taller cell
   (BABU88 categories) while `aspect-ratio` scales with the column width and
   always fills its cell. */
[data-source="items"] .card-img, [data-source="games"] .card-img,
[data-source="game_type"] .card-img,
[data-source="items"] [data-item-index] img, [data-source="games"] [data-item-index] img {
  position: static !important;
  width: 100% !important;
  height: auto !important;
  aspect-ratio: 16 / 10;
  object-fit: cover !important;
  display: block !important;
}

/* === slider slide-width net (open-design body variance) ===
   A `slider` block is a horizontal scroller. Its slides typically set
   flex-shrink:0 with an auto (max-content) basis and NO max-width, so a card
   with a long description balloons to its content's full single-line width and
   the rail needs absurd horizontal scrolling (pko Featured Games ledger rows
   measured 1327/1200/879px; 7k tickets ballooned + upscaled their thumbnails).
   Cap each slide with a max-width CEILING — NOT a forced width, so each card
   keeps its own intended size (a vertical ticket ~300px, a horizontal img+text
   ledger ~400px) and only the runaway is clipped. Keyed on the stable
   data-block-type attribute (class-name agnostic) and matched on both `.card`
   and the always-present `[data-item-index]` wrapper. Neutralize the desc
   min-width floor so text wraps INSIDE the card instead of forcing it wider.
   The page's own `.ticket{max-width:320px}` is silently overridden by the broad
   `.card{max-width:100%}` overflow net (same specificity, later) — this
   re-asserts a real ceiling. */
[data-block-type="slider"] .card,
[data-block-type="slider"] [data-item-index] {
  max-width: min(90vw, 440px) !important;
}
[data-block-type="slider"] [class*="desc"] {
  min-width: 0 !important;
}

/* === promo banner net (open-design body variance) ===
   Promotion images are WIDE banners (e.g. 1920×450) whose text/offer IS the
   content. A `.card-img { object-fit: cover }` crops the sides off and loses
   the offer. Show the WHOLE banner (contain, natural aspect) so nothing is
   cut. Scoped to the promotions section. */
/* `html body` boosts specificity to beat the page's own fixed heights. Card +
   image-wrap collapse to hug the banner (no floating gap); the banner shows
   whole (contain), never cropped.
   :has(img) guard: only unclamp a card that actually CONTAINS a banner image.
   A text-only promo motif (huc's fixed-height "ticket" whose left column is
   fine-print clipped by height + overflow) relies on its fixed height; blanket
   height:auto ballooned those tickets 280px → 777px, dumping the full terms
   text into the layout. Positive structural match per the net invariants. */
html body [data-source="promotions"] .card:has(img),
html body [data-source="promotions"] [data-item-index]:has(img) {
  height: auto !important; min-height: 0 !important;
}
html body [data-source="promotions"] .card-img-wrap,
html body [data-source="promotions"] [class*="img-wrap"],
html body [data-source="promotions"] [class*="image-wrap"],
html body [data-source="promotions"] [class*="thumb"] {
  height: auto !important; min-height: 0 !important; max-height: none !important;
  aspect-ratio: auto !important;
}
html body [data-source="promotions"] .card-img, html body [data-source="promotions"] img {
  object-fit: contain !important; width: 100% !important; height: auto !important;
  position: static !important; display: block !important;
}

/* === dead-Tailwind grid net (open-design body variance) ===
   The LLM writes grid containers with Tailwind classes (grid grid-cols-1
   sm:grid-cols-2 lg:grid-cols-3) but no Tailwind is loaded → the container
   stays display:block → cards stack single-column full-width. Force a real
   responsive grid for any container that carries a grid-cols-* class. */
[class*="grid-cols"] {
  display: grid !important;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)) !important;
  gap: 16px !important;
}
/* === provider-card un-clip net ===
   Provider "Featured Providers" cards (.provider-grid > .provider-card >
   .provider-logo) sometimes clip the logo in a short overflow:hidden bar
   (coin-dozer showed 26px slivers). Lay them out as centered logo tiles and
   never clip the logo. */
.provider-grid {
  display: grid !important;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)) !important;
  gap: 16px !important;
}
.provider-card, [class*="provider-card"] {
  overflow: visible !important;
  height: auto !important;
  min-height: 88px;
  display: flex !important;
  align-items: center;
  justify-content: center;
  padding: 14px;
}
/* hero CTA must be a normal button, not a full-height stretched bar (do NOT
   set align-items on the hero itself — that collapses a stretch-height hero
   image block; the button self-centers via align-self). */
[class*="hero"] .btn, [class*="hero"] [class*="cta"], [class*="hero"] [class*="register"],
[class*="hero"] a.btn-primary, [class*="hero"] [class*="btn-primary"] {
  height: auto !important; align-self: center !important; max-width: 260px !important;
  width: auto !important; padding: 14px 30px !important;
  display: inline-flex !important; align-items: center; justify-content: center; white-space: nowrap;
}
.provider-logo {
  height: 56px !important;
  width: auto !important;
  max-width: 82% !important;
  object-fit: contain !important;
  position: static !important;
}

/* === content-width net (open-design body variance) ===
   The LLM caps content with Tailwind `container` / `max-w-7xl` / `mx-auto`
   (inert, no framework) → content spans the full viewport edge-to-edge
   (ugly 1400px+ line lengths, stretched rows). Cap the CONTENT column and
   centre it. Scoped to container/wrapper classes (NOT <section>), so section
   backgrounds still bleed full-width while their inner content is contained. */
[class*="container"], [class*="mx-auto"], [class*="max-w"],
main > div:not([class*="hero"]), .page-main > div:not([class*="hero"]) {
  max-width: 1200px !important;
  margin-left: auto !important;
  margin-right: auto !important;
}


/* DRAWER-SHIM-START */
@media (max-width: 880px) {
  .mobile-drawer.is-open, .mobile-drawer[data-open], .mobile-drawer.open {
    display: flex !important;
    inset: 0 0 0 auto !important;
    width: min(320px, 85vw) !important;
    transform: translateX(0) !important;
    z-index: 1001 !important;
  }
  .drawer-backdrop.is-open, .drawer-backdrop[data-open],
  .mobile-drawer__backdrop.is-open, .mobile-drawer__backdrop[data-open] {
    display: block !important; opacity: 1 !important;
    pointer-events: auto !important; z-index: 1000 !important;
  }
  .mobile-drawer ul {
    list-style: none !important; margin: 0 0 1.25rem !important;
    padding: 0 !important;
  }
  .mobile-drawer li { margin: 0 0 0.4rem !important; }
  .mobile-drawer a {
    display: block !important; text-decoration: none !important;
    padding: 0.5rem 0 !important;
  }
  .mobile-drawer ul ul {
    display: block !important; padding-left: 1rem !important;
    opacity: 1 !important; visibility: visible !important;
    position: static !important; transform: none !important;
  }
  .mobile-drawer ul ul a { font-size: 0.9rem !important; opacity: 0.85; }
}
@media (min-width: 881px) {
  .mobile-drawer, .mobile-drawer[data-open], .mobile-drawer.is-open,
  .drawer-backdrop, .drawer-backdrop[data-open],
  .mobile-drawer__backdrop {
    display: none !important;
  }
}
/* DRAWER-SHIM-END */
