/* ============================================================
   System layer — spacing/type/radius scale (LOCKED 2026-07-04)
   Root 16px = 1rem. Everything on an even/4-based scale.
   Complements tokens.css (colours). Load order: tokens → system → home.
   ============================================================ */
:root {
  /* --- Type scale (px÷16). Floor 10px, cap 64px. --- */
  --fs-10: 0.625rem;  --fs-12: 0.75rem;   --fs-14: 0.875rem;
  --fs-16: 1rem;      --fs-17: 1.0625rem; --fs-19: 1.1875rem;
  --fs-20: 1.25rem;   --fs-24: 1.5rem;    --fs-28: 1.75rem;
  --fs-32: 2rem;      --fs-36: 2.25rem;   --fs-40: 2.5rem;
  --fs-48: 3rem;      --fs-56: 3.5rem;    --fs-64: 4rem;

  /* Roles (static now — headings get clamp() AFTER build, once Martin walks the breakpoints) */
  --fs-body: var(--fs-17);   --lh-body: 1.65;
  --fs-lead: var(--fs-19);   --lh-lead: 1.5;
  --lh-heading: 1.15;
  --fs-eyebrow: var(--fs-12);
  --fs-h4: var(--fs-20);
  --fs-h3: var(--fs-24);
  --fs-h2: var(--fs-36);
  --fs-h1: var(--fs-48);

  /* --- Spacing scale (rem) --- */
  --s-2: 0.125rem;  --s-4: 0.25rem;  --s-8: 0.5rem;   --s-12: 0.75rem;
  --s-16: 1rem;     --s-20: 1.25rem; --s-24: 1.5rem;  --s-28: 1.75rem;
  --s-32: 2rem;     --s-36: 2.25rem; --s-40: 2.5rem;  --s-48: 3rem;
  --s-56: 3.5rem;   --s-64: 4rem;    --s-72: 4.5rem;  --s-80: 5rem;
  --s-96: 6rem;     --s-112: 7rem;   --s-128: 8rem;

  /* --- Radius (16-multiples) + pill --- */
  --radius: 1rem;        /* 16px — cards/panels (also set in tokens.css) */
  --radius-lg: 2rem;     /* 32px — hero / large panels */
  --radius-pill: 999px;  /* buttons / chips / pills */

  /* --- Layout --- */
  --container: 85rem;    /* 1360px content max — the CONTAINER is bounded; text inside runs full width */
  --gutter: var(--s-24);

  --font-display: 'Sora', system-ui, sans-serif;
  --font-body: 'Figtree', system-ui, sans-serif;
}

/* --- Reset / base (minimal; harness ships its own reset in prod theme) --- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* Lock background scroll while any modal <dialog> is open (all site dialogs use showModal()).
   Pure CSS via :has() → auto-unlocks on EVERY close path (X / backdrop / Esc) since native
   <dialog> drops the [open] attribute itself. Locks the ROOT scroller (html is the page
   scroller here, not body) so the wheel/touch can't move the page behind the modal. */
html:has(dialog[open]) { overflow: hidden; }

/* --- Real slot cover art over the poster--{prov} gradient -----------------------------------------
   oseg_slot_thumb_pic() (inc/slots-data.php) emits <picture class="slot-thumb"> inside a
   position:relative poster/thumb/chip container; the image covers the gradient + monogram/text,
   which stay as the automatic fallback wherever no art exists (7 slots + any future slot). */
.slot-thumb { position: absolute; inset: 0; z-index: 1; display: block; line-height: 0; overflow: hidden; }
.slot-thumb__img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* hosts that need explicit relative + clip for the absolute image */
.slr-stage__poster, .slr-otile__glyph, .sk-chip { position: relative; overflow: hidden; }
/* overlays that must stay above the cover image (all are absolutely/relatively positioned already) */
.sk-tile__badge, .scard__badge, .scard__jackpot, .poster__badge, .poster__hover,
.pv-spotlight__badge { z-index: 2; }
h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: var(--lh-heading);
  color: var(--ink);
  margin: 0;
  font-weight: 800;
  letter-spacing: -0.01em;
  /* NO max-width by default — paragraphs & headings run the full container (Martin's rule) */
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); font-weight: 700; }
h4 { font-size: var(--fs-h4); font-weight: 700; }
p  { margin: 0; }
a  { color: inherit; text-decoration: none; }
img, picture, svg { max-width: 100%; display: block; }
strong { font-weight: 700; }

