/* ==========================================================================
   FRONTGRADE  ·  CONSENT MANAGER SKIN AND CLEARANCE
   The consent notice and the preferences dialog are drawn by the Klaro
   library. Nothing here changes what it does; this file changes what it looks
   like and stops it sitting on top of the page.

   WHAT IT COVERS
     1. Tokens handed to the library. Klaro paints from a small set of its own
        CSS variables. They are pointed at the fg2 tokens so the dialog is
        made of the same greys, the same accent and the same type as the rest
        of the site rather than the library stock green on charcoal.
     2. The notice, restyled from a floating 400px card in the bottom right
        corner to a full width band across the foot of the page. The corner
        card landed on the accessibility trigger and the back to top button
        and covered whatever the page had scrolled to; a band can have its
        height measured and reserved, which is what makes the occlusion test
        pass rather than nearly pass.
     3. Reserved space, from the two values fg2/js/klaro-theme.js publishes:
          html[data-fg-consent="open"]   the notice is on screen
          --fg-consent-h                 how tall it is right now
        Those two names are also read by fg2/css/a11y.css, so neither may be
        renamed without changing that file too.
     4. The preferences dialog, restyled to the same palette, with the switch
        recoloured to the accent and every control given the theme focus ring.

   CONTRAST
   Every foreground and background pair below was measured against the rendered
   dialog rather than taken from the token file. Text pairs clear 4.5:1, and
   controls and boundaries clear 3:1 on the better of their fill and their
   border. Re-measure before changing any colour here.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. THE LIBRARY OWN VARIABLES
   Klaro paints from these. Setting them here means the parts of the library
   this file does not name explicitly still come out in the site palette
   rather than in the library defaults.
   -------------------------------------------------------------------------- */

.klaro {
  --font-family:       var(--font-body);
  --title-font-family: var(--font-display);
  --font-size:         var(--fs-body);

  --dark1:  var(--surface-raised);      /* dialog and notice ground        */
  --dark2:  var(--border-hairline-strong);
  --dark3:  var(--text-primary);
  --light1: var(--text-primary);        /* body text on the dark ground    */
  --light2: var(--border-default);
  --light3: var(--text-primary);
  --white1: var(--text-display);
  --white2: var(--surface-elevated);    /* switch track, off               */
  --white3: var(--text-display);        /* switch knob                     */

  --green1: var(--accent);
  --green2: var(--accent);
  --green3: var(--accent);
  --blue1:  var(--surface-elevated);
  --blue2:  var(--accent);

  --button-text-color: var(--text-on-accent);
  --border-radius: 0;
  --border-width: 1px;
  --border-style: solid;
}


/* --------------------------------------------------------------------------
   2. THE NOTICE, AS A BAND
   The library ships the notice as a fixed card in one corner above 1024px.
   Two things are wrong with a corner card here: it lands exactly where the
   accessibility trigger and the back to top button live, and its height
   cannot be reserved without reserving a strip of page the card does not
   actually cover. A full width band can be measured and reserved exactly.
   -------------------------------------------------------------------------- */

.klaro .cookie-notice:not(.cookie-modal-notice) {
  position: fixed;
  right: 0;
  left: 0;
  bottom: 0;
  top: auto;
  width: 100%;
  max-width: none;
  border-radius: 0;
  background: var(--surface-raised);
  border-top: var(--border-hairline-w) solid var(--border-hairline-strong);
  box-shadow: var(--shadow-panel);
  color: var(--text-primary);
  font: var(--type-body);
}

/* The band content column, so the text does not run the full width of a wide
   screen. */
.klaro .cookie-notice:not(.cookie-modal-notice) .cn-body {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--space-5) var(--space-6);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-7);
}

.klaro .cookie-notice:not(.cookie-modal-notice) .cn-body > h2 {
  flex: 1 0 100%;
  margin: 0;
  font: var(--fw-display) var(--fs-h4)/var(--lh-tight) var(--font-display);
  letter-spacing: var(--ls-h3);
  text-transform: uppercase;
  color: var(--text-display);
}

.klaro .cookie-notice:not(.cookie-modal-notice) .cn-body > p {
  flex: 1 1 32rem;
  margin: 0;
  font: var(--type-body);
  line-height: var(--lh-body);
  color: var(--text-primary);
}

.klaro .cookie-notice:not(.cookie-modal-notice) .cn-body > p strong {
  color: var(--text-display);
  font-weight: var(--fw-semibold);
}

/* The three controls sit together at the end of the band and wrap as one
   block, so the reject control can never be pushed onto a line of its own
   while the accept control keeps the prominent position. */
.klaro .cookie-notice:not(.cookie-modal-notice) .cn-ok {
  flex: 0 0 auto;
  margin: 0;
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-4);
}

