/*!
 * CMP SDK — Stylesheet (cmp.css) v1.0.0
 * All visual tokens are CSS custom properties, overridden at runtime by cmp-ui.js.
 */

/* ─────────────────────────────────────────────────────────────────────────
   Design tokens (defaults — overridden by theme from API)
   ───────────────────────────────────────────────────────────────────────── */
:root {
  --cmp-primary:     #5b5ef4;
  --cmp-primary-hov: #4240d4;
  --cmp-accent:      #22d3a0;
  --cmp-bg:          #ffffff;
  --cmp-bg-2:        #f8f8fc;
  --cmp-bg-3:        #f0f0f8;
  --cmp-text:        #111827;
  --cmp-text-muted:  #6b7280;
  --cmp-border:      #e5e7eb;
  --cmp-radius:      14px;
  --cmp-radius-sm:   8px;
  --cmp-shadow:      0 4px 24px rgba(0,0,0,.10), 0 1px 4px rgba(0,0,0,.06);
  --cmp-shadow-lg:   0 8px 40px rgba(0,0,0,.14), 0 2px 8px rgba(0,0,0,.06);
  --cmp-font:        system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --cmp-z:           2147483640;
  --cmp-transition:  220ms cubic-bezier(.4,0,.2,1);
}

/* ─────────────────────────────────────────────────────────────────────────
   Reset scope — keep styles isolated
   ───────────────────────────────────────────────────────────────────────── */
.cmp-banner, .cmp-fab, .cmp-overlay, .cmp-modal {
  box-sizing: border-box;
  font-family: var(--cmp-font);
  font-size:   15px;
  line-height: 1.5;
  color:       var(--cmp-text);
  -webkit-font-smoothing: antialiased;
}
.cmp-banner *, .cmp-fab *, .cmp-overlay *, .cmp-modal * {
  box-sizing: border-box;

  /* Defensive reset against host-page typography. Integrators routinely style
     bare element selectors globally -- `p { max-width: 65ch }` for a readable
     measure, `h1..h6 { font-family: <brand>; text-wrap: balance }` for headings
     -- and those selectors match the nodes we inject just as happily as their
     own content. We can't ask every site to scope its CSS, so we defend here.

     The cascade does NOT sort this out on its own: a property we never declare
     has nothing on our side to win with, so the host's rule applies unopposed.
     That is what made a 65ch measure squeeze the notice copy into a narrow
     column and leave a large empty gutter down the side of the banner.

     Only properties a host is likely to set on element selectors are listed,
     and every value is our own default -- never a magic number. This block
     stays at the TOP of the file on purpose: it is specificity (0,1,0), the
     same as the component rules below, so any component that declares one of
     these for itself still wins on source order. Add to this list rather than
     patching individual components. */
  max-width:      none;
  min-width:      0;
  float:          none;
  font-family:    inherit;
  line-height:    inherit;
  letter-spacing: normal;
  word-spacing:   normal;
  text-indent:    0;
  text-transform: none;
  text-wrap:      wrap;

  /* Paint properties, same rationale as the typography above. A host that
     resets its own controls -- `button { background: none }` is in Tailwind's
     preflight, Bootstrap's reboot and most hand-rolled resets -- matches our
     injected <button> too, and .cmp-btn--primary's background disappears while
     its `color:#fff` survives: a white button with white, invisible text and
     only the border left to see. Every value here is the CSS initial, so this
     changes nothing on a clean page; it only gives us something to win with.
     Component rules below declare their own and win on source order. */
  background:  none;
  color:       inherit;
  box-shadow:  none;
  text-shadow: none;
}

/* Hand cursor on everything clickable. Browsers give <button>, <select> and
   checkboxes the ARROW by default — only <a href> gets the hand for free — so
   every interactive control in the SDK opts in here rather than each component
   remembering to. Scoped to the SDK roots so we never touch the host page.
   <label> is deliberately absent: adding it here (specificity 0,1,1) would beat
   .cmp-toggle__slider--locked (0,1,0) and put a hand on essential purpose
   toggles that can't be switched. The two clickable labels we do have —
   .cmp-toggle__slider and .cmp-age-gate — already set pointer themselves. */
.cmp-banner button,  .cmp-overlay button,  .cmp-modal button,  .cmp-fab,
.cmp-banner a[href], .cmp-overlay a[href], .cmp-modal a[href],
.cmp-banner select,  .cmp-overlay select,  .cmp-modal select,
.cmp-banner input[type="checkbox"],
.cmp-overlay input[type="checkbox"],
.cmp-modal input[type="checkbox"],
.cmp-banner input[type="radio"],
.cmp-overlay input[type="radio"],
.cmp-modal input[type="radio"],
.cmp-banner [role="button"], .cmp-overlay [role="button"], .cmp-modal [role="button"] {
  cursor: pointer;
}
/* …but a control you can't use shouldn't invite the click. */
.cmp-banner button:disabled,  .cmp-overlay button:disabled,  .cmp-modal button:disabled,
.cmp-banner select:disabled,  .cmp-overlay select:disabled,  .cmp-modal select:disabled,
.cmp-banner input:disabled,   .cmp-overlay input:disabled,   .cmp-modal input:disabled,
.cmp-banner [aria-disabled="true"],
.cmp-overlay [aria-disabled="true"],
.cmp-modal [aria-disabled="true"] {
  cursor: not-allowed;
}

/* ─────────────────────────────────────────────────────────────────────────
   Banner
   ───────────────────────────────────────────────────────────────────────── */
/* Full-bleed bar: spans the whole viewport width and sits flush against the
   edge it is anchored to, so it reads as a band across the page rather than a
   floating card. Only the edge facing the page content carries a rule; the
   corners stay square because a radius on a full-width bar leaves a sliver of
   page showing through at the very edge. */
.cmp-banner {
  position:   fixed;
  left:       0;
  right:      0;
  width:      100%;
  z-index:    var(--cmp-z);
  background: var(--cmp-bg);
  border:     0;
  border-radius: 0;
  box-shadow: var(--cmp-shadow-lg);
  padding:    18px 32px;
  max-width:  none;
  margin:     0;

  /* Entry animation */
  opacity:    0;
  transition: opacity var(--cmp-transition), transform var(--cmp-transition);
}

.cmp-banner--bottom {
  bottom: 0;
  top:    auto;
  border-top: 1px solid var(--cmp-border);
  transform: translateY(12px);
}
.cmp-banner--top {
  top:    0;
  bottom: auto;
  border-bottom: 1px solid var(--cmp-border);
  transform: translateY(-12px);
}

/* The banner and modal are focused programmatically (tabindex="-1") purely to
   move the reading position when they open. Chrome treats that as keyboard focus
   and paints its default ring, which on a full-width bar reads as a stray black
   box drawn around the whole page edge. Suppress it here — neither element is
   keyboard-reachable, so no real focus indicator is lost; every control INSIDE
   them keeps its own :focus-visible ring. */
.cmp-banner:focus, .cmp-banner:focus-visible,
.cmp-modal:focus,  .cmp-modal:focus-visible {
  outline: none;
}

/* Content measure inside the full-width bar — centred, so the copy does not run
   the entire width of a wide monitor. */