/* --- Reusable primitives --- */
.container { max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.container--narrow { max-width: calc(60rem + (var(--gutter) * 2)); }

/* Custom scrollbar utility — opt in with .oseg-scroll on any scroll container (drawer, header search,
   modal bodies). Colour is driven by --sb-color (default green --primary; --primary flips per theme).
   Override per context, e.g. `.hsearch__scroll { --sb-color: var(--accent); }`. Thin, rounded pill thumb,
   inset via a transparent border; deepens on hover. WebKit/Blink pseudo-elements + Firefox scrollbar-*. */
/* WebKit/Blink: styled pseudo-element scrollbar (below). Firefox: standard props, but ONLY in
   browsers without ::-webkit-scrollbar — modern Chromium honours scrollbar-width/color and then
   IGNORES the pseudo-elements, collapsing the styled bar into a faint near-invisible default one. */
@supports not selector(::-webkit-scrollbar) {
  .oseg-scroll { scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--sb-color, var(--primary)) 100%, var(--surface)) transparent; }
}
.oseg-scroll::-webkit-scrollbar { width: 10px; height: 10px; } /* height → horizontal bar matches the vertical one */
/* inset the track by the container radius so the bar never collides with rounded corners (both axes) */
.oseg-scroll::-webkit-scrollbar-track { background: transparent; margin: var(--radius); }
.oseg-scroll::-webkit-scrollbar-thumb { border-radius: var(--radius-pill);
  border: 3px solid transparent; background-clip: padding-box;
  background-color: color-mix(in srgb, var(--sb-color, var(--primary)) 100%, var(--surface)); }
.oseg-scroll::-webkit-scrollbar-thumb:hover {
  background-color: color-mix(in srgb, var(--sb-color, var(--primary)) 100%, var(--surface)); }
.section { padding-block: var(--s-64); }
.section--tint { background: var(--hero); }
.section--panel { background: var(--panel); color: var(--panel-ink); }
.section--panel h2, .section--panel h3 { color: var(--panel-ink); }

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin: 0 0 var(--s-12);
}
.eyebrow--alt  { color: var(--kicker-alt); }
.eyebrow--main { color: var(--kicker-main); }

.lead { font-size: var(--fs-lead); line-height: var(--lh-lead); color: var(--sub); }

/* Visually-hidden (screen-reader only) */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* Buttons */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-8);
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-17);
  padding: var(--s-16) var(--s-28);
  border-radius: var(--radius-pill);
  border: 0; cursor: pointer; text-align: center;
  transition: transform .2s ease, filter .2s ease, background-color .2s ease;
}
/* soft coloured glow that blooms beneath the button on hover (blurred copy of its own background) */
.btn::before {
  display: block;
  position: absolute;
  z-index: -1;
  content: "";
  inset-inline: 10px;
  inset-block: 12px 0;
  opacity: 0;
  border-radius: inherit;
  background: inherit;
  transition: opacity .2s ease;
  filter: blur(11px);
}
.btn:hover { transform: translate3d(0, -2px, 0); filter: brightness(0.96); }
.btn:hover::before { opacity: .8; }
.btn--primary { background: var(--primary); color: var(--on-primary); }
.btn--ghost   { background: var(--accent); color: var(--on-primary); }
.btn--cancel  { background: var(--negative); color: var(--on-primary); }   /* destructive/clear — same red as the pro/con --negative */
.btn--block { width: 100%; }
.btn:disabled { opacity: .5; cursor: not-allowed; filter: none; transform: none; }
.btn:disabled:hover { transform: none; filter: none; }
.btn:disabled:hover::before { opacity: 0; }

/* Chips / pills */
.chip {
  display: inline-flex; align-items: center; gap: var(--s-4);
  font-size: var(--fs-14); font-weight: 500; color: var(--sub);
  padding: var(--s-8) var(--s-16);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: var(--surface);
}
.pill {
  display: inline-flex; align-items: center;
  font-size: var(--fs-14); font-weight: 700; color: #fff;
  background: var(--accent); padding: var(--s-4) var(--s-12);
  border-radius: var(--radius-pill);
}

/* Star rating (gold) */
.stars { color: var(--star); letter-spacing: 2px; font-size: var(--fs-16); }

/* Rating stars (Approach B) — site-wide widget rendered by oc_stars()/ocr_hstars(); 5 discrete
   stars, each fills in turn with a pop + gold glow (animated by the global assets/js/stars.js).
   Base rules live here so ANY page can show animated stars; page-specific context tweaks (e.g.
   .ocr-overall) stay in their own stylesheet. */