.klaro .cookie-notice:not(.cookie-modal-notice) .cn-buttons {
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
}


/* --------------------------------------------------------------------------
   3. THE TWO ANSWERS, THE SAME SIZE AS EACH OTHER
   Refusing has to be as easy as agreeing. Both controls are buttons, both are
   one click, both sit in the same group, and the rules below give them the
   same box: the same padding, the same type, the same minimum width and the
   same border weight. Only the fill differs, and the reject control is the
   one that carries the lighter, higher contrast border.
   -------------------------------------------------------------------------- */

.klaro .cookie-notice .cm-btn,
.klaro .cookie-modal .cm-btn,
.klaro .context-notice .cm-btn {
  min-width: 10.5rem;
  margin: 0;
  padding: var(--space-3) var(--space-6);
  border: var(--border-hairline-w) solid transparent;
  border-radius: 0;
  font: var(--fw-semibold) var(--fs-small)/1.2 var(--font-body);
  letter-spacing: var(--ls-btn);
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-standard),
              border-color var(--dur-fast) var(--ease-standard);
}

/* Accept. */
.klaro .cookie-notice .cm-btn.cm-btn-success,
.klaro .cookie-modal .cm-btn.cm-btn-success,
.klaro .cookie-modal .cm-btn.cm-btn-accept-all {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-on-accent);
}

/* Reject. */
.klaro .cookie-notice .cm-btn.cn-decline,
.klaro .cookie-modal .cm-btn.cn-decline,
.klaro .cookie-notice .cm-btn.cm-btn-danger,
.klaro .cookie-modal .cm-btn.cm-btn-danger {
  background: var(--surface-elevated);
  border-color: var(--border-strong);
  color: var(--text-display);
}

/* Save the visitor own selection, inside the dialog. */
.klaro .cookie-modal .cm-btn.cm-btn-accept,
.klaro .cookie-modal .cm-btn.cm-btn-info {
  background: var(--surface-elevated);
  border-color: var(--border-strong);
  color: var(--text-display);
}

.klaro .cookie-notice .cm-btn.cm-btn-success:hover,
.klaro .cookie-modal .cm-btn.cm-btn-success:hover,
.klaro .cookie-modal .cm-btn.cm-btn-accept-all:hover {
  background: var(--accent-hover);
}

.klaro .cookie-notice .cm-btn.cn-decline:hover,
.klaro .cookie-modal .cm-btn.cn-decline:hover,
.klaro .cookie-modal .cm-btn.cm-btn-accept:hover,
.klaro .cookie-modal .cm-btn.cm-btn-info:hover {
  border-color: var(--accent);
}

.klaro .cm-btn:disabled { opacity: 0.6; cursor: default; }


/* --------------------------------------------------------------------------
   4. THE THIRD PATH
   Manage preferences is the route to the categories. The library renders it
   as a link and the module gives it role="button" and aria-haspopup="dialog",
   so it is announced as a button; it is styled as one too, quieter than the
   two answers but the same height, so the row reads as three controls.
   -------------------------------------------------------------------------- */

.klaro .cookie-notice .cm-link.cn-learn-more,
.klaro .cookie-modal .cm-link {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  margin: 0;
  padding: var(--space-3) var(--space-2);
  color: var(--text-display);
  font: var(--fw-semibold) var(--fs-small)/1.2 var(--font-body);
  letter-spacing: var(--ls-btn);
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.klaro .cookie-notice .cm-link.cn-learn-more:hover,
.klaro .cookie-modal .cm-link:hover { color: var(--accent); }

/* Body links inside the notice and the dialog. */
.klaro .cookie-notice a:not(.cm-btn):not(.cm-link),
.klaro .cookie-modal a:not(.cm-btn):not(.cm-link),
.klaro .context-notice a {
  color: var(--text-display);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.klaro .cookie-notice a:not(.cm-btn):not(.cm-link):hover,
.klaro .cookie-modal a:not(.cm-btn):not(.cm-link):hover { color: var(--accent); }


/* --------------------------------------------------------------------------
   5. FOCUS
   The theme two tone ring, on every control the dialog owns, including the
   notice container itself, which takes focus when the notice appears.
   -------------------------------------------------------------------------- */

.klaro .cm-btn:focus-visible,
.klaro .cm-link:focus-visible,
.klaro a:focus-visible,
.klaro button:focus-visible,
.klaro input:focus-visible,
.klaro #klaro-cookie-notice:focus-visible,
.klaro .cm-modal:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-inner);
  outline-offset: var(--focus-ring-offset);
  box-shadow: 0 0 0 calc(var(--focus-ring-width) + var(--focus-ring-offset)) var(--focus-ring-outer);
}