.cmp-banner__container {
  width:     100%;
  max-width: 1200px;
  margin:    0 auto;
}
.cmp-banner--bottom.cmp-banner--visible,
.cmp-banner--top.cmp-banner--visible {
  opacity:   1;
  transform: translateY(0);
}

/* Top bar: brand (logo + company name) on left, language select on right */
.cmp-banner__top {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             12px;
  padding-bottom:  10px;
  margin-bottom:   14px;
  border-bottom:   1px solid var(--cmp-border);
}
.cmp-banner__brand {
  display:     flex;
  align-items: center;
  gap:         8px;
  min-width:   0;
  flex:        1;          /* take remaining space so lang-select stays compact */
}
.cmp-banner__company {
  font-size:     14px;
  font-weight:   600;
  color:         var(--cmp-text);
  white-space:   nowrap;
  overflow:      hidden;
  text-overflow: ellipsis;
}
/* Language picker in the top bar must NOT stretch */
.cmp-banner__top .cmp-lang__trigger {
  width:     auto;
  min-width: 90px;
  max-width: 150px;
}

/* One row on a wide bar: notice copy on the left, actions hugging the right.
   Both are flex items with a basis, so when the copy can no longer hold its
   420px measure the buttons wrap onto their own row on their own — no media
   query needed for the in-between widths. */
.cmp-banner__inner {
  display:        flex;
  flex-direction: row;
  align-items:    center;
  justify-content: space-between;
  flex-wrap:      wrap;
  gap:            14px 32px;
}

.cmp-banner__text {
  flex:      1 1 420px;
  min-width: 0;
}

/* Logo when inside the top brand bar */
.cmp-banner__logo {
  display:       block;
  height:        24px;
  width:         auto;
  flex-shrink:   0;
  margin-bottom: 0;
}

.cmp-banner__title {
  margin:      0 0 6px;
  font-size:   16px;
  font-weight: 600;
  line-height: 1.3;
  color:       var(--cmp-text);
}

.cmp-banner__body {
  margin:     0;
  font-size:  14px;
  color:      var(--cmp-text-muted);
  line-height: 1.55;
  /* Admins type notice copy as multi-line text (numbered lists, paragraphs) and
     it is stored verbatim in body_text. HTML would collapse those newlines into
     spaces, running the whole notice together on one line. `pre-line` keeps the
     line breaks while still collapsing accidental double spaces and wrapping
     normally — do not change this to `pre`, which would also stop wrapping. */
  white-space: pre-line;
}

/* Cookie policy link at the end of the banner copy — it reads as part of the
   sentence flow, so it keeps the body's size and wraps inline with it. */
.cmp-banner__policy-link {
  display:         inline;
  font-size:       14px;
  font-weight:     500;
  color:           var(--cmp-primary);
  text-decoration: none;
  transition:      color var(--cmp-transition);
}
.cmp-banner__policy-link:hover {
  color:           var(--cmp-primary-hov);
  text-decoration: underline;
}

.cmp-banner__actions {
  display:    flex;
  align-items: center;
  gap:        10px;
  flex-wrap:  wrap;             /* buttons wrap onto a new line among themselves if needed */
  flex:       0 0 auto;         /* sized by its buttons — never stretched by the row */
  justify-content: flex-end;    /* hug the right edge of the bar */
}

/* ─────────────────────────────────────────────────────────────────────────
   Buttons
   ───────────────────────────────────────────────────────────────────────── */
.cmp-btn {
  display:       inline-flex;
  align-items:   center;
  justify-content: center;
  text-align:    center;
  padding:       9px 20px;
  border-radius: var(--cmp-radius-sm);
  font-family:   var(--cmp-font);
  font-size:     14px;
  font-weight:   500;
  line-height:   1.3;
  cursor:        pointer;
  border:        1.5px solid transparent;
  white-space:   normal;        /* long translated labels wrap inside the button, not past it */
  word-break:    break-word;
  /* min-content, NOT max-content. max-content is the label laid out on ONE line
     with no wrapping, so it forced the button to be at least as wide as the whole
     string -- and because min-width always beats max-width, the `max-width:100%`
     below could never take effect and `white-space:normal` never got the chance
     to wrap. A long translated label (Tamil "எல்லாவற்றையும் நிராகரிக்கவும்.")
     therefore spilled straight out of the footer. min-content is the longest
     unbreakable token, which is what the floor was always meant to be. */
  min-width:     min-content;
  max-width:     100%;          /* never grow past the available row width */
  flex:          0 1 auto;
  transition:    border-color var(--cmp-transition), box-shadow var(--cmp-transition),
                 transform var(--cmp-transition), opacity var(--cmp-transition);
  text-decoration: none;
}
.cmp-btn:focus-visible {
  outline:       2px solid var(--cmp-primary);
  outline-offset: 2px;
}

/* Doubled class (0,2,0) on purpose, not a typo. Host resets reach our buttons
   through ATTRIBUTE selectors, which carry class-level specificity: Tailwind's
   preflight ships `button, [type='button'], [type='reset'], [type='submit']
   { background-color: transparent; background-image: none }`, and every button
   we build sets type="button". [type='button'] is (0,1,0) — an exact tie with a
   single .cmp-btn--primary — so the winner is decided by source order, and a
   bundler that injects the host's CSS after our <link> takes it. Only the
   background is in that rule, so `color:#fff` survives and the control renders
   as a blank white box with invisible white text. Two classes put us out of
   reach of any single-class or attribute selector regardless of load order. */
.cmp-btn.cmp-btn--primary {
  background: var(--cmp-primary);
  color:      #ffffff;
  border-color: var(--cmp-primary);
}
.cmp-btn--primary:hover  { box-shadow: 0 2px 10px rgba(0,0,0,.16); transform: translateY(-1px); }
.cmp-btn--primary:active { opacity: .9; transform: translateY(0); }

.cmp-btn--secondary {
  background: transparent;
  color:      var(--cmp-primary);
  border-color: var(--cmp-primary);
}
.cmp-btn--secondary:hover  { border-width: 2px; padding: 8.5px 19.5px; }
.cmp-btn--secondary:active { opacity: .85; }

.cmp-btn--ghost {
  background:   transparent;
  color:        var(--cmp-text-muted);
  border-color: var(--cmp-border);
}
.cmp-btn--ghost:hover  { border-color: var(--cmp-text-muted); }

.cmp-btn--save {
  /* distinct from secondary for clarity */
  font-weight: 500;
}

/* ─────────────────────────────────────────────────────────────────────────
   Floating action button
   ───────────────────────────────────────────────────────────────────────── */
.cmp-fab {
  position:      fixed;
  z-index:       var(--cmp-z);
  display:       inline-flex;
  align-items:   center;
  gap:           6px;
  background:    var(--cmp-primary);
  color:         #fff;
  border:        none;
  border-radius: 50px;
  padding:       10px 14px 10px 12px;
  cursor:        pointer;
  box-shadow:    var(--cmp-shadow);
  font-family:   var(--cmp-font);
  font-size:     12px;
  font-weight:   600;
  letter-spacing: .02em;
  opacity:       0;
  pointer-events: none;
  transition:    opacity var(--cmp-transition), transform var(--cmp-transition),
                 background var(--cmp-transition);
  /* Reduced-motion */
  transform:     scale(.85);
}
/* Same host-preflight tie as .cmp-btn.cmp-btn--primary above — the FAB is a
   <button type="button"> too, so [type='button']{background-color:transparent}
   ties .cmp-fab at (0,1,0) and wins on source order, leaving a shadow outline
   with white text and no fill. Doubled class for the PAINT ONLY: lifting the
   whole .cmp-fab block to (0,2,0) would also raise its `opacity:0` above
   .cmp-fab--visible (0,1,0) and the button would never fade in. */