.ocr-hstars { display: inline-flex; gap: .1em; font-family: var(--font-display); font-size: var(--fs-16); line-height: 1; }
.ocr-hstar { position: relative; display: inline-block; color: var(--line);
  transition: transform .3s cubic-bezier(.34, 1.56, .64, 1), text-shadow .45s ease; }
.ocr-hstar::before { content: '★'; }
/* glow lives on the PARENT star shape (text-shadow, unclipped) — not on the overflow:hidden fill,
   whose clipped drop-shadow read as a rectangular smear sweeping behind the stars */
.ocr-hstar__on { position: absolute; inset: 0; width: 0; overflow: hidden; color: var(--nav-gold); text-shadow: none; }
.ocr-hstar.is-lit { transform: scale(1.18); text-shadow: 0 0 6px color-mix(in srgb, var(--nav-gold) 85%, transparent); }
@media (prefers-reduced-motion: reduce) { .ocr-hstar { transition: none; } }

/* Volatility pips fill-in — the gold `.is-on` pips colour in grey→gold one-by-one on viewport entry
   (pure colour fade, no size/brightness change). Armed/played by the global assets/js/stars.js.
   `.vola-armed` = start state (grey); removing it (staggered) fades to the gold rest state. */
.vola__bar i, .sk-vola__bar i { transition: background-color .45s ease; }
.vola__bar i.is-on.vola-armed, .sk-vola__bar i.is-on.vola-armed { background: var(--line); }

/* Right-edge section rail — shared sticky TOC. Fixed dots + hover-label; hidden until the driver
   (assets/js/toc-rail.js) docks it in once the page's hero/jump-nav scrolls above the viewport.
   Any page that renders `.ocr-rail` markup gets it (provider, slot-review, casino-review, guide). */
.ocr-rail { position: fixed; right: 7px; top: 50%; transform: translateY(-50%); z-index: 20;
  opacity: 0; visibility: hidden; }
.ocr-rail ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-8); align-items: flex-end; }
.ocr-rail__dot { position: relative; display: inline-flex; align-items: center; gap: var(--s-8); text-decoration: none; }
.ocr-rail__dot::after { content: ''; flex: none; width: 12px; height: 12px; border-radius: 50%;
  background: var(--line); transition: background .2s ease, transform .2s ease; }
.ocr-rail__dot:hover::after, .ocr-rail__dot:focus-visible::after { background: var(--sub); }
.ocr-rail__dot.is-active::after { background: var(--accent); transform: scale(1.333); }
/* label pulled OUT of flow (absolute) so the anchor's hit-area shrinks to just the 10px dot —
   otherwise the in-flow (opacity:0) label kept the <a> wide and it intercepted clicks over the
   content to its left. Now the tooltip only appears when you point the dot itself, and being
   absolute + pointer-events:none it floats over content without ever blocking it. */
.ocr-rail__label { position: absolute; right: calc(100% + var(--s-8)); top: 50%;
  white-space: nowrap; font-size: var(--fs-14); font-weight: 600; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-pill); padding: var(--s-4) var(--s-16);
  opacity: 0; transform: translate(var(--s-8), -50%); pointer-events: none;
  transition: opacity .2s ease, transform .2s ease; }
.ocr-rail__dot:hover .ocr-rail__label, .ocr-rail__dot:focus-visible .ocr-rail__label { opacity: 1; transform: translate(0, -50%); }
@media (prefers-reduced-motion: reduce) { .ocr-rail__label, .ocr-rail__dot::after { transition: none; } }
@media (max-width: 767px) { .ocr-rail { display: none; } }

/* ============================================================
   Prose primitive (.oc-prose) — unified editorial reading column.
   ONE class owns the 60rem column + typography; every flowing
   element styles via descendant selector. Put .oc-prose on the
   innermost div wrapping editorial HTML — NOT on a <section> or a
   .container (those keep their own width/padding). ink + fs-19
   everywhere by design. Replaces the old per-template prose classes
   (.pv-prose / .rgg-prose / .ocr-prose / .slr-prose).
   ============================================================ */
