/* ============================================================
   RABBIT ROLL - brand system v2
   Register: casino PRODUCT chrome, in the Stake / Shuffle / MyStake family.
   Measured off shuffle.com: base rgb(8,8,8), elevated surfaces #202329 /
   #2A2E38 / #343843, muted ink #828998, radii 6-8px, controls 36-48px.
   We keep that skeleton and swap the accent to Rabbit Roll lilac (hue 305).
   Dense, hard-edged, near-black. Not pastel, not plush, not airy.
   ============================================================ */

:root {
  /* ---- surfaces: near-black, barely lilac-tinted so it is ours ---- */
  --rr-black:   oklch(0.115 0.006 305);
  --rr-bg:      oklch(0.155 0.009 305);
  --rr-panel:   oklch(0.205 0.012 305);
  --rr-panel-2: oklch(0.255 0.015 305);
  --rr-panel-3: oklch(0.305 0.018 305);
  --rr-line:    oklch(0.33  0.016 305);

  /* ---- ink ---- */
  --rr-ink:   oklch(1 0 0);
  --rr-ink-2: oklch(0.72 0.02 305);   /* 6.0:1 on --rr-panel */
  --rr-ink-3: oklch(0.64 0.02 305);   /* 4.7:1 on --rr-panel - the floor */

  /* ---- accent + semantic ---- */
  --rr-lilac:     oklch(0.72 0.20 305);
  --rr-lilac-hot: oklch(0.80 0.19 303);
  --rr-lilac-dim: oklch(0.42 0.14 305);
  --rr-win:       oklch(0.80 0.19 150);
  --rr-lose:      oklch(0.68 0.19  25);
  --rr-gold:      oklch(0.84 0.15  85);

  /* ---- shape: hard, small radii. plush is dead ---- */
  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-pill: 999px;

  /* ---- control heights: compact ---- */
  --h-sm: 32px;
  --h-md: 38px;
  --h-lg: 44px;

  /* ---- space: tight ---- */
  --s-1: 4px;  --s-2: 6px;  --s-3: 10px; --s-4: 14px;
  --s-5: 20px; --s-6: 28px; --s-7: 40px; --s-8: 56px;

  --rail: 232px;

  /* stronger than the CSS built-ins, which are too weak to read as intentional */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease: var(--ease-out);
  /* exits are always faster than entrances: the user is already gone */
  --t-press: 130ms;
  --t-hover: 160ms;
  --t-enter: 240ms;
  --t-exit: 150ms;

  --font-ui: 'Chivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-num: 'Chivo Mono', ui-monospace, 'SF Mono', monospace;

  --z-base: 0; --z-raised: 10; --z-sticky: 100; --z-overlay: 200;
  --z-modal: 300; --z-toast: 400;
}

/* ============================================================
   reset
   ============================================================ */

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

/* The hidden attribute is only display:none from the UA sheet, so any author
   `display` rule silently beats it. An empty race panel rendered a 0 pool and a
   dead clock because of exactly this. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--rr-bg);
  color: var(--rr-ink);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 { margin: 0; font-weight: 800; letter-spacing: -0.015em; line-height: 1.1; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
svg { display: block; }
ul { margin: 0; padding: 0; list-style: none; }

/* Focus is a brand surface, not a browser default.

   The old rule forced border-radius: 4px onto every focused element, so the
   ring cut corners off pills and squared off circles. An outline already
   follows the element's own radius; overriding it was the bug. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--rr-lilac);
  outline-offset: 3px;
  /* the glow is what stops a 2px line disappearing against a dark panel */
  box-shadow: 0 0 0 5px oklch(0.72 0.20 305 / 0.22);
}

/* A mouse user pressing a button should not get a ring; a keyboard user must.
   :focus-visible already does that, this only removes the UA fallback. */
:where(a, button):focus:not(:focus-visible) { outline: none; }

/* ---- skip link ----
   Without one, reaching the games from the keyboard means tabbing through
   every rail entry first, on every single page load. */
.skip {
  /* Clipped rather than translated. translateY(calc(-100% - ...)) depends on the
     element's own height being resolved at the moment the transform is computed,
     and it was not: the link ended up 24px short and sat half-visible over the
     page. Clipping to a 1px box cannot half-fail. */
  position: fixed; left: var(--s-4); top: var(--s-4); z-index: var(--z-toast);
  width: 1px; height: 1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
  background: var(--rr-lilac); color: var(--rr-black);
  font-size: 13px; font-weight: 800; border-radius: var(--r-sm);
}
.skip:focus-visible {
  width: auto; height: var(--h-md); padding: 0 var(--s-4);
  clip-path: none; overflow: visible;
  display: inline-flex; align-items: center;
}

/* ============================================================
   primitives
   ============================================================ */

.num {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  height: var(--h-md); padding: 0 var(--s-4);
  border-radius: var(--r-sm);
  font-size: 13px; font-weight: 700; white-space: nowrap;
  /* named properties only: `all` animates things you did not mean to animate */
  transition: background-color var(--t-hover) var(--ease),
              color var(--t-hover) var(--ease),
              transform var(--t-press) var(--ease);
}
.btn:active { transform: scale(0.97); }
.btn--lg { height: var(--h-lg); padding: 0 var(--s-5); font-size: 14px; }
.btn--sm { height: var(--h-sm); padding: 0 var(--s-3); font-size: 12px; }