.cmp-fab.cmp-fab { background: var(--cmp-primary); }
.cmp-fab--visible {
  opacity:        1;
  pointer-events: auto;
  transform:      scale(1);
}
.cmp-fab:hover  { box-shadow: 0 4px 18px rgba(0,0,0,.22); transform: scale(1.04); }
.cmp-fab:active { transform: scale(.98); }
.cmp-fab:focus-visible { outline: 2px solid var(--cmp-primary); outline-offset: 3px; }

.cmp-fab svg {
  width:  18px;
  height: 18px;
  flex-shrink: 0;
}

.cmp-fab__label { white-space: nowrap; }

/* Positions */
.cmp-fab--bottom-left   { bottom: 20px; left:  20px; }
.cmp-fab--bottom-right  { bottom: 20px; right: 20px; }
.cmp-fab--top-left      { top: 20px;    left:  20px; }
.cmp-fab--top-right     { top: 20px;    right: 20px; }

/* ─────────────────────────────────────────────────────────────────────────
   Overlay & Modal
   ───────────────────────────────────────────────────────────────────────── */
.cmp-overlay {
  position:   fixed;
  inset:      0;
  z-index:    var(--cmp-z);
  background: rgba(0,0,0,.38);
  display:    flex;
  align-items: center;
  justify-content: center;
  padding:    16px;
  opacity:    0;
  pointer-events: none;
  transition: opacity var(--cmp-transition);
}
.cmp-overlay--visible {
  opacity:        1;
  pointer-events: auto;
}

.cmp-modal {
  background:    var(--cmp-bg);
  border-radius: var(--cmp-radius);
  box-shadow:    var(--cmp-shadow-lg);
  width:         100%;
  max-width:     680px;
  max-height:    88vh;
  display:       flex;
  flex-direction: column;
  transform:     scale(.95) translateY(10px);
  transition:    transform var(--cmp-transition);
  overflow:      hidden;
}
.cmp-modal--visible {
  transform: scale(1) translateY(0);
}

/* Header */
.cmp-modal__header {
  display:       flex;
  align-items:   center;
  justify-content: space-between;
  padding:       18px 24px 14px;
  border-bottom: 1px solid var(--cmp-border);
  flex-shrink:   0;
}
.cmp-modal__header-left {
  display:    flex;
  align-items: center;
  gap:        10px;
}
.cmp-modal__header-right {
  display:    flex;
  align-items: center;
  gap:        8px;
  flex-shrink: 0;
}
.cmp-modal__logo {
  height: 24px;
  width:  auto;
}
.cmp-modal__title {
  margin:      0;
  font-size:   17px;
  font-weight: 700;
  color:       var(--cmp-text);
}
.cmp-modal__close {
  width:      32px;
  height:     32px;
  display:    flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border:     none;
  border-radius: 6px;
  cursor:     pointer;
  color:      var(--cmp-text-muted);
  flex-shrink: 0;
  transition: background var(--cmp-transition), color var(--cmp-transition);
}
.cmp-modal__close:hover { box-shadow: inset 0 0 0 1.5px var(--cmp-border); }
.cmp-modal__close svg   { width: 18px; height: 18px; }

/* Tabs */
.cmp-tabs {
  display:       flex;
  gap:           2px;
  padding:       0 24px;
  border-bottom: 1px solid var(--cmp-border);
  background:    var(--cmp-bg);
  flex-shrink:   0;
  overflow-x:    auto;
}
.cmp-tab {
  padding:        10px 14px;
  font-family:    var(--cmp-font);
  font-size:      13px;
  font-weight:    500;
  color:          var(--cmp-text-muted);
  background:     transparent;
  border:         none;
  border-bottom:  2.5px solid transparent;
  cursor:         pointer;
  white-space:    nowrap;
  transition:     color var(--cmp-transition), border-color var(--cmp-transition);
  margin-bottom:  -1px;
}
.cmp-tab:hover       { border-bottom-color: var(--cmp-border); }
.cmp-tab--active     { color: var(--cmp-primary); border-bottom-color: var(--cmp-primary); }
.cmp-tab:focus-visible { outline: 2px solid var(--cmp-primary); outline-offset: -2px; border-radius: 4px; }

/* Content */
.cmp-modal__content {
  flex:      1;
  /* A flex item's automatic minimum size would otherwise be its content height,
     so the body could push past the modal's max-height and get clipped by
     .cmp-modal{overflow:hidden} instead of scrolling. */
  min-height: 0;
  overflow-y: auto;
  padding:   20px 24px;
  overscroll-behavior: contain;
}

/* Footer */
.cmp-modal__footer {
  display:       flex;
  align-items:   center;
  justify-content: flex-end;
  gap:           8px;
  padding:       14px 24px;
  border-top:    1px solid var(--cmp-border);
  flex-shrink:   0;
  flex-wrap:     wrap;
  background:    var(--cmp-bg);
}
.cmp-modal__footer-left {
  /* grow to push Save/Accept to the right, but flex-basis AUTO, not 0.
     `flex: 1` is basis:0 -- the group claimed zero width, so it never counted
     toward the row and never tripped the footer's flex-wrap; its button then
     overflowed on top of the Save button beside it. Visible only once a label
     got long (Tamil "எல்லாவற்றையும் நிராகரிக்கவும்." vs "Reject all").
     min-width:0 keeps it able to shrink so the button wraps instead of pushing
     the row wider. */
  flex: 1 1 auto;
  min-width: 0;
}

/* ─────────────────────────────────────────────────────────────────────────
   Preferences tab — purpose cards
   ───────────────────────────────────────────────────────────────────────── */
.cmp-pref__intro {
  margin:     0 0 16px;
  font-size:  13px;
  color:      var(--cmp-text-muted);
  line-height: 1.6;
}

.cmp-purpose-card {
  display:       flex;
  flex-direction: column;
  padding:       0;
  border-radius: var(--cmp-radius-sm);
  border:        1px solid var(--cmp-border);
  background:    var(--cmp-bg);
  margin-bottom: 10px;
  transition:    border-color var(--cmp-transition), background var(--cmp-transition);
}
.cmp-purpose-card:last-child { margin-bottom: 0; }
.cmp-purpose-card--essential { background: var(--cmp-bg-2); }

.cmp-purpose__info { flex: 1; min-width: 0; }

/* Level 1 — category head row (arrow · name · toggle) */
.cmp-cat__head {
  display:     flex;
  align-items: center;
  gap:         12px;
  padding:     14px 16px;
}
.cmp-cat__arrow {
  flex:        0 0 auto;
  display:     inline-flex;
  align-items: center;
  justify-content: center;
  width:       22px;
  height:      22px;
  padding:     0;
  border:      none;
  background:  none;
  color:       var(--cmp-text-muted);
  cursor:      pointer;
  border-radius: 4px;
  transition:  transform var(--cmp-transition), color var(--cmp-transition);
}
.cmp-cat__arrow:hover { color: var(--cmp-text); }
.cmp-cat__head--open .cmp-cat__arrow { transform: rotate(90deg); }
.cmp-cat__label {
  flex:        1;
  min-width:   0;
  display:     inline-flex;
  align-items: center;
  gap:         8px;
  cursor:      pointer;
}
.cmp-cat__count {
  font-size:   12px;
  font-weight: 500;
  color:       var(--cmp-text-muted);
}

