/* Cookie consent card.

   A compact relative of the editorial card: the same surface, the same
   radius family, the same hairline and shadow language, scaled down. It
   floats in the bottom-right corner rather than sitting in the page flow,
   so it carries a border as well as a shadow — the border is what defines
   it against a dark ground, where the shadow alone does not read.

   Typography is inherited from the .type-* roles in the markup; this file
   sets no type properties of its own. */

.consent-card {
  --consent-padding: var(--space-5);

  position: fixed;
  z-index: 150;

  right: var(--page-padding);
  bottom: var(--page-padding);

  width: min(
    calc(100% - (var(--page-padding) * 2)),
    380px
  );

  max-height: calc(100dvh - (var(--page-padding) * 2));

  padding: var(--consent-padding);

  display: flex;
  flex-direction: column;

  gap: var(--space-4);

  overflow-y: auto;
  overscroll-behavior: contain;

  border: 1px solid var(--line);
  border-radius: var(--radius-xl);

  background: var(--surface-overlay);

  color: var(--text);

  box-shadow: var(--shadow-md);

  /* The entrance is the only motion: a short rise into place. Reduced
     motion is honoured globally, which leaves the card simply present. */
  animation: consent-enter 260ms var(--ease-out) both;
}

@keyframes consent-enter {
  from {
    opacity: 0;
    transform: translateY(var(--space-3));
  }
}

.consent-title {
  margin: 0;
}

.consent-body {
  margin: 0;
}

.consent-policy {
  color: var(--brand);

  text-decoration: underline;
  text-underline-offset: 2px;
}

.consent-policy:hover {
  text-decoration-thickness: 2px;
}

/* --- Preferences ------------------------------------------------------- */

.consent-options {
  display: flex;
  flex-direction: column;

  gap: var(--space-4);

  padding-top: var(--space-4);

  border-top: 1px solid var(--line);
}

.consent-option {
  display: flex;
  flex-direction: column;

  gap: var(--space-1);

  min-width: 0;
}

.consent-option-head {
  display: flex;
  align-items: center;
  justify-content: space-between;

  gap: var(--space-4);

  min-width: 0;
}

.consent-option-name {
  min-width: 0;

  overflow-wrap: anywhere;
}

.consent-option-note {
  margin: 0;
}

.consent-checkbox {
  flex: 0 0 auto;

  width: 18px;
  height: 18px;

  margin: 0;

  accent-color: var(--brand);

  cursor: pointer;
}

.consent-checkbox:disabled {
  cursor: default;
}

/* An always-on control still has to read as on rather than as broken. */
.consent-option:has(.consent-checkbox:disabled) .consent-checkbox {
  opacity: 0.55;
}

/* --- Actions ----------------------------------------------------------- */

.consent-actions {
  display: flex;
  flex-wrap: wrap;

  gap: var(--space-3);
}

/* Accept and Reject are the same size and the same weight of control. The
   only difference between them is fill, which is how this design system
   already distinguishes a filled surface from a bordered one — not a
   nudge toward either answer. */
.consent-button {
  flex: 1 1 0;

  min-width: 0;

  padding: var(--space-3) var(--space-4);

  appearance: none;
  -webkit-appearance: none;

  border: 1px solid transparent;
  border-radius: var(--radius-control);

  background: transparent;

  color: var(--text);

  cursor: pointer;

  transition:
    background-color var(--motion-ui),
    border-color var(--motion-ui),
    color var(--motion-ui);
}

/* The brand at full strength carries a 4.08:1 label on this page ground —
   short of the 4.5:1 that 16px text needs. Deepening it against --ink keeps
   the same hue and the same token as its source while clearing the
   threshold in both schemes. */
.consent-button--accept {
  --consent-accept: color-mix(in srgb, var(--brand) 90%, var(--ink));

  border-color: var(--consent-accept);

  background: var(--consent-accept);

  color: var(--background);
}

.consent-button--accept:hover {
  --consent-accept: color-mix(in srgb, var(--brand) 80%, var(--ink));
}

.consent-button--reject {
  border-color: var(--line-strong);
}

.consent-button--reject:hover {
  background: var(--surface-sunken);
  border-color: var(--text-secondary);
}

.consent-button--save {
  flex: 0 0 auto;

  width: 100%;

  border-color: var(--line-strong);
}

.consent-button--save:hover {
  background: var(--surface-sunken);
  border-color: var(--text-secondary);
}

/* The quiet third control. It opens a panel rather than deciding anything,
   so it carries no button chrome. */
.consent-manage {
  align-self: flex-start;

  padding: 0;

  appearance: none;
  -webkit-appearance: none;

  border: 0;

  background: transparent;

  /* Colour comes from the .type-meta role in the markup. */

  text-decoration: underline;
  text-underline-offset: 2px;

  cursor: pointer;

  transition: color var(--motion-ui);
}

.consent-manage:hover {
  color: var(--text);
}

/* --- Footer reopen control --------------------------------------------- */

/* Sits beside the copyright line. A button, not a link: it opens UI on this
   page and navigates nowhere. */
.consent-reopen {
  padding: 0;

  appearance: none;
  -webkit-appearance: none;

  border: 0;

  background: transparent;

  /* Colour comes from the .type-legal role in the markup, so the control
     matches the copyright line it sits beside. */

  cursor: pointer;

  transition: color var(--motion-ui);
}

.consent-reopen:hover {
  color: var(--text);
}

/* --- Small screens ------------------------------------------------------ */

@media (max-width: 560px) {

  .consent-card {
    --consent-padding: var(--space-4);

    right: var(--page-padding);
    left: var(--page-padding);

    width: auto;

    /* The page stays visible and usable behind the card: it takes the lower
       part of the screen, not the screen. With the preferences open the
       panel scrolls inside this bound rather than growing past it. */
    max-height: 58dvh;

    gap: var(--space-3);

    border-radius: var(--radius-lg);
  }

  .consent-options {
    gap: var(--space-3);

    padding-top: var(--space-3);
  }

  .consent-actions {
    gap: var(--space-2);
  }

}

@supports (padding: max(0px)) {
  .consent-card {
    bottom: max(var(--page-padding), env(safe-area-inset-bottom));
  }
}
