/* ============================================================
   DJC_ConsentBanner
   layer one is a hairline strip pinned to the bottom edge -- no
   card, no shadow, no outer radius -- so it reads as browser
   chrome rather than an interruption. layer two is a bottom sheet
   that replaces the strip rather than stacking on it, so the two
   feel like one object opening.

   this sheet ships on every page, including pages that never load
   campaign-base.css, so every knob reads a house token with a
   plain fallback and every color-mix() is preceded by a flat
   declaration. nothing here can assume the base sheet.

   "low contrast" in this design means the chrome -- the border,
   the surface, the divider. it never means the type. the strip
   sentence runs at full ink and the quietest text still clears
   4.5:1; shrinking type colour is the easy way to make a strip
   disappear and the one reduction that breaks accessibility.

   accept and reject share one rule with no modifier on either, so
   they cannot drift apart. equal prominence is a legal
   requirement, not a style preference, and no button here may use
   --brand-3 (the give / download cta colour).
   ============================================================ */

/* ========================================
   TOKENS
   ======================================== */
.djc-consent {
  /* local knobs -- retune the component by overriding these on
     .djc-consent rather than editing the rules below */

  /* the greys are deliberately NOT read from the house ink tokens.
     contrast here is a compliance property, not a theming one: the
     muted line carries the mandated purpose-and-vendor disclosure at
     11-12px, so it has to clear 4.5:1 on every page. --ink-muted
     resolves to a fixed 52% white tint, which lands near 3.2:1 and
     cannot reach 4.5:1 at ANY brand palette -- even a pure black
     --brand-dark tops out around 4.3:1. these literals are the tuned
     values: 5.0:1 on the sheet, 4.8:1 on the strip.
     the same reasoning keeps the component readable if it is ever
     mounted inside a .band--dark, where the house tokens invert. */
  --dc-surface: #ffffff;
  --dc-surface-alt: #fafaf9;
  --dc-ink: #2d2d2b;
  --dc-ink-strong: #141413;
  --dc-ink-muted: #6f6f6c;
  --dc-line: #e4e4e1;

  /* borders that carry meaning on their own need 3:1, not the
     hairline used for dividers */
  --dc-line-strong: #767674;

  /* the one thing that stays brand-swappable: links, focus ring, and
     the "on" switch. measured around 7:1 across the shipped palettes */
  --dc-accent: var(--text-link, #3a6d9e);

  /* confirmation colours for the gpc notice. deliberately outside
     the brand palette so it reads as a system message rather than
     campaign art */
  --dc-ok-bkg: #e9f3ec;
  --dc-ok-ink: #2f6b4f;
  --dc-ok-line: #cfe4d6;

  /* the off track is a ui component, so it needs 3:1 in its own right
     -- a near-white track leaves both the control and its state
     invisible. this sits at about 3.5:1 and still reads as "off" */
  --dc-switch-off: #8a8a87;

  --dc-radius-sm: 8px;
  --dc-radius-sheet: 14px;
  --dc-radius-pill: 999px;

  --dc-size-body: clamp(12px, 1.3vw, 13px);
  --dc-size-label: clamp(11px, 1.2vw, 12px);

  font-family: var(--font-ui, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif);
  color: var(--dc-ink);
}

.djc-consent a,
.djc-consent a:visited {
  color: var(--dc-accent);
}

.djc-consent button {
  font-family: inherit;
  cursor: pointer;
}

.djc-consent :focus-visible {
  outline: 2px solid var(--dc-accent);
  outline-offset: 2px;
}

/* ========================================
   STRIP
   ======================================== */
.djc-consent__strip {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  background: var(--dc-surface-alt);
  border-top: 1px solid var(--dc-line);
  z-index: 900;
}

.djc-consent__dismiss {
  position: absolute;
  top: 7px;
  right: 10px;
  width: 28px;
  height: 28px;
  padding: 0;
  font-size: 22px;
  line-height: 1;
  color: var(--dc-ink-muted);
  background: transparent;
  border: 0;
  border-radius: 6px;
}

.djc-consent__dismiss:hover {
  color: var(--dc-ink-strong);
  background: rgb(0 0 0 / 0.06);
}

.djc-consent__strip-in {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 16px;
  max-width: 1180px;
  width: 100%;
  margin: 0 auto;
  padding: 9px 48px 9px 16px;
}

.djc-consent__copy {
  flex: 1 1 320px;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  font-size: var(--dc-size-body);
  line-height: 1.45;
  margin: 0;
}

/* the sentence stays at full ink -- the strip is quiet because of
   its chrome, not because the words are hard to read */
.djc-consent__text {
  color: var(--dc-ink);
}

.djc-consent__link {
  font-size: var(--dc-size-label);
  white-space: nowrap;
}

.djc-consent__actions {
  display: flex;
  gap: 8px;
  flex: 0 1 auto;
}

/* ========================================
   BUTTONS
   ======================================== */
.djc-consent__btn {
  flex: 1 1 auto;
  min-width: 108px;
  padding: 7px 16px;
  font-size: var(--dc-size-body);
  font-weight: 600;
  color: var(--dc-ink);
  background: var(--dc-surface);
  border: 1px solid #d5d5d2;
  border: 1px solid color-mix(in srgb, var(--dc-ink) 18%, white);
  border-radius: var(--dc-radius-sm);
  transition: background 0.15s ease;
}

.djc-consent__btn:hover {
  background: #f2f2f0;
  background: color-mix(in srgb, var(--dc-ink) 6%, white);
}

.djc-consent__btn:active {
  background: #ececea;
  background: color-mix(in srgb, var(--dc-ink) 10%, white);
}

.djc-consent__btn--accept {
  color: #ffffff;
  background: var(--dc-accent);
  border-color: var(--dc-accent);
}

.djc-consent__btn--accept:hover {
  color: #ffffff;
  background: #24537e;
  border-color: #24537e;
}

/* ========================================
   GPC NOTICE
   ======================================== */
/* renders inline at the top of the strip so the footprint never
   grows, and again inside the sheet -- a locked switch with no
   reason next to it is worse than no switch at all */
.djc-consent__gpc {
  display: flex;
  justify-content: center;
  padding: 6px 16px;
  font-size: var(--dc-size-label);
  font-weight: 500;
  line-height: 1.4;
  color: var(--dc-ok-ink);
  background: var(--dc-ok-bkg);
  border-bottom: 1px solid var(--dc-ok-line);
}

/* the notice is built empty and filled by js, because an aria-live
   region has to already be in the accessibility tree before its
   content changes or the announcement never fires. :empty keeps it
   out of the layout until there is something to say. */
.djc-consent__gpc:empty {
  display: none;
}

/* ========================================
   SHEET
   ======================================== */
.djc-consent__prefs {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: none;
  flex-direction: column;
  justify-content: flex-end;
  z-index: 950;
}

.djc-consent__scrim {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgb(20 20 19 / 0.32);
  background: color-mix(in srgb, var(--dc-ink-strong) 32%, transparent);
  opacity: 0;
  transition: opacity 0.22s ease;
}

.djc-consent__sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 560px;
  max-height: 88vh;
  margin: 0 auto;
  overflow: auto;
  background: var(--dc-surface);
  border: 1px solid var(--dc-line);
  border-bottom: 0;
  border-radius: var(--dc-radius-sheet) var(--dc-radius-sheet) 0 0;
  transform: translateY(100%);
  transition: transform 0.22s ease;
}

