/*
 * compliance.css — Thread 19's own styles. Kept out of site/assets/, which
 * Thread 8 owns, so that a change to the game's stylesheet can never silently
 * unhide a CTA or flatten the age modal.
 *
 * Everything here is written against tokens the site already defines, with a
 * fallback value on every var() so the file is correct on its own if it is ever
 * loaded before or without the main stylesheet. A compliance surface that
 * depends on another sheet having loaded first is a compliance surface that
 * fails open.
 */

/* --- the page frame ------------------------------------------------------ */

/* B12. The policy pages load base.css and this file and nothing else. The frame
   every other content page uses lives in rules.css, which these pages never
   load, so the text sat flush against both viewport edges at every width from
   320px to 3840px: main and article.policy both computed padding 0 and
   max-width none. The frame is declared here instead, so it travels with the
   compliance bundle and cannot be lost again by a page not loading a stylesheet
   it has no other reason to load.

   M17. The cap is --container-lg, the same step the other content surfaces use,
   from the container scale documented in base.css. The gutter padding sits on
   the article alone and the cap alone sits on main, so the two can never stack
   and pay the gutter twice. Both are stated with a literal fallback in the
   var(), per the rule at the top of this file. */
.policy-page main {
  width: 100%;
  max-width: var(--container-lg, 78rem);
  margin: 0 auto;
}

article.policy {
  width: 100%;
  max-width: var(--container-lg, 78rem);
  margin: 0 auto;
  padding: var(--space-7, 2rem) var(--gutter, 1rem) var(--space-9, 4rem);
}

/* --- the CTA contract, expressed in CSS ---------------------------------- */

/* Thread 11 markup opts in by carrying data-cta-slot. It stays hidden until the
   root element says the edge allowed a CTA. This is belt and braces, not the
   control: the /go/ gate at the edge is what actually stops the exit. But it
   means a Thread 11 regression that renders a slot unconditionally still shows
   nothing in a blocked market, and it means the no-CTA page has no gap where a
   CTA would have been rather than a hole. */
[data-cta-slot] { display: none; }
:root[data-cta-ready="1"] [data-cta-slot] { display: revert; }

/* The no-CTA state is a finished state, not an empty one. Where Thread 11 marks
   a container that would have held commercial content, this collapses it
   completely so the surrounding layout closes up. */
:root:not([data-cta-ready="1"]) [data-cta-container] { display: none; }

/* --- age gate ------------------------------------------------------------ */

.bjg-age-gate {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  padding: 1rem;
  background: rgb(0 0 0 / 0.72);
}

.bjg-age-gate__panel {
  width: min(28rem, 100%);
  padding: 1.5rem;
  border-radius: var(--radius-lg, 12px);
  background: var(--surface, #14161a);
  color: var(--text, #f2f4f7);
  box-shadow: 0 1.5rem 3rem rgb(0 0 0 / 0.5);
}

.bjg-age-gate__panel h2 { margin: 0 0 0.5rem; font-size: 1.25rem; }
.bjg-age-gate__panel p { margin: 0 0 0.75rem; line-height: 1.5; }
.bjg-age-gate__why { font-size: 0.875rem; opacity: 0.75; }

.bjg-age-gate__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1rem;
}

/* 44px minimum on both axes. A tap target on a gate that decides whether a
   minor sees a gambling link is not a place to save vertical space. */
.bjg-age-gate__actions button {
  flex: 1 1 8rem;
  min-height: 44px;
  min-width: 44px;
  padding: 0.6rem 1rem;
  font: inherit;
  border-radius: var(--radius, 8px);
  cursor: pointer;
}

/* --- responsible-gambling page ------------------------------------------ */

/* The helpline table is the whole point of the page, so it has to survive a
   360px viewport without horizontal scroll on the document. The wrapper scrolls,
   the page does not. */
/* N6. The scrollbar stays visible rather than being left to the platform to
   hide, and site.js adds the edge fade, the accessible name and the tabindex
   that makes the region scrollable from the keyboard. Same treatment as
   rules.css, restated because these pages do not load that file. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--border-ui, rgb(255 255 255 / 0.45)) transparent;
}
.table-wrap[data-scroll="end"] {
  -webkit-mask-image: linear-gradient(to right, transparent, black 2rem);
          mask-image: linear-gradient(to right, transparent, black 2rem);
}
.table-wrap[data-scroll="start"] {
  -webkit-mask-image: linear-gradient(to left, transparent, black 2rem);
          mask-image: linear-gradient(to left, transparent, black 2rem);
}
.table-wrap[data-scroll="both"] {
  -webkit-mask-image: linear-gradient(to right, transparent, black 2rem,
                                     black calc(100% - 2rem), transparent);
          mask-image: linear-gradient(to right, transparent, black 2rem,
                                     black calc(100% - 2rem), transparent);
}
.table-wrap:focus-visible {
  outline: 2px solid var(--focus, #7cc6ff);
  outline-offset: 2px;
}

.helplines, .cookies {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.helplines caption, .cookies caption {
  text-align: left;
  padding-bottom: 0.5rem;
  opacity: 0.8;
}

.helplines th, .helplines td, .cookies th, .cookies td {
  padding: 0.5rem 0.75rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border, rgb(255 255 255 / 0.12));
}

/* M15. Links inside running policy prose keep their line box and gain the
   tappable area through vertical padding on the inline box, which does not shift
   the paragraph and does not loosen the leading. */
.policy :is(p, li, dd, dt) a {
  padding-block: calc((var(--tap-min, 2.75rem) - 1em) / 2);
}

/* Thirteen helpline links measured 20px tall. A helpline number is the single
   most important standalone action on the page, so each one is a real 44px
   target instead. This block comes after the prose rule and cancels its padding,
   so a link never gets both treatments and ends up 66px tall. */
.helplines a,
.own-helpline a,
.policy-crosslink a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min, 2.75rem);
  padding-block: 0;
}