.oc-prose {
  max-width: 60rem; margin: 0 auto;
  font-size: var(--fs-19); color: var(--sub);
}
.oc-prose > * + * { margin-top: var(--s-20); }
.oc-prose p { margin-top: 0; margin-bottom: var(--s-20); }
.oc-prose p:last-child { margin-bottom: 0; }
.oc-prose strong { font-weight: 700; color: var(--ink); }
.oc-prose a { color: var(--accent); text-decoration: none; border-bottom: 2px solid transparent; transition: color .25s ease, border-color .25s ease; }
.oc-prose a:hover { color: var(--primary); border-bottom-color: currentColor; }
.oc-prose :is(h2, h3, h4) {
  color: var(--ink); line-height: var(--lh-heading);
  scroll-margin-top: calc(var(--header-h, 82px) + 5rem);
  margin-top: var(--s-40); margin-bottom: var(--s-20);
  padding-left: var(--s-20); border-left: var(--s-4) solid var(--nav-gold);
}
.oc-prose :is(h2, h3, h4):first-child { margin-top: 0; }
.oc-prose h2 { font-size: var(--fs-h2); }
.oc-prose h3 { font-size: var(--fs-h3); }
.oc-prose h4 { font-size: var(--fs-h4); }
.oc-prose ul, .oc-prose ol {
  margin-top: 0; margin-bottom: var(--s-20); padding-left: var(--s-20);
  display: grid; gap: var(--s-12);
}
.oc-prose ul:last-child, .oc-prose ol:last-child { margin-bottom: 0; }
.oc-prose ul { list-style: none; }
.oc-prose ul li { position: relative; padding-left: var(--s-24); }
.oc-prose ul li::before {
  content: ""; position: absolute; left: 0; top: .6em;
  width: .5rem; height: .5rem; border-radius: 50%; background: var(--accent);
}
.oc-prose blockquote {
  margin: var(--s-32) 0;
  padding: var(--s-24);
  background: var(--hero);
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius-s);
  font-family: var(--font-display);
  font-size: var(--fs-17);
  color: var(--ink);
}
.oc-prose blockquote:last-child { margin-bottom: 0; }
@media (max-width: 40rem) { .oc-prose { font-size: var(--fs-17); } }

/* Phone (≤767px): step the type ROLE tokens down one notch (the clamp-later note above — done by
   walking the breakpoints). The raw --fs-NN scale is untouched; only the semantic roles shrink. */
@media (max-width: 47.9375rem) {
  :root {
    --fs-lead: var(--fs-17);
    --fs-body: var(--fs-16);
    --fs-h4:   var(--fs-16);
    --fs-h3:   var(--fs-20);
    --fs-h2:   var(--fs-28);
    --fs-h1:   var(--fs-32);
  }
  .oc-prose blockquote { font-size: var(--fs-16); }
}

/* Narrow phones (≤460px): where an eyebrow is "pill + trailing text" (e.g. [Geprüft · Juli 2026]
   Unabhängiger Vergleich), the trailing green label no longer fits beside the pill — stack it
   below by turning the <p> into a flex column. Scoped via :has() so plain (pill-less) eyebrows
   are untouched. Centered heroes keep centre alignment. */
@media (max-width: 28.75rem) {
  .eyebrow:has(.eyebrow-pill) { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-8); }
  .e404-hero .eyebrow:has(.eyebrow-pill), .ks-hero .eyebrow:has(.eyebrow-pill),
  .oc-hero .eyebrow:has(.eyebrow-pill) { align-items: center; }
  .eyebrow:has(.eyebrow-pill) .eyebrow-pill { margin-right: 0; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* --- scroll-reveal pre-paint guard (see reveal.js) ---
   Hides reveal targets before first paint so below-fold elements never flash their server-rendered
   state before GSAP takes over. Armed by an inline script in header.php (JS-only → no-JS keeps content
   visible); reveal.js drops the .oseg-reveal-arm class the instant it owns the inline opacity, and on
   any early bail (reduced-motion / no GSAP). Motion-safe: never hides when the user prefers reduced
   motion, so the reduced-motion path can't leave anything invisible. */
@media (prefers-reduced-motion: no-preference) {
  html.oseg-reveal-arm [data-reveal]:not([data-no-reveal]),
  html.oseg-reveal-arm [data-reveal-group]:not([data-no-reveal]) > *:not([data-no-reveal]),
  html.oseg-reveal-arm .section-head:not([data-no-reveal]),
  html.oseg-reveal-arm .faq-section .faq-item:not([data-no-reveal]) { opacity: 0; }
}
/* opt-out: put data-no-reveal on the element itself to exclude it from the scroll-reveal (both the
   JS and this pre-hide guard skip it) — e.g. a section-head you want static. */