.djc-consent__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px 12px;
}

.djc-consent__title {
  font-size: 15px;
  font-weight: 600;
  margin: 0;
}

.djc-consent__close {
  padding: 4px 8px;
  font-size: 18px;
  line-height: 1;
  color: var(--dc-ink-muted);
  background: none;
  border: 0;
  border-radius: 6px;
}

.djc-consent__close:hover {
  background: #f2f2f0;
  background: color-mix(in srgb, var(--dc-ink) 6%, white);
}

.djc-consent__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 18px;
  border-top: 1px solid var(--dc-line);
}

.djc-consent__row-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.djc-consent__row-label {
  font-size: var(--dc-size-body);
  font-weight: 600;
}

/* purpose and vendors share one muted line -- both have to
   survive, but they do not need two lines to do it */
.djc-consent__row-desc {
  font-size: var(--dc-size-label);
  line-height: 1.45;
  color: var(--dc-ink-muted);
}

.djc-consent__row-locked {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--dc-ink-muted);
  white-space: nowrap;
}

.djc-consent__foot {
  display: flex;
  gap: 8px;
  padding: 14px 18px;
  border-top: 1px solid var(--dc-line);
}

/* ========================================
   TOGGLE
   ======================================== */
.djc-consent__toggle {
  position: relative;
  flex: 0 0 auto;
  width: 38px;
  height: 22px;
  padding: 0;
  background: var(--dc-switch-off);
  border: 0;
  border-radius: var(--dc-radius-pill);
  transition: background 0.15s ease;
}

