/* ==========================================================================
   Complianz cookie banner — Clleancode

   Complianz ships cookiebanner/css/defaults/banner-optin.css, which does the
   layout properly: grid areas, the responsive collapse at 768px, a scrollable
   body, and a special case for viewports under 400px tall. All of it is built
   on --cmplz_* custom properties.

   So this file sets those properties rather than re-implementing the layout.
   A first attempt overrode the rules directly and lost: the banner stayed a
   centred modal with full-width stacked buttons, because the defaults set
   `top: 50%` and `width: 100%` that the overrides never reset. Driving the
   tokens is both shorter and survives a Complianz update.

   Structural overrides are kept below the tokens and each says why it exists.

   Every selector here is prefixed with `html`, and the tokens sit on
   `:root:root`. That is not stylistic. When Complianz has not generated a
   banner stylesheet of its own it falls back to the defaults and *injects them
   with JavaScript at runtime* -- see cookiebanner/class-banner-loader.php,
   which returns early when the generated file is missing. So the defaults
   always land after this file in the cascade no matter what order it is
   enqueued in, and matching their specificity is not enough to win.

   Constraints, from the accessibility audit (in git history):
     · every text colour at or above 4.5:1 on the banner background
     · every control at least 24x24 CSS px (WCAG 2.2 SC 2.5.8)
     · a visible focus ring at 3:1 or better
     · nothing animates width or height
     · honours prefers-reduced-motion
   ========================================================================== */

