/* ══════════════════════════════════════════════════════════════════════════════════════════════
   pn-tipsy-20260927.css — companion to web/assets/js/pn-tipsy.js (SPEC_duff-drinking_2026-09-27).

   THE WHOLE-GAME BLUR sits on `html`, never on a scoped container — it has to cover play.html's
   own body AND the `#pn-pub` overlay pn-pub.js paints into it, which a class under either one
   could never reach. `html.pn-tipsy-3.pn-tipsy-blur body` is the one selector doing that work.

   LAW: no flashing >3/s (WCAG 2.3.1) — every keyframe here runs 6s+ per cycle, nothing strobes.
   `prefers-reduced-motion`: no blur, no drift — a warm tint only, same countdown/choices/AA.
   The warning card is never blurred (it lives outside `body`, appended to `html` via #pn-tipsy-ui
   which this stylesheet explicitly exempts) and every control in it passes AA on its own ground.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── level 1 · warm (3 pints) — a faint vignette, nothing else ───────────────────────────────── */
html.pn-tipsy-1 body::after{
  content:""; position:fixed; inset:0; z-index:2147483000; pointer-events:none;
  box-shadow:inset 0 0 140px rgba(194,65,12,.14);
}

/* ── level 2 · loose (4–5 pints) — a slow ≤2px sway, 6s period (never faster than 3/s) ───────── */
@keyframes pn-tipsy-sway{ 0%,100%{ transform:translateX(0) rotate(0deg); } 50%{ transform:translateX(2px) rotate(.15deg); } }
html.pn-tipsy-2 body{ animation:pn-tipsy-sway 6s ease-in-out infinite; transform-origin:50% 50%; }
html.pn-tipsy-2 body::after{
  content:""; position:fixed; inset:0; z-index:2147483000; pointer-events:none;
  box-shadow:inset 0 0 180px rgba(194,65,12,.20);
}

/* ── level 3 · seeing double — the ACTIVE distortion only while blurUntil is live ─────────────── */
@keyframes pn-tipsy-drift{
  0%,100%{ transform:translate(0,0) scale(1); }
  50%{ transform:translate(1.5px,-1px) scale(1.004); }
}
html.pn-tipsy-3.pn-tipsy-blur body{
  animation:pn-tipsy-drift 7s ease-in-out infinite;
  filter:blur(2.5px) saturate(1.15);
}
html.pn-tipsy-3.pn-tipsy-blur body::before{
  content:""; position:fixed; inset:0; z-index:2147482999; pointer-events:none;
  /* a slow RGB-split, drawn as two soft coloured glows drifting apart rather than a hard split —
     it reads as double vision without ever looking like a broken monitor */
  background:
    radial-gradient(60% 60% at 46% 48%, rgba(255,60,60,.10), transparent 60%),
    radial-gradient(60% 60% at 54% 52%, rgba(60,140,255,.10), transparent 60%);
  animation:pn-tipsy-drift 9s ease-in-out infinite reverse;
  mix-blend-mode:screen;
}
/* once the level-3 window has expired (or tequila cleared it) the sway from level 2 still applies
   because pn-tipsy.js drops the level to 2, not to 0 — handled by the class swap itself, nothing
   extra needed here. */

/* ── reduced motion: no blur, no drift — a warm tint only, same countdown/choices (spec law) ──── */
html.pn-tipsy-reduced body{ animation:none !important; filter:none !important; }
html.pn-tipsy-reduced body::before{ animation:none !important; }
html.pn-tipsy-reduced.pn-tipsy-3 body::after{
  content:""; position:fixed; inset:0; z-index:2147483000; pointer-events:none;
  box-shadow:inset 0 0 220px rgba(194,65,12,.30);
}

@media (prefers-reduced-motion:reduce){
  html.pn-tipsy-2 body, html.pn-tipsy-3.pn-tipsy-blur body{ animation:none !important; filter:none !important; }
  html.pn-tipsy-3.pn-tipsy-blur body::before{ animation:none !important; }
}

/* ── the countdown pill ("Vision restoring — Ns") ─────────────────────────────────────────────── */
#pn-tipsy-ui{ position:fixed; inset:0; z-index:2147483647; pointer-events:none; }
.pn-tipsy-pill{
  position:fixed; right:16px; bottom:16px; pointer-events:none;
  padding:10px 16px; border-radius:999px;
  background:#1a0c02; color:#ffd9c2; border:1px solid rgba(255,178,122,.4);
  font:700 12.5px/1 IS,ui-sans-serif,system-ui,sans-serif; letter-spacing:.02em;
  box-shadow:0 8px 24px rgba(0,0,0,.4);
}