.djc-consent__toggle::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  background: var(--dc-surface);
  border-radius: var(--dc-radius-pill);
  transition: transform 0.15s ease;
}

.djc-consent__toggle.is-on {
  background: var(--dc-accent);
}

.djc-consent__toggle.is-on::after {
  transform: translateX(16px);
}

/* gpc pins advertising off. the switch still renders so the state
   is visible, it just cannot be turned back on */
.djc-consent__toggle.is-locked {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ========================================
   REOPEN
   ======================================== */
/* how a visitor gets back in after deciding -- withdrawal has to
   stay as easy as granting */
.djc-consent__reopen {
  position: fixed;
  left: 12px;
  bottom: 12px;
  padding: 6px 12px;
  font-size: var(--dc-size-label);
  font-weight: 500;
  color: var(--dc-ink-muted);
  background: var(--dc-surface);
  /* this pill is the only withdrawal affordance, and its border is the
     only thing separating it from the page -- hairline is not enough */
  border: 1px solid var(--dc-line-strong);
  border-radius: var(--dc-radius-pill);
  z-index: 900;
}

.djc-consent__reopen:hover {
  color: var(--dc-ink);
  background: var(--dc-surface-alt);
}

/* ========================================
   STATE
   ======================================== */
/* the shared base sheet ships .hide, but this component also
   renders on pages that never load it -- scope a matching rule
   so a hidden strip stays hidden everywhere */
.djc-consent .hide {
  display: none !important;
}

/* same reasoning for .nobreak -- the row markup asks for it by class, so
   it has to resolve on pages that never load the shared sheet either */
.djc-consent .nobreak {
  white-space: nowrap;
}

.djc-consent__prefs.is-open {
  display: flex;
}

/* second beat of the open: the scrim fade and the sheet slide only
   run once the overlay is laid out, so is-open and is-shown land a
   frame apart */
.djc-consent__prefs.is-shown .djc-consent__scrim {
  opacity: 1;
}

.djc-consent__prefs.is-shown .djc-consent__sheet {
  transform: none;
}

/* the sheet owns the viewport while open */
.djc-consent-locked {
  overflow: hidden;
}

/* ========================================
   RESPONSIVE
   ======================================== */
/* the two buttons go full width together, never one before the
   other -- a stacked accept above a stacked reject would read as a
   hierarchy */
@media (max-width: 620px) {
  .djc-consent__actions {
    flex: 1 1 100%;
  }

  .djc-consent__btn {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* ========================================
   REDUCED MOTION
   ======================================== */
@media (prefers-reduced-motion: reduce) {

  .djc-consent__btn,
  .djc-consent__scrim,
  .djc-consent__sheet,
  .djc-consent__toggle,
  .djc-consent__toggle::after {
    transition: none;
  }
}
