/* ═══════════════════════════════════════════════════════════════════════════
   THE ANALYTICS-CONSENT BAR: the one stylesheet, for every page.

   Markup:   templates/partials/consent_bar.html   (the only place it is drawn)
   Behaviour: static/js/analytics_ga4.js            (shows it, stores the choice,
                                                     starts analytics, sets
                                                     data-shape)
   Look:     this file. Every shell (base.html and the six React shells)
             includes the partial, so the bar cannot differ from page to page.

   The look is the Porcelain ConsentBar's (DESIGN.md §13): a solid --cls-blue
   bar floating over the bottom of the viewport, detached from the edges
   (24px gutters on a desktop, 12px on a phone), a --cls-blue-deep hairline all
   round, the Tutix mark, ink-on-accent text and two pill buttons. A PILL while
   it sits on one row; --cls-r-lg once its text wraps or it stacks (always, on
   a phone). CSS cannot see a wrap, so analytics_ga4.js writes data-shape
   ("row" | "stacked") from the laid-out boxes, the same rule lib/useRowShape
   applies to React bars. The padding depends on the width only, never on the
   shape, so that measurement can never flip back and forth.

   Only --cls-* tokens, so light and dark come from the token sheet. This file
   is written for pages whose own stylesheet may be Tailwind's preflight or a
   Porcelain bundle's, so it restates the few properties a reset could change.
   ═══════════════════════════════════════════════════════════════════════════ */

.cls-consent {
  box-sizing: border-box;
  position: fixed;
  left: 24px;
  right: 24px;
  bottom: 24px;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0;
  padding: 12px 12px 12px 24px;
  background: var(--cls-blue);
  border: 1px solid var(--cls-blue-deep);
  border-radius: var(--cls-pill);
  box-shadow: var(--cls-lit-on), 0 8px 24px -10px color-mix(in srgb, var(--cls-shadow-ink) 45%, transparent);
  color: var(--cls-on-accent);
  font-family: inherit;
  font-size: 13px;
  line-height: 1.4;
  text-align: left;
}
.cls-consent[data-shape="stacked"] {
  border-radius: var(--cls-r-lg);
}

/* the script removes .hidden to show the bar and puts it back to dismiss it */
.cls-consent.hidden {
  display: none;
}

/* A route that draws its own full-page screen (a Study quiz, a flashcard run)
   marks <html data-cls-immersive>; the bar never covers an answer. */
html[data-cls-immersive] .cls-consent {
  display: none;
}

.cls-consent-glyph {
  display: flex;
  flex: none;
  align-items: center;
}
.cls-consent-glyph img {
  display: block;
  flex: none;
}

.cls-consent-text {
  flex: 1 1 220px;
  min-width: 180px;
  font-size: 13px;
  line-height: 1.4;
}

.cls-consent-actions {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
}

.cls-consent-decline,
.cls-consent-accept {
  position: relative;
  box-sizing: border-box;
  height: 36px;
  margin: 0;
  padding: 0 14px;
  border-radius: var(--cls-pill);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 120ms cubic-bezier(0, 0, 0.2, 1);
}
/* 36px to look at, 44px to hit: the product-wide minimum touch target, drawn
   as an invisible margin so the pill itself stays the size the system draws. */
.cls-consent-decline::after,
.cls-consent-accept::after {
  content: "";
  position: absolute;
  inset: -4px -2px;
}

.cls-consent-decline {
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--cls-on-accent) 32%, transparent);
  color: var(--cls-on-accent);
}
.cls-consent-decline:hover {
  background: color-mix(in srgb, var(--cls-on-accent) 10%, transparent);
}

/* --cls-leaf + --cls-blue-ink: the "light chip, accent-coloured label" pairing
   the rest of the system uses for text on a raised surface. It adapts by mode
   (white fill and dark-blue label in light, a dark warm fill and pale-blue
   label in dark), so a solid black fill is never needed. */
.cls-consent-accept {
  background: var(--cls-leaf);
  border: 1px solid var(--cls-leaf);
  color: var(--cls-blue-ink);
}
.cls-consent-accept:hover {
  background: color-mix(in srgb, var(--cls-leaf) 88%, var(--cls-blue-ink));
}

.cls-consent-decline:focus-visible,
.cls-consent-accept:focus-visible {
  outline: 2px solid var(--cls-on-accent);
  outline-offset: 2px;
}

@media (max-width: 640px) {
  .cls-consent {
    left: 12px;
    right: 12px;
    bottom: 12px;
    flex-wrap: wrap;
    row-gap: 12px;
    padding: 12px 16px;
  }
  /* the mark stays beside the text: they share the first row, the buttons take
     the second (a full-width basis cannot fit beside them, so it wraps) */
  .cls-consent-text {
    flex: 1 1 0;
    min-width: 0;
  }
  .cls-consent-actions {
    flex: 1 0 100%;
    justify-content: flex-end;
  }
}

/* Beside the signed-in rail, not over it: the bar keeps to the content area, so
   the rail's account row and its menu stay reachable while the choice is open. */
@media (min-width: 768px) {
  body:has(.cls-shell-rail) .cls-consent {
    left: calc(var(--cls-rail-icon) + 24px);
  }
}
@media (min-width: 1200px) {
  body:has(.cls-shell-rail) .cls-consent {
    left: calc(var(--cls-rail) + 24px);
  }
}

/* Under 768px the signed-in shell has a fixed bottom tab bar; the bar floats
   12px above it instead of covering it. */
@media (max-width: 767.98px) {
  body:has(.cls-shell-tabbar) .cls-consent {
    bottom: calc(var(--cls-tabbar) + env(safe-area-inset-bottom, 0px) + 12px);
  }
}

@media print {
  .cls-consent {
    display: none !important;
  }
}