:root:root {
  /* The banner sits slightly above the page black so it reads as a surface
     rather than a hole. #141416 against the page's #0d0d0d. */
  --cmplz_banner_background_color: #141416;
  --cmplz_banner_border_color: hsla(0, 0%, 100%, .14);
  --cmplz_banner_border_width: 1px;
  --cmplz_banner_border_radius: 2px;
  --cmplz_banner_width: 760px;
  --cmplz_banner_margin: 10px;

  /* 17.9:1 on the banner background. The message is dimmed separately below,
     because this one token also colours the title and the category headings. */
  --cmplz_text_color: var(--clr-white, #fff);
  --cmplz_hyperlink_color: var(--clr-white, #fff);

  --cmplz_title_font_size: clamp(20px, 2.1vw, 26px);
  --cmplz_text_font_size: 14px;
  --cmplz_link_font_size: 13px;
  --cmplz_category_body_font_size: 13px;
  --cmplz_category_header_title_font_size: 15px;
  --cmplz_category_header_active_font_size: 12px;

  /* The default is the literal keyword `green`, which is 1.9:1 here. */
  --cmplz_category_header_always_active_color: hsla(0, 0%, 100%, .66);

  /* Accept is the inverse of the banner; deny and settings are outlines. Both
     primary actions are the same size, because a reject that is harder to
     reach than accept is not freely given consent. */
  --cmplz_button_accept_background_color: var(--clr-white, #fff);
  --cmplz_button_accept_border_color: var(--clr-white, #fff);
  --cmplz_button_accept_text_color: #141416;

  --cmplz_button_deny_background_color: transparent;
  --cmplz_button_deny_border_color: hsla(0, 0%, 100%, .45);
  --cmplz_button_deny_text_color: var(--clr-white, #fff);

  --cmplz_button_settings_background_color: transparent;
  --cmplz_button_settings_border_color: hsla(0, 0%, 100%, .22);
  --cmplz_button_settings_text_color: hsla(0, 0%, 100%, .78);

  --cmplz_button_border_radius: 2px;
  --cmplz_button_font_size: 14px;

  --cmplz_slider_active_color: var(--clr-white, #fff);
  --cmplz_slider_inactive_color: hsla(0, 0%, 100%, .25);
  --cmplz_slider_bullet_color: #141416;

  /* --cmplz_category_open_icon_url is deliberately not set. The default is a
     dark PNG that would be invisible here, but the banner markup already ships
     an inline <svg> drawn in currentColor; setting the background as well
     rendered a second, scaled-up chevron behind the first. Colour is set on
     the button below instead. */

  --cmplz-manage-consent-height: 38px;
  --cmplz-manage-consent-offset: -26px;
}

/* ---------------------------------------------------------- the surface -- */

html .cmplz-cookiebanner {
  font-family: var(--font-sans);
  /* The defaults centre it with top:50% + translateY(-50%). A consent notice
     is not a modal -- the audit found the theme's own centred banner covering
     the contact form's first two fields -- so it is anchored to the bottom.
     `top` has to be reset explicitly or it keeps winning over `bottom`. */
  top: auto;
  bottom: 16px;
  transform: translateX(-50%);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
  padding: 22px 20px 18px;
}

@media (min-width: 769px) {
  .cmplz-cookiebanner {
    bottom: 28px;
    padding: 28px 30px 24px;
  }
}

/* --------------------------------------------------------------- header -- */

/* The default header is a 100px / 1fr / 100px grid that centres the title.
   With no logo configured the left column is dead space and the title sits
   oddly off-centre; left-aligned matches every other heading on the site. */
html .cmplz-cookiebanner .cmplz-header {
  grid-template-columns: 1fr auto;
  gap: 16px;
}

html .cmplz-cookiebanner .cmplz-logo:empty {
  display: none;
}

html .cmplz-cookiebanner .cmplz-title {
  grid-column-start: 1;
  justify-self: start;
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.15;
}

html .cmplz-cookiebanner .cmplz-close {
  grid-column-start: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* SC 2.5.8 wants 24x24; the default is exactly 24 with a 20px glyph. */
  width: 32px;
  height: 32px;
  border-radius: 2px;
  color: hsla(0, 0%, 100%, .66);
  transition: color .2s ease, background-color .2s ease;
}

html .cmplz-cookiebanner .cmplz-close:hover {
  color: var(--clr-white, #fff);
  background: hsla(0, 0%, 100%, .08);
  /* The default shrinks the glyph from 20px to 18px on hover, which reads as
     a wobble. */
  font-size: inherit;
}

html .cmplz-cookiebanner .cmplz-close svg {
  width: 13px;
  height: 13px;
}

/* ----------------------------------------------------------------- body -- */

/* --cmplz_text_color has to stay white for the title and category headings,
   so the running copy is dimmed here instead. .66 alpha composites to
   ~#adadad on #141416 — 8.0:1. */
.cmplz-cookiebanner .cmplz-message,
html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-description {
  color: hsla(0, 0%, 100%, .66);
  line-height: 1.65;
}

html .cmplz-cookiebanner .cmplz-message a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

html .cmplz-cookiebanner .cmplz-divider {
  background: hsla(0, 0%, 100%, .14);
  height: 1px;
  border: 0;
}

/* ----------------------------------------------------------- categories -- */

/* The default category background is rgba(239,239,239,.5) — a light panel on
   a dark banner, which put dark-on-light text where everything else is
   light-on-dark. */
html .cmplz-cookiebanner .cmplz-categories .cmplz-category {
  background-color: hsla(0, 0%, 100%, .04);
  border: 1px solid hsla(0, 0%, 100%, .1);
  border-radius: 2px;
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-category-header {
  min-height: 48px;
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-category-title {
  font-weight: 700;
  letter-spacing: -.02em;
}

/* -------------------------------------------------------------- buttons -- */

/* The defaults already give these min-height:45px and share the row with
   width:100% + gap. Do not add flex-wrap here: combined with width:100% it
   puts every button on its own line, which is what the first attempt did. */
html .cmplz-cookiebanner .cmplz-buttons .cmplz-btn {
  font-weight: 700;
  letter-spacing: -.01em;
  transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}

html .cmplz-cookiebanner .cmplz-buttons .cmplz-btn.cmplz-accept:hover {
  background-color: hsla(0, 0%, 100%, .86);
  border-color: hsla(0, 0%, 100%, .86);
}

.cmplz-cookiebanner .cmplz-buttons .cmplz-btn.cmplz-deny:hover,
.cmplz-cookiebanner .cmplz-buttons .cmplz-btn.cmplz-view-preferences:hover,
html .cmplz-cookiebanner .cmplz-buttons .cmplz-btn.cmplz-save-preferences:hover {
  background-color: hsla(0, 0%, 100%, .1);
  border-color: hsla(0, 0%, 100%, .6);
  color: var(--clr-white, #fff);
}

/* ------------------------------------------------------------ documents -- */

html .cmplz-cookiebanner .cmplz-links .cmplz-link {
  color: hsla(0, 0%, 100%, .66);
  /* List items, not inline links in a sentence, so SC 2.5.8 has no exception
     to offer them. */
  display: inline-block;
  padding-block: 6px;
  text-underline-offset: 2px;
}

html .cmplz-cookiebanner .cmplz-links .cmplz-link:hover {
  color: var(--clr-white, #fff);
}

/* Until the wizard has generated the legal documents, Complianz's JS leaves
   this list in a broken state: one link with a real href but no text at all,
   and the rest still carrying the raw "{title}" placeholder. An empty <a> is
   also a link with no accessible name, so hiding them fixes two things.
   They come back on their own once the documents exist. */
html .cmplz-cookiebanner .cmplz-links a:empty,
html .cmplz-cookiebanner .cmplz-links a.cmplz-hidden {
  display: none;
}

html .cmplz-cookiebanner .cmplz-links li:has(> a:empty),
html .cmplz-cookiebanner .cmplz-links li:has(> a.cmplz-hidden) {
  display: none;
}

/* ------------------------------------------------------- manage consent -- */

html #cmplz-manage-consent .cmplz-manage-consent {
  right: auto;
  left: 0;
  min-width: 0;
  padding: 10px 14px;
  background-color: var(--clr-dark, #0d0d0d);
  border-color: hsla(0, 0%, 100%, .16);
  border-left: 0;
  border-radius: 0 2px 2px 0;
  color: hsla(0, 0%, 100%, .72);
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: .02em;
}

html #cmplz-manage-consent .cmplz-manage-consent:hover {
  color: var(--clr-white, #fff);
}

/* The default hides this below 768px, which leaves a phone with no way back
   to the decision at all. */
@media (max-width: 768px) {
  #cmplz-manage-consent .cmplz-manage-consent {
    display: block;
  }
}

/* --------------------------------------------------------------- focus -- */

/* The theme's global ring is currentColor, which disappears against the
   accept button and the dark panels. SC 1.4.11 wants 3:1. */
.cmplz-cookiebanner :focus-visible,
html #cmplz-manage-consent :focus-visible {
  outline: 2px solid var(--clr-white, #fff);
  outline-offset: 3px;
  box-shadow: 0 0 0 4px rgba(0, 0, 0, .55);
  border-radius: 2px;
}

html .cmplz-cookiebanner .cmplz-btn.cmplz-accept:focus-visible {
  outline-color: var(--clr-white, #fff);
  box-shadow: 0 0 0 4px rgba(0, 0, 0, .75);
}

html .cmplz-cookiebanner .cmplz-consent-checkbox:focus-visible + .cmplz-label {
  outline: 2px solid var(--clr-white, #fff);
  outline-offset: 3px;
}

/* -------------------------------------------------------------- motion -- */

@media (prefers-reduced-motion: reduce) {
  .cmplz-cookiebanner,
  .cmplz-cookiebanner .cmplz-btn,
  .cmplz-cookiebanner .cmplz-close,
  .cmplz-cookiebanner .cmplz-icon.cmplz-open,
  #cmplz-manage-consent .cmplz-manage-consent {
    transition: none !important;
    animation: none !important;
  }
}

@media (prefers-contrast: more) {
  :root:root {
    --cmplz_banner_border_color: hsla(0, 0%, 100%, .4);
    --cmplz_category_header_always_active_color: hsla(0, 0%, 100%, .9);
  }

  .cmplz-cookiebanner .cmplz-message,
  .cmplz-cookiebanner .cmplz-links .cmplz-link,
  .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-description {
    color: hsla(0, 0%, 100%, .9);
  }
}

/* --------------------------------------------------- room for the banner -- */

/* Set by an inline script in <head> from a server-side read of Complianz's
   status cookie -- see clleancode_complianz_banner_pending(). Reserving the
   space after paint is what measured as a 0.28 layout shift on /contact/. */
/* Measured banner heights plus their offset from the viewport edge: 423 + 16
   below 769px, 250 + 28 above it. Matching them means the footer ends exactly
   where the banner begins -- no content hidden behind it, and no gap. The
   figures are fixed rather than measured at runtime because measuring after
   paint is what causes layout shift; the consent script releases the space on
   dismissal instead. */
html.cll-cookie-pending body {
  padding-bottom: 440px;
}

@media (min-width: 769px) {
  html.cll-cookie-pending body {
    padding-bottom: 280px;
  }
}

/* --------------------------------------------- empty document placeholders -- */

/* Complianz renders one <li> per legal document and fills the label with
   "{title}" against href="#" until the wizard has generated them. The links
   are hidden above; without this the theme's `ul { list-style: disc }` leaves
   three bullets floating under the buttons. */
html .cmplz-cookiebanner .cmplz-links ul,
html .cmplz-cookiebanner .cmplz-documents ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Browsers without :has() keep the list item but lose the marker, which is
   the lesser of the two. */
html .cmplz-cookiebanner .cmplz-links li {
  list-style: none;
}

/* The block keeps its grid row even when every link inside it is hidden,
   leaving a band of empty space under the buttons. */
html .cmplz-cookiebanner .cmplz-documents:not(:has(a:not(:empty):not(.cmplz-hidden))) {
  display: none;
}

/* ------------------------------------------------------------- toggles -- */

/* The default switch is a 40x20 input over a 28x15 track. Twenty pixels is
   below the 24x24 that WCAG 2.2 SC 2.5.8 asks for, and at 28x15 the switch is
   hard to read as a control at all. Scaled up; the geometry is `::before` for
   the track and `::after` for the bullet, both absolutely positioned, so
   nothing here affects layout. */
html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox input.cmplz-consent-checkbox {
  width: 48px;
  height: 28px;
  top: -4px;
  margin: 0;
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox .cmplz-label {
  padding-left: 44px;
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox .cmplz-label::before {
  width: 40px;
  height: 22px;
  top: -11px;
  border-radius: 11px;
  /* .25 alpha reads as "off" but barely registers as a control. */
  background-color: hsla(0, 0%, 100%, .3);
  border: 1px solid hsla(0, 0%, 100%, .25);
  box-sizing: border-box;
  padding-left: 0;
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox .cmplz-label::after {
  width: 16px;
  height: 16px;
  left: 4px;
  top: -8px;
  border-radius: 50%;
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox input.cmplz-consent-checkbox:checked + .cmplz-label::after {
  left: 21px;
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox input.cmplz-consent-checkbox:checked + .cmplz-label::before {
  border-color: var(--clr-white, #fff);
}

/* The default focus style is a blue ring that belongs to the plugin's palette. */
html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox input.cmplz-consent-checkbox:focus-visible + .cmplz-label::before {
  box-shadow: 0 0 0 2px #141416, 0 0 0 4px var(--clr-white, #fff);
}

/* --------------------------------------------------------- open chevron -- */

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-category-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* SC 2.5.8 — the default button is 25x28. */
  min-width: 32px;
  min-height: 32px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 2px;
  color: hsla(0, 0%, 100%, .7);
  cursor: pointer;
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-category-toggle:hover {
  color: var(--clr-white, #fff);
  background: hsla(0, 0%, 100%, .08);
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-icon.cmplz-open {
  width: 16px;
  height: 16px;
  margin: 0;
  background-image: none;
}

html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-icon.cmplz-open svg {
  width: 14px;
  height: 14px;
}

/* ------------------------------------------------- checkbox accessible name -- */

/* Complianz renders each consent switch as
   `<label class="cmplz-label" for="…"><span class="screen-reader-text">Statistics</span></label>`
   and then hides that span with `display: none` in its own stylesheet. A span
   hidden that way is removed from the accessibility tree, so the checkbox ends
   up with no accessible name at all -- axe reports it as a critical `label`
   violation, and a screen-reader user hears an unlabelled checkbox.
   Visually hidden rather than display:none restores the name without showing
   anything. */
html .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-category-header .cmplz-banner-checkbox label > span {
  display: block;
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------- short viewports (landscape) -- */

/*
 * Complianz has an emergency squeeze for viewports under 400px tall -- every
 * landscape phone. Measured at 568x320 and 844x390, it renders the buttons at
 *
 *     height: 14px !important; min-height: unset !important;
 *     padding: 0 !important; font-size: 8px !important;
 *
 * Fourteen pixels tall with eight-pixel type: far below the 24x24 that WCAG 2.2
 * SC 2.5.8 asks for, and barely legible. Accept and Deny are the two controls
 * on the page that must not be hard to hit.
 *
 * The banner already has `overflow-y: auto` and a max-height, so the right
 * answer on a short screen is to let the body scroll and keep the buttons
 * usable. !important here only because the rules being corrected use it.
 */
@media (max-height: 400px) {
  html .cmplz-cookiebanner .cmplz-buttons .cmplz-btn {
    height: auto !important;
    min-height: 40px !important;
    padding: 8px 14px !important;
    font-size: 13px !important;
    line-height: 1.2 !important;
    white-space: nowrap !important;
  }

  html .cmplz-cookiebanner {
    padding: 12px 16px 14px;
  }

  /* The title can go; the message immediately below says the same thing, and
     on a 320px-tall screen the room is better spent on the choice itself. */
  html .cmplz-cookiebanner .cmplz-title {
    font-size: 16px;
  }

  html .cmplz-cookiebanner .cmplz-close {
    width: 28px;
    height: 28px;
  }

  /* Keep the scroll on the body rather than squeezing its content. */
  html .cmplz-cookiebanner .cmplz-body {
    max-height: none;
  }

  html .cmplz-cookiebanner .cmplz-message {
    font-size: 12px;
    line-height: 1.45;
  }
}

/* ------------------------------------------------------------ narrow phones -- */

/*
 * Complianz hides the banner title below 425px:
 *
 *     @media (max-width: 425px) {
 *       .cmplz-cookiebanner .cmplz-header .cmplz-title { display: none; }
 *     }
 *
 * The banner is `role="dialog" aria-labelledby="cmplz-header--optin"`, and that
 * id is the title. Hiding it with display:none removes it from the
 * accessibility tree, so on a phone the dialog loses its accessible name --
 * and the header becomes a bar containing nothing but a close button.
 */
@media (max-width: 425px) {
  html .cmplz-cookiebanner .cmplz-header .cmplz-title {
    display: block;
    font-size: 19px;
  }
}

/* At narrow widths Complianz stacks the category header into a single column,
   which drops the switch onto its own line and leaves the row looking unfinished.
   Title and control belong on one line; only the description wraps below. */
@media (max-width: 425px) {
  html .cmplz-cookiebanner .cmplz-category .cmplz-category-header {
    grid-template-columns: 1fr auto auto !important;
    gap: 10px;
    align-items: center;
  }

  html .cmplz-cookiebanner .cmplz-category .cmplz-category-header .cmplz-category-title {
    grid-column-start: 1;
  }

  html .cmplz-cookiebanner .cmplz-category .cmplz-category-header .cmplz-always-active {
    grid-column-start: 2;
  }
}

/* ==========================================================================
   Complianz's own "Manage consent" trigger
   The plugin renders a trigger of its own wherever its document shortcode
   appears, which left /privacy-policy/ with two ways to reopen the banner:
   that button and the footer's "Cookie preferences". One route is enough,
   and the footer one is on every page.

   Hidden rather than filtered away, because the footer button forwards its
   click to this element to reuse Complianz's own banner id, consent type and
   focus-trap handling. A programmatic .click() still fires on a hidden
   element, so the plumbing keeps working while the duplicate disappears.
   ========================================================================== */
html #cmplz-manage-consent {
  display: none;
}
