/* Cookie-banner skin.
 *
 * Maps the vendored CookieConsent engine's --cc-* custom properties onto the site's own theme tokens,
 * so the banner inherits the client's colours, corner radius and fonts instead of looking like a
 * bolted-on third-party widget.
 *
 * Loaded as its own <link> AFTER lib/cookieconsent/cookieconsent.css — not @imported into
 * styles.css. The engine defines these same properties on :root, and at equal specificity the later
 * sheet wins, so load order is the whole mechanism here.
 *
 * Accessibility is not decoration in this file, it is the requirement:
 *   - nothing below 16px, including the cookie tables and the small print;
 *   - a visible :focus-visible ring on every control, at 3:1 against its own background;
 *   - accept and reject at identical size and weight, side by side (the engine's equalWeightButtons
 *     handles the DOM; this makes sure the CSS doesn't quietly undo it);
 *   - motion respects prefers-reduced-motion.
 */

:root {
  /* ---- Surfaces and text ---- */
  --cc-bg: var(--background, #f8fcfb);
  --cc-primary-color: var(--foreground, #111827);
  --cc-secondary-color: var(--tertiary, #3d3d3d);

  /* ---- Primary action (Accept all) ---- */
  --cc-btn-primary-bg: var(--primary, #e01a0c);
  /* White fails on a light brand colour; --on-primary is worked out to pass on it. */
  --cc-btn-primary-color: var(--on-primary, #ffffff);
  --cc-btn-primary-border-color: var(--primary, #e01a0c);
  --cc-btn-primary-hover-bg: var(--secondary, #282828);
  --cc-btn-primary-hover-color: #ffffff;
  --cc-btn-primary-hover-border-color: var(--secondary, #282828);

  /* ---- Secondary action (Reject all / Choose).
   *      Deliberately the same size and weight as the primary, only a different fill. A quieter
   *      "reject" is the dark pattern regulators fine, so this must never become a text link. ---- */
  --cc-btn-secondary-bg: var(--surface, #ededed);
  --cc-btn-secondary-color: var(--foreground, #111827);
  --cc-btn-secondary-border-color: var(--tertiary, #3d3d3d);
  --cc-btn-secondary-hover-bg: var(--tertiary, #3d3d3d);
  --cc-btn-secondary-hover-color: #ffffff;
  --cc-btn-secondary-hover-border-color: var(--tertiary, #3d3d3d);

  /* ---- Toggles ---- */
  --cc-toggle-on-bg: var(--primary, #e01a0c);
  --cc-toggle-off-bg: var(--tertiary, #3d3d3d);
  --cc-toggle-on-knob-bg: #ffffff;
  --cc-toggle-off-knob-bg: #ffffff;
  --cc-toggle-readonly-bg: var(--surface, #ededed);
  --cc-toggle-readonly-knob-bg: var(--tertiary, #3d3d3d);
  --cc-toggle-readonly-knob-icon-color: var(--surface, #ededed);

  /* ---- Structure ---- */
  --cc-separator-border-color: color-mix(in srgb, var(--tertiary, #3d3d3d) 25%, transparent);
  --cc-cookie-category-block-bg: var(--surface, #ededed);
  --cc-cookie-category-block-bg-hover: color-mix(in srgb, var(--surface, #ededed) 80%, var(--tertiary, #3d3d3d));
  --cc-cookie-category-block-border: color-mix(in srgb, var(--tertiary, #3d3d3d) 20%, transparent);
  --cc-cookie-category-expanded-block-bg: transparent;
  --cc-cookie-category-block-bg-hover-border: var(--tertiary, #3d3d3d);
  --cc-overlay-bg: rgb(0 0 0 / 0.55);
  --cc-footer-bg: var(--surface, #ededed);
  --cc-footer-color: var(--foreground, #111827);
  --cc-footer-border-color: color-mix(in srgb, var(--tertiary, #3d3d3d) 20%, transparent);

  /* Follows the site's button-shape setting, so a site with pill buttons gets a pill banner. */
  --cc-btn-border-radius: var(--btn-radius, 0.5rem);
  --cc-modal-border-radius: var(--radius-lg, 0.75rem);
}

/* The engine sets its own font stack; use the site's instead. */
#cc-main {
  --cc-font-family: var(--font-body, inherit);
}

/* ---- Minimum text size ------------------------------------------------------------------------
 * 16px is a hard floor across the Kit, and here it is the difference between a readable cookie table
 * and a decorative one.
 *
 * This is a blanket rule rather than a list of selectors because the engine sizes in `em` at almost
 * every level — buttons at 0.82em, table rows at 0.81em, section wrappers at 0.9em — and those nest,
 * so the reduction compounds and an enumerated list goes stale the moment upstream adds a wrapper.
 * Absolute values on every node stop the compounding outright.
 *
 * The doubled id is deliberate, not a typo: the engine's own rules are `#cc-main .pm__btn` and the
 * like, specificity (1,1,0). `#cc-main *` is only (1,0,0) and would lose. `#cc-main#cc-main *` is
 * (2,0,0) and wins without needing !important.
 */
#cc-main#cc-main,
#cc-main#cc-main * {
  font-size: max(1rem, 16px);
  line-height: 1.5;
}

#cc-main#cc-main .cm__title,
#cc-main#cc-main .pm__title {
  font-family: var(--font-title, inherit);
  font-size: max(1.125rem, 18px);
}

/* The close button's icon is sized by the engine (a 40px button whose svg fills it and is then
   `transform: scale(.5)`), NOT by font-size — so the blanket rule above does not reach it and it must
   not be given a size here. Setting width/height on the svg made it 20px and the engine's scale(.5)
   then halved it again, leaving a tiny cross adrift in the corner.
   All that is needed is centring the flex wrapper the engine leaves unaligned. */
#cc-main#cc-main .pm__close-btn span,
#cc-main#cc-main .cm__btn--close span {
  align-items: center;
  justify-content: center;
}

/* ---- Focus visibility -------------------------------------------------------------------------
 * Keyboard users must always be able to see where they are. The engine ships a focus style, but it
 * is tuned to its own palette and disappears against some client themes.
 */
#cc-main :is(button, a, input):focus-visible {
  outline: 3px solid var(--primary, #e01a0c);
  outline-offset: 2px;
  /* Second ring in the surface colour, so the outline stays visible even when the control's own
     background is close to the primary colour. */
  box-shadow: 0 0 0 5px var(--background, #f8fcfb);
}

/* ---- Equal-weight actions ---------------------------------------------------------------------
 * The engine's equalWeightButtons option makes the markup equal; this keeps the CSS from undoing it.
 * Both buttons get the same padding, weight and minimum width, so neither can be visually demoted.
 */
#cc-main .cm__btn,
#cc-main .pm__btn {
  font-weight: 600;
  min-height: 2.75rem; /* comfortable touch target */
  padding-inline: 1.25rem;
}

/* ---- Cookie tables ----------------------------------------------------------------------------
 * Narrow viewports must be able to read the declared cookies, not just scroll past them.
 */
#cc-main .pm__section--table {
  overflow-x: auto;
}

#cc-main table {
  min-width: 32rem;
}

#cc-main th {
  text-align: start;
  font-weight: 600;
}

/* ---- Motion -----------------------------------------------------------------------------------*/
@media (prefers-reduced-motion: reduce) {
  #cc-main *,
  #cc-main *::before,
  #cc-main *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* ================================================================================================
   LAYOUT PRESETS

   Six silhouettes out of one set of engine markup. `data-dbl-banner` is set on <html> by
   cookie-banner.js from the server-rendered preset, so the backoffice preview and the live page cannot
   disagree about which layout is in force.

   Two rules run through all of it:

   1. Below 40rem every preset becomes the same bottom sheet. A floating card, a centred modal and a
      full-height drawer are all the wrong shape at 360px. The phone layout is not where a brand gets
      expressed; it is where the buttons have to be reachable with one thumb.
   2. Nothing here may separate accept from reject, shrink text under 16px, or cover the page. Those
      rules are declared above and none of this overrides them.
   ================================================================================================ */

/* Comfortable width by default, so no preset accidentally spans a 27-inch monitor. */
#cc-main#cc-main .cm {
  max-width: min(28rem, calc(100vw - 2rem));
}

/* ---- 1 · CARD ---------------------------------------------------------------------------------
   The default: engine box, bottom left. Nothing to add on desktop. */

/* ---- 2 · BAR ---------------------------------------------------------------------------------- */
html[data-dbl-banner="bar"] #cc-main#cc-main .cm {
  max-width: none;
  border-radius: 0;
  border-inline: 0;
  border-bottom: 0;
}

@media (min-width: 60rem) {
  html[data-dbl-banner="bar"] #cc-main#cc-main .cm__body {
    /* The engine caps its own body at 880px: right for a box, wrong for a full-width strip — it
       left the text wrapping in a 412px column and made the strip three lines tall. */
    max-width: 90rem;
    margin-inline: auto;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 1.5rem;
  }
  html[data-dbl-banner="bar"] #cc-main#cc-main .cm__btns {
    margin: 0;
  }
}

/* A fixed bar covers whatever is at the bottom of the page — usually the footer, and on a phone often
   the footer nav. cookie-banner.js measures the bar and publishes its height; this spends it. */
html[data-dbl-banner="bar"] body {
  padding-bottom: var(--dbl-banner-height, 0);
}

/* ---- 3 · SPOTLIGHT ---------------------------------------------------------------------------
   Centred with the page dimmed behind — but still readable and scrollable, which is the difference
   between a spotlight and a cookie wall. */
html[data-dbl-banner="spotlight"] #cc-main#cc-main .cm {
  max-width: min(34rem, calc(100vw - 2rem));
}

/* The dim. pointer-events stays off on purpose: the visitor can still read, scroll and click the page
   behind it, so this is emphasis rather than a cookie wall.

   Gated on the engine's own show--consent class, NOT on the preset attribute alone. The attribute is
   set on every page load and never removed, and the engine hides .cm rather than #cc-main - which it
   keeps around to host the preferences modal. Scoped to the preset alone, this left a 45% black film
   over the entire site after the visitor accepted, making every colour on the page wrong. */
html.show--consent[data-dbl-banner="spotlight"] #cc-main::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: rgb(0 0 0 / 45%);
}

/* ---- 4 · DRAWER ------------------------------------------------------------------------------ */
@media (min-width: 40rem) {
  html[data-dbl-banner="drawer"] #cc-main#cc-main .cm {
    position: fixed;
    inset-block: 0;
    inset-inline-end: 0;
    width: min(24rem, 90vw);
    max-width: none;
    height: 100vh;
    border-radius: 0;
    border-block: 0;
    border-inline-end: 0;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    overflow-y: auto;
    transform: none;
  }
  /* Copy at the top, actions pinned to the bottom. The engine nests .cm__btns INSIDE .cm__body, so the
     split has to happen there — spacing the children of .cm instead just pushed the whole block to one
     end and left two thirds of a full-height panel empty. */
  html[data-dbl-banner="drawer"] #cc-main#cc-main .cm__body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
  }
  html[data-dbl-banner="drawer"] #cc-main#cc-main .cm__texts {
    /* The engine lets this grow and centres its own content, which in a full-height panel put the
       heading 200px below the top edge. Sized to its text, then the auto margin does the pushing. */
    flex: 0 0 auto;
    justify-content: flex-start;
    margin-block-end: auto;
  }
}

/* ---- 5 · IMAGE CARD -------------------------------------------------------------------------- */
@media (min-width: 40rem) {
  html[data-dbl-banner="image"] #cc-main#cc-main .cm {
    max-width: min(40rem, calc(100vw - 2rem));
    display: grid;
    /* The image never takes more than a third. The copy is the point and must not be squeezed into a
       gutter to make room for decoration. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: 0;
    overflow: hidden;
  }
  /* Every track is placed by hand rather than auto-flowed. The engine opens the modal with an empty
     zero-height <div tabindex="-1"> focus sentinel as the first child of .cm, and auto-placement gave
     that the top-right cell — which pushed the copy down a row and left the image column a blank
     white strip. The sentinel shares the copy's cell instead of getting one of its own; it has to keep
     existing and stay focusable, so it is placed, not hidden. */
  html[data-dbl-banner="image"] #cc-main#cc-main .cm::before {
    content: "";
    display: block;
    grid-row: 1 / -1;
    grid-column: 1;
    background-image: var(--dbl-banner-image, none);
    background-size: cover;
    background-position: center;
    /* A tint behind it, so with no image configured the preset degrades to a coloured panel rather
       than a blank hole. */
    background-color: color-mix(in srgb, var(--primary, #e01a0c) 12%, transparent);
  }
  html[data-dbl-banner="image"] #cc-main#cc-main .cm > [tabindex="-1"],
  html[data-dbl-banner="image"] #cc-main#cc-main .cm__body {
    grid-row: 1;
    grid-column: 2;
  }
}

/* Large phone / small tablet: the column becomes a strip above the copy. */
@media (min-width: 25rem) and (max-width: 39.99rem) {
  html[data-dbl-banner="image"] #cc-main#cc-main .cm::before {
    content: "";
    display: block;
    height: 5rem;
    background-image: var(--dbl-banner-image, none);
    background-size: cover;
    background-position: center;
    margin: -1rem -1rem 0.75rem;
  }
}
/* Below 25rem the image is dropped: no room for decoration and a decision at the same time. */

/* ---- 6 · INLINE ------------------------------------------------------------------------------
   In the document flow at the top, pushing the page down. Nothing is covered, no focus trap is
   needed, and the choice comes first in the reading order. cookie-banner.js moves the engine root to
   the front of body — CSS alone cannot, since `position: static` would leave it where it was
   appended, at the end. */
html[data-dbl-banner="inline"] #cc-main {
  position: static;
}

html[data-dbl-banner="inline"] #cc-main#cc-main .cm {
  position: static;
  max-width: none;
  width: 100%;
  border-radius: 0;
  border-inline: 0;
  border-block-start: 0;
  box-shadow: none;
  /* No transform-based entry: it would animate the page height and shift the layout on every load. */
  transform: none;
}

/* The strip sits above the page in flow, but the Kit's main nav is `fixed top-0`, so on its own it
   would ignore the strip and be painted underneath it — the site header simply vanished. Offsetting by
   the measured height puts both on screen. Scoped to the Kit's own header markup: a client theme with a
   differently pinned header needs the same one-line offset, which is why the docs call this preset out. */
html[data-dbl-banner="inline"] header nav,
html[data-dbl-banner="inline"] header .menu-panel {
  top: var(--dbl-banner-height, 0);
}

@media (min-width: 60rem) {
  html[data-dbl-banner="inline"] #cc-main#cc-main .cm__body {
    /* The engine caps its own body at 880px: right for a box, wrong for a full-width strip — it
       left the text wrapping in a 412px column and made the strip three lines tall. */
    max-width: 90rem;
    margin-inline: auto;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 1.5rem;
  }
  html[data-dbl-banner="inline"] #cc-main#cc-main .cm__btns {
    margin: 0;
  }
}

/* ================================================================================================
   PHONES — one shape for every preset: a bottom sheet with full-width stacked actions. Last in the
   file so it wins over each preset's desktop rules.
   ================================================================================================ */
@media (max-width: 39.99rem) {
  html[data-dbl-banner]:not([data-dbl-banner="inline"]) #cc-main#cc-main .cm {
    position: fixed;
    inset-block-start: auto;
    inset-block-end: 0;
    inset-inline: 0;
    width: auto;
    max-width: none;
    height: auto;
    /* Rounded at the top only: it is attached to the bottom edge, not floating above it. */
    border-radius: var(--radius-xl, 0.75rem) var(--radius-xl, 0.75rem) 0 0;
    border-block-end: 0;
    border-inline: 0;
    transform: none;
    /* Past this a sheet starts behaving like a takeover. */
    max-height: 85vh;
    overflow-y: auto;
    margin: 0;
  }

  /* Full width, stacked, same order as desktop. Accept and reject stay adjacent and identically
     sized — that is the part that must not change with the viewport. */
  html[data-dbl-banner] #cc-main#cc-main .cm__btns,
  html[data-dbl-banner] #cc-main#cc-main .cm__btn-group,
  html[data-dbl-banner] #cc-main#cc-main .pm__btn-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  html[data-dbl-banner] #cc-main#cc-main .cm__btn,
  html[data-dbl-banner] #cc-main#cc-main .pm__btn {
    width: 100%;
    /* Comfortably above the 44px minimum touch target. */
    min-height: 3rem;
  }

  /* No room for a media column beside text at this width. */
  html[data-dbl-banner="image"] #cc-main#cc-main .cm {
    display: block;
  }
}