.cmp-purpose__name {
  display:    inline-flex;
  align-items: center;
  gap:        8px;
  font-weight: 600;
  font-size:  14px;
  color:      var(--cmp-text);
}

/* Level 2 — collapsible body, indented under the arrow/name */
.cmp-cat__body {
  padding: 0 16px 14px 50px;
}
.cmp-cat__cookies-btn {
  /* block, not the button default inline-block: this sits directly after the
     vendors toggle, and as inline-block the two ran together on one line. */
  display:         block;
  background:      none;
  border:          none;
  font-family:     var(--cmp-font);
  font-size:       12px;
  font-weight:     600;
  color:           var(--cmp-primary);
  cursor:          pointer;
  padding:         4px 0;
  text-align:      left;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cmp-cat__cookies-btn:hover { text-underline-offset: 4px; }

/* Level 3 — cookie detail cards */
.cmp-cookies {
  margin-top:     10px;
  display:        flex;
  flex-direction: column;
  gap:            8px;
}
.cmp-cookies--hidden { display: none; }
.cmp-cookie {
  border:        1px solid var(--cmp-border);
  border-radius: var(--cmp-radius-sm);
  background:    var(--cmp-bg);
  padding:       10px 12px;
}
.cmp-cookie__row {
  display:   flex;
  gap:       10px;
  padding:   2px 0;
  font-size: 12px;
  line-height: 1.5;
}
.cmp-cookie__label {
  flex:        0 0 84px;
  font-weight: 600;
  color:       var(--cmp-text-muted);
}
.cmp-cookie__value {
  flex:       1;
  min-width:  0;
  color:      var(--cmp-text);
  word-break: break-word;
}
.cmp-cookie__value--mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:   11.5px;
}

.cmp-purpose__desc {
  margin:    0 0 6px;
  font-size: 13px;
  color:     var(--cmp-text-muted);
}