/* The switch is an opacity-zero input sitting over a drawn track, so the ring
   has to be drawn on the track instead. */
.klaro .cm-list-input:focus-visible + .cm-list-label .slider {
  outline: var(--focus-ring-width) solid var(--focus-ring-inner);
  outline-offset: var(--focus-ring-offset);
  box-shadow: 0 0 0 calc(var(--focus-ring-width) + var(--focus-ring-offset)) var(--focus-ring-outer);
}


/* --------------------------------------------------------------------------
   6. THE PREFERENCES DIALOG
   The module marks this one role="dialog" aria-modal="true";
   fg2/js/klaro-theme.js supplies the behaviour that claim implies. These
   rules supply the look.
   -------------------------------------------------------------------------- */

.klaro .cookie-modal .cm-bg { background: var(--scrim-strong); }

.klaro .cookie-modal .cm-modal.cm-klaro {
  background: var(--surface-raised);
  color: var(--text-primary);
  border: var(--border-hairline-w) solid var(--border-hairline-strong);
  border-radius: 0;
  box-shadow: var(--shadow-panel);
  max-width: 46rem;
}

.klaro .cookie-modal .cm-modal .cm-header {
  border-bottom-color: var(--border-hairline-strong);
  padding: var(--space-6) var(--space-7) var(--space-5);
}

.klaro .cookie-modal .cm-modal .cm-header h1.title {
  font: var(--fw-display) var(--fs-h3)/var(--lh-h3) var(--font-display);
  letter-spacing: var(--ls-h3);
  text-transform: uppercase;
  color: var(--text-display);
}

.klaro .cookie-modal .cm-modal .cm-header p { color: var(--text-primary); }

.klaro .cookie-modal .cm-modal .cm-body { padding: var(--space-5) var(--space-7); }

.klaro .cookie-modal .cm-modal .cm-footer {
  border-top-color: var(--border-hairline-strong);
  padding: var(--space-5) var(--space-7) var(--space-6);
}

.klaro .cookie-modal .cm-modal .cm-footer-buttons {
  display: flex;
  flex-flow: row wrap;
  gap: var(--space-3);
  justify-content: flex-start;
}

.klaro .cookie-modal .cm-modal .hide {
  top: var(--space-5);
  right: var(--space-5);
  padding: var(--space-2);
  cursor: pointer;
}
.klaro .cookie-modal .cm-modal .hide svg { stroke: var(--text-display); }

/* Purpose and service rows. */
.klaro .cookie-modal .cm-list-title,
.klaro .cookie-notice .cm-list-title {
  color: var(--text-display);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-body);
}

.klaro .cookie-modal .cm-list-description,
.klaro .cookie-notice .cm-list-description {
  color: var(--text-primary);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
}

.klaro .cookie-modal .cm-modal .cm-body ul.cm-purposes li.cm-purpose span.cm-required,
.klaro .cookie-modal .cm-modal .cm-body ul.cm-purposes li.cm-purpose span.cm-opt-out,
.klaro .cookie-modal .cm-modal .cm-body ul.cm-services li.cm-service span.cm-required,
.klaro .cookie-modal .cm-modal .cm-body ul.cm-services li.cm-service span.cm-opt-out,
.klaro .cookie-modal .cm-modal .cm-body ul.cm-purposes li.cm-purpose p.purposes,
.klaro .cookie-modal .cm-modal .cm-body ul.cm-services li.cm-service p.purposes,
.klaro .cookie-modal .cm-modal .cm-body ul.cm-purposes li.cm-purpose .cm-services .cm-caret {
  color: var(--text-primary);
  font-size: var(--fs-2xs);
}

.klaro .cookie-modal .cm-switch-container,
.klaro .cookie-notice .cm-switch-container {
  border-bottom-color: var(--border-hairline);
  padding-top: var(--space-4);
  padding-bottom: var(--space-4);
}

/* The switch. Off is a dark track with a light boundary on the dark panel, on
   is the accent. Both states clear 3:1 against the panel they sit on. */
.klaro .cookie-modal .cm-list-label .slider,
.klaro .cookie-notice .cm-list-label .slider {
  background-color: var(--surface-elevated);
  border: var(--border-hairline-w) solid var(--border-strong);
  box-shadow: none;
}

.klaro .cookie-modal .cm-list-label .slider::before,
.klaro .cookie-notice .cm-list-label .slider::before {
  background-color: var(--text-display);
}

.klaro .cookie-modal .cm-list-input:checked + .cm-list-label .slider,
.klaro .cookie-notice .cm-list-input:checked + .cm-list-label .slider {
  background-color: var(--accent);
  border-color: var(--accent);
  opacity: 1;
}