/* ── the warning / tequila / reaction card — NEVER blurred, always AA, always escapable ──────── */
.pn-tipsy-warn{
  position:fixed; inset:0; z-index:2147483647; pointer-events:auto;
  align-items:center; justify-content:center; padding:20px;
  background:rgba(5,4,3,.72); backdrop-filter:blur(6px);
}
/* the `hidden` attribute must actually hide it — an unconditional `display:flex` above beat the
   UA [hidden]{display:none} rule on specificity, so the (invisible but pointer-events:auto) full-
   screen dialog sat over everything else and swallowed clicks meant for the room underneath. */
.pn-tipsy-warn:not([hidden]){ display:flex; }
.pn-tipsy-card{
  width:min(440px,100%); padding:24px; border-radius:16px; box-sizing:border-box;
  background:#17100a; border:1px solid rgba(214,166,96,.30); color:#f6efdf;
  box-shadow:0 24px 60px rgba(0,0,0,.5);
}
.pn-tipsy-line{ margin:0 0 18px; font:500 15px/1.55 IS,ui-sans-serif,system-ui,sans-serif; color:#f2ead8; }
.pn-tipsy-choices{ display:flex; flex-direction:column; gap:10px; }
.pn-tipsy-btn{
  display:flex; align-items:center; justify-content:center; gap:8px;
  min-height:46px; padding:10px 16px; border-radius:10px; border:1px solid rgba(255,178,122,.4);
  background:rgba(255,178,122,.08); color:#ffd9c2; cursor:pointer;
  font:700 14px/1 IS,ui-sans-serif,system-ui,sans-serif;
}
.pn-tipsy-btn:hover{ background:rgba(255,178,122,.16); }
.pn-tipsy-btn:focus-visible{ outline:2px solid #ffd9c2; outline-offset:2px; }
.pn-tipsy-btn--acc{ background:#c2410c; border-color:#c2410c; color:#ffffff; } /* 5.18:1, house measured */
.pn-tipsy-btn--acc:hover{ background:#d4500f; }

/* the reaction-test button — big, obvious, colour + text state (never colour alone) */
.pn-tipsy-react{
  display:flex; align-items:center; justify-content:center;
  width:100%; min-height:120px; border-radius:14px; border:2px solid rgba(255,178,122,.4);
  background:rgba(255,178,122,.06); color:#ffd9c2;
  font:800 22px/1 IS,ui-sans-serif,system-ui,sans-serif; letter-spacing:.04em; cursor:pointer;
}
.pn-tipsy-react.is-go{ background:#2f9e5c; border-color:#2f9e5c; color:#ffffff; } /* AA on green */

/* ── the toast (tequila afford failures) ──────────────────────────────────────────────────────── */
.pn-tipsy-toast{
  position:fixed; left:50%; bottom:80px; transform:translateX(-50%) translateY(8px);
  z-index:2147483647; display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  max-width:min(92vw,480px); padding:12px 16px; border-radius:12px;
  background:#17100a; border:1px solid rgba(214,166,96,.30); color:#f2ead8;
  font:500 13.5px/1.4 IS,ui-sans-serif,system-ui,sans-serif;
  opacity:0; pointer-events:none; transition:opacity .18s, transform .18s;
}
.pn-tipsy-toast.is-on{ opacity:1; transform:translateX(-50%) translateY(0); pointer-events:auto; }
.pn-tipsy-note-cta{
  min-height:36px; padding:7px 14px; border-radius:10px; border:0; background:#c2410c; color:#fff;
  font:700 13px/1 IS,ui-sans-serif,system-ui,sans-serif; cursor:pointer;
}

/* ── the house-game overlay (pool), same shape as pn-pub.js's own .pnpub-game ─────────────────── */
.pn-tipsy-game{ position:fixed; inset:0; z-index:2147483646; display:flex; flex-direction:column; background:#0d0906; }
.pn-tipsy-game-bar{
  display:flex; align-items:center; justify-content:space-between; padding:10px 14px;
  background:#17100a; color:#f2ead8; font:700 12px/1 IS,ui-sans-serif,system-ui,sans-serif; letter-spacing:.08em;
}
.pn-tipsy-game-x{
  min-height:40px; padding:8px 14px; border-radius:8px; border:1px solid rgba(255,178,122,.4);
  background:transparent; color:#ffd9c2; font:700 11px/1 IS,ui-sans-serif,system-ui,sans-serif; cursor:pointer;
}
.pn-tipsy-game-frame{ flex:1; border:0; width:100%; }

@media (max-width:480px){
  .pn-tipsy-card{ padding:18px; }
  .pn-tipsy-pill{ right:10px; bottom:10px; font-size:11.5px; padding:8px 12px; }
}