.helplines [data-own-market="1"] {
  background: var(--accent-soft, rgb(120 190 255 / 0.12));
}

.own-market-note {
  display: block;
  font-size: 0.8125rem;
  font-weight: 400;
  opacity: 0.85;
}

/* A mandated warning is quoted verbatim in its own language. No italics, no
   decorative quote marks that a screen reader will read out, nothing that could
   be mistaken for our own paraphrase. */
.statutory-notices { padding-left: 1.25rem; }
.statutory-notices li { margin-bottom: 0.5rem; line-height: 1.5; }
.statutory-notices q { quotes: none; display: block; }

.operator-block { margin-top: 2rem; }
.operator-id { margin: 0; }
.operator-id .kv { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.35rem; }
.operator-id dt { font-weight: 600; min-width: 11rem; }
.operator-id dd { margin: 0; }

.policy .lede { font-size: 1.0625rem; line-height: 1.6; }
.policy-updated { margin-top: 2rem; font-size: 0.875rem; opacity: 0.75; }
.policy-crosslink { margin-top: 1.5rem; }

@media (prefers-reduced-motion: reduce) {
  .bjg-age-gate { animation: none; }
}

/* --- promoted single helpline (responsible-gambling page) ----------------- */
/* The visitor's own helpline, lifted out of the all-markets table by
   compliance.js. Ships hidden and empty, so with JavaScript off the page falls
   back to the full table with nothing missing. */
.own-helpline {
  margin: 1.5rem 0;
  padding: 1rem 1.25rem;
  border-left: 4px solid var(--accent, #2f9e6b);
  background: var(--surface-2, rgba(255, 255, 255, 0.04));
  border-radius: 4px;
}

.own-helpline h3 {
  margin: 0 0 0.35rem;
  font-size: 1rem;
}

.own-helpline__body {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.75rem;
  font-size: 1.0625rem;
  line-height: 1.5;
}

.own-helpline__part:first-child {
  font-weight: 600;
  flex-basis: 100%;
}

.own-helpline__fallback {
  margin: 1.5rem 0 0.5rem;
}

.helplines-all {
  margin: 1rem 0 1.5rem;
}

.helplines-all > summary {
  cursor: pointer;
  padding: 0.65rem 0;
  min-height: 44px;
  display: flex;
  align-items: center;
}

/* Methodology tables (Thread 16). The rubric renders from
   data/scoring_weights.json, so a column can gain a long label after a weight
   change. The scroll wrapper is what stops that becoming horizontal page scroll
   on a 360px viewport. */
.table-scroll {
  overflow-x: auto;
  margin: 0 0 1.5rem;
  -webkit-overflow-scrolling: touch;
}

.rubric {
  width: 100%;
  min-width: 22rem;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.rubric th, .rubric td {
  padding: 0.5rem 0.75rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border, rgb(255 255 255 / 0.12));
}

.rubric thead th { font-weight: 500; opacity: 0.8; }
.rubric tbody th { font-weight: 500; }
.rubric .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rubric tr.total th, .rubric tr.total td {
  border-top: 1px solid var(--border, rgb(255 255 255 / 0.24));
  border-bottom: 0;
  font-weight: 600;
}

.byline { margin-top: 1.5rem; font-size: 0.875rem; opacity: 0.8; }
.byline p { margin: 0 0 0.35rem; }
.natext { font-size: 0.875rem; opacity: 0.75; }
/* The entry gate is the same panel as the exit gate with one difference: it is
   the condition of entry, so it has no dismiss control and its backdrop is
   opaque enough to make that obvious. The page underneath is untouched and stays
   in the rendered DOM, which is what build/seo_guard.py checks for. */
.bjg-age-gate--entry {
  background: rgba(8, 10, 14, 0.94);
}

.bjg-age-gate--entry .bjg-age-gate__actions a {
  display: inline-block;
  padding: 0.65rem 1.1rem;
  border-radius: 8px;
  border: 1px solid currentColor;
  text-decoration: none;
  font-weight: 600;
}