.klaro .cookie-modal .cm-list-input:checked + .cm-list-label .slider::before,
.klaro .cookie-notice .cm-list-input:checked + .cm-list-label .slider::before {
  background-color: var(--text-on-accent);
}

.klaro .cookie-modal .cm-list-input.required:checked + .cm-list-label .slider,
.klaro .cookie-modal .cm-list-input.only-required + .cm-list-label .slider {
  background-color: var(--accent);
  border-color: var(--accent);
  opacity: 1;
  cursor: not-allowed;
}

.klaro .cookie-modal .cm-list-input.half-checked:checked + .cm-list-label .slider {
  background-color: var(--surface-elevated);
  border-color: var(--accent);
  opacity: 1;
}


/* --------------------------------------------------------------------------
   7. THE CONTEXTUAL PLACEHOLDER
   What stands in for a blocked embed until the visitor allows it.
   -------------------------------------------------------------------------- */

.klaro .context-notice {
  background: var(--surface-panel);
  border: var(--border-hairline-w) solid var(--border-hairline-strong);
  border-radius: 0;
  color: var(--text-primary);
  padding: var(--space-6);
}
.klaro .context-notice p { color: var(--text-primary); }
.klaro .context-notice.cm-dark { background: var(--surface-panel); }
.klaro .context-notice.cm-dark p { color: var(--text-primary); }


/* --------------------------------------------------------------------------
   8. RESERVED SPACE
   The two values published by fg2/js/klaro-theme.js become the guarantee that
   nothing focusable ever sits underneath the notice.

   scroll-padding-bottom takes the band out of the region the browser treats
   as in view, so focusing anything scrolls it clear of the band instead of
   behind it. The extra space is the focus ring own room: the ring is drawn
   2px outside the element at a 2px offset.

   padding-bottom on body adds the band height to the end of the document so
   the last elements on the page can be scrolled clear too. The reserve is
   never visible, because the only moment it is on screen is at the very
   bottom of the scroll, which is exactly where the band is painted over it.

   Both are withdrawn the moment the notice goes.
   -------------------------------------------------------------------------- */

html[data-fg-consent="open"] {
  scroll-padding-bottom: calc(var(--fg-consent-h, 0px) + var(--space-4, 16px));
}

html[data-fg-consent="open"] body {
  padding-bottom: var(--fg-consent-h, 0px);
}

/* The back to top button is fixed, so reserved space cannot move it. It is
   lifted by the band own measured height and raised past it in the stack,
   the same treatment the accessibility trigger gets in fg2/css/a11y.css. */
html[data-fg-consent="open"] .back-to-top {
  bottom: calc(0.625rem + var(--fg-consent-h, 0px));
  z-index: 100000;
}


/* --------------------------------------------------------------------------
   9. THE BAND SHARE OF A SMALL SCREEN
   Every pixel the band takes is a pixel of reserved space the reader loses.
   It is capped at a third of the small viewport and scrolls inside itself
   past that, so the page keeps two thirds of the screen whatever the text
   grows to. The cap is a maximum, not a height: a band that fits is left
   alone.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
  .klaro .cookie-notice:not(.cookie-modal-notice) {
    max-height: 34vh;
    max-height: 34dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .klaro .cookie-notice:not(.cookie-modal-notice) .cn-body {
    padding: var(--space-4);
    gap: var(--space-3) var(--space-4);
  }

  .klaro .cookie-notice:not(.cookie-modal-notice) .cn-ok {
    flex: 1 1 100%;
    justify-content: stretch;
  }

  .klaro .cookie-notice:not(.cookie-modal-notice) .cn-buttons {
    flex: 1 1 100%;
  }

  /* Both answers keep the same box on a phone as well: one row, equal share. */
  .klaro .cookie-notice:not(.cookie-modal-notice) .cn-buttons .cm-btn {
    flex: 1 1 0;
    min-width: 0;
    padding-left: var(--space-3);
    padding-right: var(--space-3);
  }
}

@media (max-width: 660px) {
  .klaro .cookie-modal .cm-modal.cm-klaro { max-height: 92vh; max-height: 92dvh; }
  .klaro .cookie-modal .cm-modal .cm-header,
  .klaro .cookie-modal .cm-modal .cm-body,
  .klaro .cookie-modal .cm-modal .cm-footer {
    padding-left: var(--space-5);
    padding-right: var(--space-5);
  }
  .klaro .cookie-modal .cm-modal .cm-footer-buttons .cm-btn { flex: 1 1 100%; }
}


/* --------------------------------------------------------------------------
   10. MOTION AND PRINT
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .klaro .cm-btn,
  .klaro .cm-list-label .slider,
  .klaro .cm-list-label .slider::before { transition: none; }
}

@media print {
  html[data-fg-consent="open"] body { padding-bottom: 0; }
  .klaro { display: none !important; }
}