.cmp-meta {
  display:  flex;
  gap:      8px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.cmp-meta__item {
  font-size:     11px;
  color:         var(--cmp-text-muted);
  background:    var(--cmp-bg-3);
  padding:       2px 8px;
  border-radius: 4px;
}

/* Badges */
.cmp-badge {
  display:       inline-flex;
  align-items:   center;
  font-size:     11px;
  font-weight:   600;
  padding:       2px 8px;
  border-radius: 4px;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.cmp-badge--essential {
  background: rgba(34,211,160,.12);
  color:      #0e9063;
}

/* Expand vendors button */
.cmp-expand-btn {
  display:      block;           /* own line — see .cmp-cat__cookies-btn */
  background:   none;
  border:       none;
  font-family:  var(--cmp-font);
  font-size:    12px;
  color:        var(--cmp-primary);
  cursor:       pointer;
  padding:      2px 0;
  margin-top:   8px;             /* breathing room after the meta chips */
  text-align:   left;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.cmp-expand-btn:hover { text-underline-offset: 4px; }

.cmp-vendor-list {
  list-style: none;
  margin:     6px 0 0;
  padding:    0 0 0 12px;
  border-left: 2px solid var(--cmp-border);
}
.cmp-vendor-list--hidden { display: none; }
.cmp-vendor-item {
  font-size: 12px;
  color:     var(--cmp-text-muted);
  padding:   2px 0;
}
.cmp-vendor-item__link {
  color:                 var(--cmp-primary);
  text-decoration:       underline;
  text-underline-offset: 2px;
}
.cmp-vendor-item__link:hover { text-underline-offset: 4px; }

/* Tracker table */
.cmp-tracker-wrap {
  overflow-x: auto;
  margin-top: 8px;
}
.cmp-tracker-table {
  width:           100%;
  border-collapse: collapse;
  font-size:       12px;
}
.cmp-tracker-table th,
.cmp-tracker-table td {
  text-align:    left;
  padding:       5px 10px;
  border-bottom: 1px solid var(--cmp-border);
}
.cmp-tracker-table th {
  font-weight: 600;
  color:       var(--cmp-text-muted);
  font-size:   11px;
  text-transform: uppercase;
  letter-spacing: .04em;
  background:  var(--cmp-bg-2);
}

/* ─────────────────────────────────────────────────────────────────────────
   Toggle switch
   ───────────────────────────────────────────────────────────────────────── */
.cmp-toggle {
  position:   relative;
  flex-shrink: 0;
  width:       44px;
  height:      24px;
  margin-top:  2px;
}

.cmp-toggle__input {
  position: absolute;
  opacity:  0;
  width:    0;
  height:   0;
}

.cmp-toggle__slider {
  position:      absolute;
  inset:         0;
  background:    var(--cmp-border);
  border-radius: 999px;
  cursor:        pointer;
  transition:    background var(--cmp-transition);
}
.cmp-toggle__slider::before {
  content:    "";
  position:   absolute;
  width:      18px;
  height:     18px;
  left:       3px;
  top:        3px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,.18);
  transition: transform var(--cmp-transition);
}
.cmp-toggle__input:checked + .cmp-toggle__slider {
  background: var(--cmp-primary);
}
.cmp-toggle__input:checked + .cmp-toggle__slider::before {
  transform: translateX(20px);
}
.cmp-toggle__slider--locked {
  opacity: .5;
  cursor:  not-allowed;
}
.cmp-toggle__input:focus-visible + .cmp-toggle__slider {
  outline:        2px solid var(--cmp-primary);
  outline-offset: 2px;
}

/* ─────────────────────────────────────────────────────────────────────────
   Consent log tab
   ───────────────────────────────────────────────────────────────────────── */
.cmp-consent-log__id {
  font-size:   12px;
  color:       var(--cmp-text-muted);
  font-family: monospace;
  margin:      0 0 14px;
  word-break:  break-all;
}

.cmp-consent-table {
  width:           100%;
  border-collapse: collapse;
  font-size:       13px;
}
.cmp-consent-table th,
.cmp-consent-table td {
  text-align:    left;
  padding:       9px 12px;
  border-bottom: 1px solid var(--cmp-border);
}
.cmp-consent-table th {
  font-weight: 600;
  font-size:   12px;
  color:       var(--cmp-text-muted);
  text-transform: uppercase;
  letter-spacing: .04em;
  background:  var(--cmp-bg-2);
}
.cmp-consent-table tr:last-child td { border-bottom: none; }

/* ─────────────────────────────────────────────────────────────────────────
   Language picker — globe trigger + grid popover
   Replaces the old <select> (.cmp-language-select, removed): 22 DPDP languages
   read better as a 3-column grid of autonyms than as a native option list.
   ───────────────────────────────────────────────────────────────────────── */
.cmp-lang {
  position:    relative;
  flex-shrink: 0;
}

.cmp-lang__trigger {
  display:       inline-flex;
  align-items:   center;
  gap:           7px;
  height:        36px;
  max-width:     170px;
  padding:       0 10px 0 12px;
  border:        1px solid var(--cmp-border);
  border-radius: var(--cmp-radius-sm);
  background:    var(--cmp-bg);
  color:         var(--cmp-text);
  font-family:   var(--cmp-font);
  font-size:     13px;
  font-weight:   600;
  transition:    border-color var(--cmp-transition), box-shadow var(--cmp-transition);
}
.cmp-lang__trigger:hover { border-color: var(--cmp-text-muted); }
.cmp-lang__trigger:focus-visible {
  outline:      none;
  border-color: var(--cmp-primary);
  box-shadow:   0 0 0 3px rgba(91,94,244,.12);
}
.cmp-lang__globe { display: flex; flex-shrink: 0; color: var(--cmp-text-muted); }
.cmp-lang__globe svg { width: 16px; height: 16px; }
.cmp-lang__label {
  flex:          1;
  min-width:     0;
  overflow:      hidden;
  text-overflow: ellipsis;
  white-space:   nowrap;
  text-align:    left;
}
.cmp-lang__caret {
  display:     flex;
  flex-shrink: 0;
  color:       var(--cmp-text-muted);
  transition:  transform var(--cmp-transition);
}
.cmp-lang__caret svg { width: 14px; height: 14px; }
.cmp-lang--open .cmp-lang__caret { transform: rotate(180deg); }

/* Shell: does NOT scroll. It owns the frame + the bottom fade, so the fade can
   stay pinned to the edge while the options scroll underneath it. .cmp-lang__list
   inside is the scroll container. */
.cmp-lang__panel {
  position:      absolute;
  top:           calc(100% + 8px);
  right:         0;
  z-index:       5;
  width:         max-content;
  /* Four chips per row. Widened to match: at the old 340px cap four columns
     would be ~74px each and most autonyms (മലയാളം, মৈতৈলোন্, संस्कृतम्) would
     ellipsise. 440px keeps each column at ~99px — the same chip width three
     columns had — so nothing truncates that didn't before. */
  min-width:     340px;
  max-width:     min(440px, 92vw);
  overflow:      hidden;          /* clip the list's corners to the radius */
  border:        1px solid var(--cmp-border);
  border-radius: 14px;
  background:    var(--cmp-bg);
  box-shadow:    var(--cmp-shadow-lg);
  /* closed state — kept in the DOM so _cmpSetLang can patch it in place */
  opacity:        0;
  visibility:     hidden;
  transform:      translateY(-4px);
  pointer-events: none;
  transition:     opacity var(--cmp-transition), transform var(--cmp-transition),
                  visibility var(--cmp-transition);
}
.cmp-lang--open .cmp-lang__panel {
  opacity:        1;
  visibility:     visible;
  transform:      translateY(0);
  pointer-events: auto;
}

/* The scrolling grid. Long language lists scroll inside the popover rather than
   pushing it past the banner / modal, which clip their overflow. */
.cmp-lang__list {
  /* Explicit, NOT inherited from the defensive reset at the top of this file:
     that reset only covers `.cmp-banner *, .cmp-fab *, .cmp-overlay *,
     .cmp-modal *`, and the notice popup renders under .cmp-nt-overlay, which is
     none of those. Under content-box the max-height fitPanel() sets excludes
     this padding, so the panel came out 20px taller than the space measured for
     it and clipped anyway. */
  box-sizing:    border-box;
  display:       grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap:           8px;
  /* Ceiling only. The real limit is set per-open by fitPanel() in cmp-ui.js,
     which clamps this to the space actually below the trigger — a fixed height
     is what let the panel run past the viewport edge, where the last row was
     unreachable because the scroll container itself was off-screen. With room
     to spare all 6 rows show at once; where it is tight the list scrolls, and
     the rail + fade below say so. */
  max-height:    300px;
  overflow-y:    auto;
  overscroll-behavior: contain;
  padding:       10px;
  /* A visible rail is half the affordance. Reserve its width so adding it never
     reflows the grid, and paint it ourselves: a host page's bare
     `::-webkit-scrollbar { background: transparent }` (very common in dark
     themes) otherwise renders it effectively invisible and the list looks like
     a plain 12-item grid. Our class-scoped rules outrank those bare ones. */
  scrollbar-gutter: stable;
  scrollbar-width: thin;                              /* Firefox */
  scrollbar-color: var(--cmp-text-muted) transparent; /* Firefox */
}
.cmp-lang__list::-webkit-scrollbar { width: 10px; }
.cmp-lang__list::-webkit-scrollbar-track { background: transparent; }
.cmp-lang__list::-webkit-scrollbar-thumb {
  background:     var(--cmp-text-muted);
  border-radius:  5px;
  border:         3px solid transparent;   /* inset the thumb from the rail */
  background-clip: content-box;
}

/* "There is more below" fade, pinned to the shell's bottom edge. Shown only
   while the list actually overflows AND is not already scrolled to the end --
   a permanent fade would just look like a rendering artefact at the bottom.
   Inset on the right so it never washes out the scrollbar thumb. */
.cmp-lang__panel::after {
  content:        "";
  position:       absolute;
  left:           0;
  right:          10px;
  bottom:         0;
  height:         30px;
  pointer-events: none;
  background:     linear-gradient(to top, var(--cmp-bg), transparent);
  opacity:        0;
  transition:     opacity var(--cmp-transition);
}
.cmp-lang__panel--more::after { opacity: 1; }
/* Left-aligned surfaces (banner brand bar) drop the panel from the left edge. */
.cmp-lang--start .cmp-lang__panel { right: auto; left: 0; }


.cmp-lang__opt {
  min-width:     0;
  padding:       10px 8px;
  border:        1px solid transparent;
  border-radius: 10px;
  background:    var(--cmp-bg-3);
  color:         var(--cmp-text);
  font-family:   var(--cmp-font);
  font-size:     13px;
  font-weight:   500;
  line-height:   1.2;
  text-align:    center;
  overflow:      hidden;
  text-overflow: ellipsis;
  white-space:   nowrap;
  transition:    background var(--cmp-transition), color var(--cmp-transition);
}
.cmp-lang__opt:hover { background: var(--cmp-bg-2); border-color: var(--cmp-border); }
.cmp-lang__opt:focus-visible {
  outline:        2px solid var(--cmp-primary);
  outline-offset: -2px;
}
.cmp-lang__opt--active {
  position:    relative;
  background:  var(--cmp-bg-3);
  background:  color-mix(in srgb, var(--cmp-primary) 12%, transparent);
  color:       var(--cmp-primary);
  font-weight: 600;
}
/* Active marker — the dot in the chip's top-right corner. */
.cmp-lang__opt--active::after {
  content:       "";
  position:      absolute;
  top:           6px;
  right:         6px;
  width:         6px;
  height:        6px;
  border-radius: 50%;
  background:    var(--cmp-primary);
}

@media (max-width: 560px) {
  /* grid lives on the list now; min-width stays on the shell. Four columns do
     not fit a phone — drop to two and let the list scroll (rail + fade). */
  .cmp-lang__panel { min-width: 200px; }
  .cmp-lang__list  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Pills */
.cmp-pill {
  display:       inline-flex;
  align-items:   center;
  padding:       3px 10px;
  border-radius: 99px;
  font-size:     12px;
  font-weight:   600;
}
.cmp-pill--in  { background: rgba(34,211,160,.12); color: #0e9063; }
.cmp-pill--out { background: rgba(239,68,68,.10);  color: #c42b2b; }

/* ─────────────────────────────────────────────────────────────────────────
   About tab
   ───────────────────────────────────────────────────────────────────────── */
.cmp-about__heading {
  margin:      0 0 10px;
  font-size:   16px;
  font-weight: 600;
}
.cmp-about__body {
  margin:    0 0 12px;
  font-size: 14px;
  color:     var(--cmp-text-muted);
  line-height: 1.65;
  white-space: pre-line;   /* preserve the admin's line breaks — see .cmp-banner__body */
}
/* Legal links: one full-width row each, sharing the heading's left edge, with
   a hairline between rows. Underline only on hover so the resting state stays
   calm next to the body copy. */
.cmp-about__links {
  display:        flex;
  flex-direction: column;
  margin-bottom:  16px;
  border-top:     1px solid var(--cmp-border);
}
.cmp-about__link {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             12px;
  padding:         11px 0;      /* zero side padding keeps the row flush with the heading */
  font-size:       14px;
  font-weight:     500;
  color:           var(--cmp-primary);
  text-decoration: none;
  border-bottom:   1px solid var(--cmp-border);
  transition:      color var(--cmp-transition);
}
.cmp-about__link:hover .cmp-about__link-label {
  text-decoration: underline;
}
.cmp-about__link:hover { color: var(--cmp-primary-hov); }
.cmp-about__link-icon {
  display:     inline-flex;
  flex-shrink: 0;
  opacity:     .6;
}
.cmp-about__link-icon svg {
  width:  14px;
  height: 14px;
  display: block;
}
.cmp-about__link:hover .cmp-about__link-icon { opacity: 1; }

/* ─────────────────────────────────────────────────────────────────────────
   Powered by
   ───────────────────────────────────────────────────────────────────────── */
.cmp-powered-by {
  display:    block;
  text-align: center;
  font-size:  11px;
  color:      var(--cmp-text-muted);
  padding-top: 8px;
  margin-top:  4px;
}
.cmp-powered-by--about { text-align: left; }

/* ─────────────────────────────────────────────────────────────────────────
   Scrollbar styling (Webkit)
   ───────────────────────────────────────────────────────────────────────── */
.cmp-modal__content::-webkit-scrollbar { width: 5px; }
.cmp-modal__content::-webkit-scrollbar-track { background: transparent; }
.cmp-modal__content::-webkit-scrollbar-thumb { background: var(--cmp-border); border-radius: 3px; }

/* ─────────────────────────────────────────────────────────────────────────
   Reduced motion
   ───────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .cmp-banner, .cmp-modal, .cmp-overlay, .cmp-fab,
  .cmp-toggle__slider, .cmp-toggle__slider::before,
  .cmp-btn { transition: none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   Responsive — medium (tablet): too narrow for copy and buttons side by side,
   so the actions drop to their own full-width row under the notice text
   ───────────────────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  .cmp-banner          { padding: 16px 18px; }
  .cmp-banner__inner   { flex-direction: column; align-items: stretch; gap: 14px; }
  .cmp-banner__text    { flex: 1 1 auto; }
  .cmp-banner__actions { width: 100%; justify-content: flex-start; }
  .cmp-btn             { flex: 1 1 auto; }
}

/* ─────────────────────────────────────────────────────────────────────────
   Responsive — small (mobile)
   ───────────────────────────────────────────────────────────────────────── */
@media (max-width: 560px) {
  /* The bar is already edge to edge; on a phone it only needs tighter gutters. */
  .cmp-banner { padding: 16px 14px; }
  .cmp-banner--bottom { transform: translateY(20px); }
  .cmp-banner--bottom.cmp-banner--visible { transform: translateY(0); }

  .cmp-banner__actions  { justify-content: stretch; }
  .cmp-btn              { flex: 1 1 auto; justify-content: center; }

  .cmp-modal {
    max-height: 92vh;
    border-radius: var(--cmp-radius) var(--cmp-radius) 0 0;
    margin-top: auto;
  }
  .cmp-overlay { align-items: flex-end; padding: 0; }

  .cmp-modal__footer { flex-wrap: wrap; }
  .cmp-modal__footer .cmp-btn { flex: 1 1 120px; }
  /* Below this width three long translated labels cannot share a row without
     squeezing to a 125px column three lines tall. Give each its own full-width
     row instead — same treatment .cmp-modal--request already gets further down. */
  .cmp-modal__footer-left { flex: 1 1 100%; }
  /* The left group is a plain block, so its child sizes with width. The Save /
     Accept buttons are flex items of the footer, where flex-basis beats width —
     they need `flex`, not `width: 100%`, to claim a full row. */
  .cmp-modal__footer-left .cmp-btn { width: 100%; }
  .cmp-modal__footer > .cmp-btn    { flex: 1 1 100%; }
}
/* Age gate (S.9) — 18+ confirmation row in the banner */
.cmp-age-gate-row { margin: 8px 0 4px; }
.cmp-age-gate {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--cmp-text-muted, #6b7280); cursor: pointer;
}
.cmp-age-gate__check { width: 16px; height: 16px; accent-color: var(--cmp-primary, #5b5ef4); }
.cmp-btn--disabled, .cmp-btn:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }

/* ─────────────────────────────────────────────────────────────────────────
   Form consent panel (IDENTIFIED surface) — reuses the FULL preference-center
   shell (.cmp-overlay / .cmp-modal / .cmp-modal__* / .cmp-purpose-card /
   .cmp-toggle / .cmp-btn). Only the intro notice body, error region and OTP
   input below are form-specific.
   ───────────────────────────────────────────────────────────────────────── */
/* Notice body — line breaks preserved by splitting body_text into blocks */
.cmp-form__intro {
  margin:      0 0 16px;
  font-size:   14px;
  color:       var(--cmp-text-muted);
  line-height: 1.6;
}
.cmp-form__intro-line { margin: 0 0 8px; }
.cmp-form__intro-line:last-child { margin-bottom: 0; }
.cmp-form__intro-bullet {
  position:    relative;
  margin:      0 0 6px;
  padding-left: 18px;
}
.cmp-form__intro-bullet::before {
  content:  "•";
  position: absolute;
  left:     2px;
  color:    var(--cmp-primary);
}
.cmp-form__intro-gap { height: 8px; }

.cmp-form__error {
  margin:     0;
  padding:    10px 24px;
  font-size:  13px;
  color:      #c42b2b;
  background: rgba(239,68,68,.08);
}
/* OTP step */
.cmp-form__otp-wrap {
  display:         flex;
  justify-content: center;
  margin:          8px 0 4px;
}
.cmp-form__otp-input {
  width:           220px;
  max-width:       100%;
  padding:         12px 14px;
  font-size:       22px;
  letter-spacing:  .5em;
  text-align:      center;
  font-family:     ui-monospace, SFMono-Regular, Menlo, monospace;
  color:           var(--cmp-text);
  background:      var(--cmp-bg);
  border:          1.5px solid var(--cmp-border);
  border-radius:   var(--cmp-radius-sm);
  transition:      border-color var(--cmp-transition), box-shadow var(--cmp-transition);
}
.cmp-form__otp-input:focus {
  outline:      none;
  border-color: var(--cmp-primary);
  box-shadow:   0 0 0 3px rgba(91,94,244,.12);
}

/* ─────────────────────────────────────────────────────────────────────────
   Form consent — single-panel additions (header subtitle, section label,
   purpose detail lines, inline "Secure This Consent" OTP block)
   ───────────────────────────────────────────────────────────────────────── */
/* Header: title + small DPDP subtitle stacked */
.cmp-modal__title-wrap {
  display:        flex;
  flex-direction: column;
  gap:            2px;
  min-width:      0;
}
.cmp-modal__subtitle {
  font-size:   12px;
  font-weight: 500;
  color:       var(--cmp-text-muted);
}

/* "Powered by <app>" attribution — centered inside the modal, below the footer */
.cmp-modal__attr {
  text-align: center;
  font-size:  11px;
  color:      var(--cmp-text-muted);
  padding:    10px 16px 14px;
}

/* Small uppercase section label ("CONSENT CATEGORIES") */
.cmp-form__section-label {
  margin:         18px 0 10px;
  font-size:      11px;
  font-weight:    700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color:          var(--cmp-text-muted);
}

/* "Purpose:" / "Data:" lines inside a form purpose card */
.cmp-form__purpose-detail {
  padding: 0 16px 14px 16px;
}
.cmp-form__purpose-line {
  margin:      0 0 4px;
  font-size:   12.5px;
  line-height: 1.5;
  color:       var(--cmp-text-muted);
}
.cmp-form__purpose-line:last-child { margin-bottom: 0; }
.cmp-form__purpose-key {
  font-weight: 600;
  color:       var(--cmp-text);
}

/* Inline OTP block — "Secure This Consent" */
.cmp-otp {
  margin-top:     18px;
  padding-top:    16px;
  border-top:     1px solid var(--cmp-border);
}
.cmp-otp__head {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             10px;
  margin-bottom:   6px;
}
.cmp-otp__title {
  display:     inline-flex;
  align-items: center;
  gap:         8px;
  font-size:   14px;
  font-weight: 700;
  color:       var(--cmp-text);
}
.cmp-otp__lock {
  width:  16px;
  height: 16px;
  color:  var(--cmp-primary);
  flex-shrink: 0;
}
.cmp-otp__tag {
  background: var(--cmp-bg-3);
  color:      var(--cmp-text-muted);
}
.cmp-otp__body { margin-top: 4px; }
.cmp-otp__row {
  display:         flex;
  align-items:     flex-start;
  justify-content: space-between;
  gap:             12px;
  flex-wrap:       wrap;
}
.cmp-otp__sent {
  margin:    0;
  flex:      1 1 200px;
  min-width: 0;
  font-size: 13px;
  color:     var(--cmp-text-muted);
  line-height: 1.5;
}
.cmp-otp__email {
  font-weight: 600;
  color:       var(--cmp-text);
  word-break:  break-all;
}
.cmp-otp__links {
  display:         flex;
  flex-direction:  column;
  align-items:     flex-end;
  gap:             4px;
  flex-shrink:     0;
}
.cmp-otp__link {
  background:      none;
  border:          none;
  padding:         0;
  font-family:     var(--cmp-font);
  font-size:       12.5px;
  font-weight:     600;
  color:           var(--cmp-primary);
  cursor:          pointer;
  text-decoration: none;
  white-space:     nowrap;
}
.cmp-otp__link:hover { text-decoration: underline; text-underline-offset: 3px; }
.cmp-otp__link--disabled {
  color:          var(--cmp-text-muted);
  cursor:         not-allowed;
  pointer-events: none;
  opacity:        .6;
}

/* Inline Change-Email editor (replaces the native prompt) */
.cmp-otp__email-edit {
  display:        flex;
  flex-direction: column;
  gap:            8px;
  margin-top:     4px;
}
.cmp-otp__email-label {
  font-size:   12px;
  font-weight: 600;
  color:       var(--cmp-text-muted);
}
.cmp-otp__email-input {
  width:         100%;
  box-sizing:    border-box;
  padding:       10px 12px;
  font-size:     14px;
  color:         var(--cmp-text);
  background:     var(--cmp-bg);
  border:        1.5px solid var(--cmp-border);
  border-radius: var(--cmp-radius-sm);
  transition:    border-color var(--cmp-transition), box-shadow var(--cmp-transition);
}
.cmp-otp__email-input:focus {
  outline:      none;
  border-color: var(--cmp-primary);
  box-shadow:   0 0 0 3px color-mix(in srgb, var(--cmp-primary) 22%, transparent);
}
.cmp-otp__email-actions {
  display:         flex;
  gap:             8px;
  justify-content: flex-end;
}
.cmp-otp__email-btn {
  padding:   8px 16px;
  font-size: 13px;
}

/* Six single-digit boxes */
.cmp-otp__boxes {
  display:   flex;
  gap:       8px;
  margin-top: 12px;
  flex-wrap:  wrap;
}
.cmp-otp__box {
  width:           44px;
  height:          52px;
  padding:         0;
  text-align:      center;
  font-size:       22px;
  font-weight:     600;
  font-family:     ui-monospace, SFMono-Regular, Menlo, monospace;
  color:           var(--cmp-text);
  background:       var(--cmp-bg);
  border:          1.5px solid var(--cmp-border);
  border-radius:   var(--cmp-radius-sm);
  transition:      border-color var(--cmp-transition), box-shadow var(--cmp-transition);
}
.cmp-otp__box:focus {
  outline:      none;
  border-color: var(--cmp-primary);
  box-shadow:   0 0 0 3px rgba(91,94,244,.12);
}
@media (max-width: 560px) {
  .cmp-otp__box { width: 40px; height: 48px; font-size: 20px; }
}

/* ── Age gate (form consent) ─────────────────────────────────────────────── */
.cmp-agegate {
  margin:        4px 0 14px;
  padding:       12px 14px;
  border:        1.5px solid var(--cmp-border);
  border-radius: var(--cmp-radius-sm);
  background:     var(--cmp-bg);
}
.cmp-agegate__label {
  display:     flex;
  align-items: center;
  gap:         10px;
  font-size:   14px;
  color:       var(--cmp-text);
  cursor:      pointer;
}
.cmp-agegate__check { width: 18px; height: 18px; accent-color: var(--cmp-primary); }
.cmp-agegate--ok {
  display:      flex;
  align-items:  center;
  gap:          12px;
  border-color: var(--cmp-success, #16a34a);
  background:    color-mix(in srgb, var(--cmp-success, #16a34a) 10%, transparent);
}
.cmp-agegate__icon {
  flex:          0 0 auto;
  width:         28px;
  height:        28px;
  border-radius: 50%;
  display:       flex;
  align-items:   center;
  justify-content: center;
  color:         #fff;
  background:     var(--cmp-success, #16a34a);
}
.cmp-agegate__icon svg { width: 16px; height: 16px; }
.cmp-agegate__title { font-weight: 700; font-size: 14px; color: var(--cmp-success, #16a34a); }
.cmp-agegate__sub { font-size: 12.5px; color: var(--cmp-text-muted); }

/* pending (not yet verified) state */
.cmp-agegate:not(.cmp-agegate--ok) {
  display:     flex;
  align-items: center;
  gap:         12px;
}
.cmp-agegate__icon--pending { background: var(--cmp-primary); }
.cmp-agegate__title--pending { color: var(--cmp-text); }

/* ── "Consent Saved!" success screen ────────────────────────────────────── */
.cmp-success {
  display:        flex;
  flex-direction: column;
  align-items:    center;
  text-align:     center;
  padding:        8px 4px 4px;
}
.cmp-success__check {
  width:         64px;
  height:        64px;
  border-radius: 50%;
  display:       flex;
  align-items:   center;
  justify-content: center;
  color:         #fff;
  background:     var(--cmp-success, #16a34a);
  margin-bottom: 14px;
}
.cmp-success__check svg { width: 32px; height: 32px; }
.cmp-success__title {
  margin:      0 0 6px;
  font-size:   22px;
  font-weight: 700;
  color:       var(--cmp-success, #16a34a);
}
.cmp-success__sub {
  margin:    0 0 18px;
  font-size: 14px;
  color:     var(--cmp-text-muted);
}
.cmp-success__id-card {
  width:         100%;
  box-sizing:    border-box;
  padding:       16px;
  margin-bottom: 12px;
  border-radius: var(--cmp-radius);
  background:     var(--cmp-primary);
  color:         #fff;
}
.cmp-success__id-label {
  font-size:      12px;
  font-weight:    700;
  letter-spacing: .08em;
  opacity:        .9;
  margin-bottom:  10px;
}
.cmp-success__id {
  width:         100%;
  box-sizing:    border-box;
  padding:       12px;
  font-family:   ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:     18px;
  font-weight:   700;
  letter-spacing: .06em;
  color:         var(--cmp-text);
  background:     #fff;
  border:        none;
  border-radius: var(--cmp-radius-sm);
  cursor:        pointer;
}
.cmp-success__download { width: 100%; margin-bottom: 12px; }
.cmp-success__manage {
  width:           100%;
  margin-bottom:   12px;
  text-align:      center;
  text-decoration: none;
  display:         block;
}
.cmp-success__note {
  width:         100%;
  box-sizing:    border-box;
  margin:        0;
  padding:       10px 14px;
  font-size:     13px;
  text-align:    left;
  color:         var(--cmp-text);
  background:     var(--cmp-warning-bg, #fef6e0);
  border-left:   4px solid var(--cmp-warning, #f5b301);
  border-radius: var(--cmp-radius-sm);
}
.cmp-success__done { width: 100%; }

/* ─────────────────────────────────────────────────────────────────────────
   Officer-assisted consent REQUEST popup (consent_mode = request)
   The officer is present, the data principal is not. Reuses the full
   preference-center shell (.cmp-overlay / .cmp-modal / .cmp-modal__* /
   .cmp-btn) — everything below is token-driven, so the surface picks up the
   notice's configured theme (primary colour, radius, font, text colours).
   ───────────────────────────────────────────────────────────────────────── */
.cmp-modal--request { max-width: 560px; }

.cmp-request__section { margin-bottom: 22px; }
.cmp-request__section:last-child { margin-bottom: 0; }

.cmp-request__label {
  margin-bottom:   8px;
  font-size:       11px;
  font-weight:     600;
  text-transform:  uppercase;
  letter-spacing:  .04em;
  color:           var(--cmp-text-muted);
}

/* Recipient — read-only by design (the officer fixed it on their own form) */
.cmp-request__recipient {
  display:       flex;
  align-items:   center;
  gap:           10px;
  padding:       12px 14px;
  background:    var(--cmp-bg-2);
  border:        1px solid var(--cmp-border);
  border-radius: var(--cmp-radius-sm);
}
.cmp-request__recipient-icon {
  display:     flex;
  flex-shrink: 0;
  color:       var(--cmp-primary);
}
.cmp-request__recipient-icon svg { width: 18px; height: 18px; }
.cmp-request__recipient-mail {
  flex:          1;
  min-width:     0;
  overflow:      hidden;
  text-overflow: ellipsis;
  white-space:   nowrap;
  font-size:     15px;
  font-weight:   500;
  color:         var(--cmp-text);
}
.cmp-request__pill {
  flex-shrink:    0;
  padding:        2px 9px;
  border-radius:  999px;
  background:     var(--cmp-bg-3);
  color:          var(--cmp-text-muted);
  font-size:      10px;
  font-weight:    600;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.cmp-request__hint {
  margin:      8px 0 0;
  font-size:   12px;
  line-height: 1.5;
  color:       var(--cmp-text-muted);
}

/* Notice preview — full copy, line breaks preserved, no nested scroll box */
.cmp-request__notice-title {
  margin:      0 0 6px;
  font-size:   16px;
  font-weight: 600;
  color:       var(--cmp-text);
}
.cmp-request__notice-body {
  margin:      0;
  font-size:   14px;
  line-height: 1.6;
  color:       var(--cmp-text-muted);
  white-space: pre-line;
}

/* Purpose cards — read-only (the principal, not the officer, makes the choice) */
.cmp-request__purpose {
  padding:       13px 14px;
  margin-bottom: 8px;
  border:        1px solid var(--cmp-border);
  border-radius: var(--cmp-radius-sm);
  background:    var(--cmp-bg);
}
.cmp-request__purpose:last-child { margin-bottom: 0; }
.cmp-request__purpose-head {
  display:         flex;
  align-items:     flex-start;
  justify-content: space-between;
  gap:             10px;
}
.cmp-request__purpose-name {
  font-size:   14px;
  font-weight: 600;
  color:       var(--cmp-text);
}
.cmp-request__badge {
  flex-shrink:    0;
  padding:        2px 8px;
  border-radius:  999px;
  font-size:      10px;
  font-weight:    600;
  text-transform: uppercase;
  letter-spacing: .03em;
  white-space:    nowrap;
}
/* colour-mix keeps the badge on-theme; the flat fallback covers older browsers */
.cmp-request__badge--required {
  background: var(--cmp-bg-3);
  background: color-mix(in srgb, var(--cmp-primary) 12%, transparent);
  color:      var(--cmp-primary);
}
.cmp-request__badge--optional {
  background: var(--cmp-bg-3);
  color:      var(--cmp-text-muted);
}
.cmp-request__purpose-desc {
  margin:      5px 0 0;
  font-size:   12.5px;
  line-height: 1.5;
  color:       var(--cmp-text-muted);
}
.cmp-request__chips {
  display:   flex;
  flex-wrap: wrap;
  gap:       4px;
  margin-top: 7px;
}
.cmp-request__chip {
  padding:       2px 8px;
  border-radius: 6px;
  background:    var(--cmp-bg-3);
  color:         var(--cmp-text-muted);
  font-size:     11px;
  font-weight:   500;
}
.cmp-request__meta {
  margin-top: 5px;
  font-size:  11px;
  color:      var(--cmp-text-muted);
}
.cmp-request__meta--warn { color: var(--cmp-warning, #b45309); }
.cmp-request__empty {
  margin:    0;
  font-size: 13px;
  color:     var(--cmp-text-muted);
}

@media (max-width: 560px) {
  /* Footer buttons go full-width and the primary action leads. */
  .cmp-modal--request .cmp-modal__footer { gap: 8px; }
  .cmp-modal--request .cmp-modal__footer-left { flex: 1 1 100%; order: 2; }
  .cmp-modal--request .cmp-modal__footer-left .cmp-btn { width: 100%; }
  .cmp-modal--request .cmp-btn--primary { flex: 1 1 100%; order: 1; }
}