/* dark ink on lilac = 7.1:1. white on lilac would be 2.2:1 and fail hard. */
.btn--primary { background: var(--rr-lilac); color: var(--rr-black); }


.btn--solid { background: var(--rr-panel-3); color: var(--rr-ink); }


.btn--quiet { background: transparent; color: var(--rr-ink-2); }


.tag {
  display: inline-flex; align-items: center; gap: 5px;
  height: 20px; padding: 0 7px; border-radius: var(--r-xs);
  font-size: 10px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
}
.tag--live { background: var(--rr-lose); color: var(--rr-black); }
.tag--soon { background: var(--rr-panel-3); color: var(--rr-ink-2); }
.tag--demo { background: var(--rr-gold); color: var(--rr-black); }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* thin dark scrollbars, like the reference product */
.scroller { overflow-x: auto; scrollbar-width: thin; scrollbar-color: var(--rr-panel-3) transparent; }
.scroller::-webkit-scrollbar { height: 6px; }
.scroller::-webkit-scrollbar-thumb { background: var(--rr-panel-3); border-radius: var(--r-pill); }
.scroller::-webkit-scrollbar-track { background: transparent; }


/* Hover only where a cursor actually exists. On a touch screen these fire on
   tap and then stay stuck until something else is tapped. */
@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover { background: var(--rr-lilac-hot); }
  .btn--solid:hover   { background: var(--rr-line); }
  .btn--quiet:hover   { background: var(--rr-panel-2); color: var(--rr-ink); }
}

/* The room. Fixed behind everything, never in the way of a pointer. */
.rr-backdrop {
  position: fixed; inset: 0; z-index: -1;
  pointer-events: none;
  /* it lives behind opaque panels, so it only ever reads in the gaps */
  mix-blend-mode: screen;
}
/* content sits on its own layer so the backdrop cannot bleed through panels */
body > .app, body > .shell { position: relative; z-index: 1; }

/* ============================================================
   THE MARK, EXTRUDED
   Real depth: copies of one path stacked along translateZ inside a
   preserve-3d scene. Front face lit white, the body falls into lilac.
   ============================================================ */
.l3-scene { position: relative; perspective: 900px; width: 100%; height: 100%; display: grid; place-items: center; }
.l3-stack { position: relative; width: 100%; height: 100%;
  transform-style: preserve-3d; will-change: transform; }
.l3-layer { position: absolute; inset: 0; width: 100%; height: 100%;
  transform: translateZ(var(--z));
  color: color-mix(in oklch, var(--rr-lilac) calc(100% - var(--t) * 68%), var(--rr-black)); }
/* No filter here. A filter on a child of a preserve-3d parent flattens that
   child out of the 3D context, which pushed the lit face BEHIND the extrusion.
   The glow lives on the scene wrapper, outside the 3D context. */
.l3-front { color: #fff; }
.l3-scene::before {
  content: ""; position: absolute; inset: 4%; border-radius: 50%; z-index: -1;
  background: radial-gradient(circle, oklch(0.72 0.20 305 / .32), transparent 68%);
}

/* ============================================================
   TOUCH
   ============================================================
   A 38px control is fine under a mouse and a miss under a thumb. Measured on
   the lobby: eight interactive elements sat under 44px at every phone width,
   including carousel dots at 22x3.

   Bumping every control globally would bloat the desktop UI for no reason, so
   the sizes change only where the pointer is actually coarse. */
/* Width is part of the condition, not just the pointer type. A headless browser
   reports pointer:fine at any size, so a coarse-only rule is a rule nobody can
   verify, and a narrow viewport is a thumb in practice regardless of what the
   browser claims about its pointer. */
@media (pointer: coarse), (max-width: 1024px) {
  :root {
    /* 44 is the floor, so the small size cannot be 40 and still qualify */
    --h-sm: 44px;
    --h-md: 48px;
    --h-lg: 54px;
  }

  /* Anything using .btn inherits the height; these carried their own. */
  .btn--sm { height: var(--h-sm); }
  .tag { height: 22px; }

  /* Icon-only controls have no text to grow them. */
  .burger { width: 46px; height: 46px; }

  /* A logo link's hitbox is the glyph unless you give it one. */
  .lockup { padding: 8px; margin: -8px; }

  /* The dots stay 3px tall to look right, and get a 44px tall invisible pad so
     a thumb can actually land on them. Hit area and visual size are not the
     same thing and should not be forced to be. */
  .pdots { gap: 0; }
  .pdots button { position: relative; height: 3px; }
  .pdots button::after {
    content: ""; position: absolute; left: -9px; right: -9px;
    top: -22px; bottom: -22px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* The scene is decoration. Reduced motion gets the flat, lit mark. */
@media (prefers-reduced-motion: reduce) {
  .l3-stack { transform: none !important; }
  .l3-layer:not(.l3-front) { display: none; }
}
