/* ==========================================================================
   consent.css — cookie consent banner and preferences sheet

   Built on the tokens already in css/base/style.css (--surface-white, --ink,
   --mist, --line, --accent-fill, --radius, --scrim, the type scale), so it
   inherits light/dark automatically via [data-theme] and needs no palette
   of its own. Nothing here is !important and nothing here is global — every
   selector is namespaced under .nc- so it cannot collide with the rest of
   the site.

   Load order: after style.css, anywhere. It only styles elements that
   js/components/consent.js injects, so on a page without that script it is inert.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. The bar

   Fixed to the bottom rather than a full-screen interstitial. A blocking
   modal on first paint is a dark pattern in its own right — it pressures
   the "Accept" click — and several EU regulators have said so. The bar is
   dismissible, both buttons are equally prominent, and the page behind it
   stays usable.
   -------------------------------------------------------------------------- */

.nc-bar {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 9000;                 /* above the nav capsule, below nothing else */
  max-width: 560px;
  margin-inline: auto;
  padding: 20px 22px;
  background: var(--surface-white);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: 0 8px 40px rgba(0, 0, 0, 0.16);
  font-family: var(--font-body);
  color: var(--ink);
  text-align: left;              /* the site centres text in some contexts */

  /* Enters from below. Removed for prefers-reduced-motion at the bottom. */
  transform: translateY(16px);
  opacity: 0;
  transition: transform 260ms cubic-bezier(0.32, 0.72, 0, 1),
              opacity    200ms ease;
}

.nc-bar[data-open="true"] {
  transform: translateY(0);
  opacity: 1;
}

.nc-bar h2 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  line-height: var(--leading-subheading);
  letter-spacing: var(--tracking-subheading);
  font-weight: var(--font-weight-semibold);
  color: var(--ink);
}

.nc-bar p {
  margin: 0 0 16px;
  font-size: var(--text-body-sm);
  line-height: 1.5;
  color: var(--mist);
}

.nc-bar a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* --------------------------------------------------------------------------
   2. Actions

   "Accept" and "Reject" are the SAME size, weight and visual prominence.
   This is not a style choice — under DPDP Rule 3 and the EDPB's dark-pattern
   guidance, making refusal harder than acceptance invalidates the consent
   you collected. A greyed-out or text-only "Reject" next to a filled blue
   "Accept" is the single most common way a banner fails an audit.
   -------------------------------------------------------------------------- */

.nc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.nc-btn {
  flex: 1 1 auto;
  min-height: 44px;              /* iOS touch target floor */
  padding: 11px 18px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: opacity 150ms ease, background 150ms ease;
  -webkit-tap-highlight-color: transparent;
}

.nc-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Accept and Reject — identical treatment, deliberately. */
.nc-btn-primary {
  background: var(--accent-fill);
  color: #ffffff;
}

/* Reject is a SOLID fill, not a ghost button. A low-alpha outlined "Reject"
   next to a filled "Accept" reads as the lesser option even at identical
   dimensions, and that visual asymmetry is exactly what the CNIL and the
   EDPB have called out. Same size, same weight, same contrast — only the
   hue differs. */
.nc-btn-secondary {
  background: var(--surface-pebble);
  color: var(--ink);
  border-color: var(--line-strong, var(--line));
}

.nc-btn-primary:hover,
.nc-btn-secondary:hover { opacity: 0.86; }
.nc-btn-primary:active,
.nc-btn-secondary:active { opacity: 0.72; }

/* "Manage" is the genuinely secondary action — a third path, not a refusal
   path, so it is allowed to be quieter than the other two. */
.nc-btn-link {
  flex: 0 0 auto;
  background: none;
  border: none;
  padding: 11px 12px;
  color: var(--mist);
  font-size: var(--text-body-sm);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.nc-btn-link:hover { color: var(--ink); }

/* --------------------------------------------------------------------------
   3. Preferences sheet
   -------------------------------------------------------------------------- */

.nc-scrim {
  position: fixed;
  inset: 0;
  z-index: 9100;
  background: var(--scrim);
  opacity: 0;
  transition: opacity 200ms ease;
}

.nc-scrim[data-open="true"] { opacity: 1; }

.nc-sheet {
  position: fixed;
  z-index: 9200;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -48%);
  width: min(520px, calc(100vw - 32px));
  max-height: min(640px, calc(100dvh - 48px));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 26px 26px 20px;
  background: var(--surface-white);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 16px 60px rgba(0, 0, 0, 0.24);
  font-family: var(--font-body);
  color: var(--ink);
  text-align: left;
  opacity: 0;
  transition: opacity 200ms ease, transform 240ms cubic-bezier(0.32, 0.72, 0, 1);
}

.nc-sheet[data-open="true"] {
  opacity: 1;
  transform: translate(-50%, -50%);
}

.nc-sheet h2 {
  margin: 0 0 4px;
  font-family: var(--font-display);
  font-size: var(--text-heading-sm);
  line-height: var(--leading-heading-sm);
  letter-spacing: var(--tracking-heading-sm);
  font-weight: var(--font-weight-semibold);
}

.nc-sheet > p {
  margin: 0 0 20px;
  font-size: var(--text-body-sm);
  line-height: 1.5;
  color: var(--mist);
}

/* --- one category row --- */

.nc-cat {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 16px 0;
  border-top: 1px solid var(--line);
}

.nc-cat-body { flex: 1 1 auto; min-width: 0; }

.nc-cat-title {
  display: block;
  font-size: var(--text-body-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--ink);
  margin-bottom: 3px;
}

.nc-cat-desc {
  margin: 0;
  font-size: var(--text-caption);
  line-height: 1.45;
  color: var(--mist);
}

.nc-cat-always {
  flex: 0 0 auto;
  align-self: center;
  font-size: var(--text-caption);
  color: var(--mist);
  white-space: nowrap;
}

/* --- the switch ---

   A real <input type="checkbox">, visually replaced. Keyboard, screen
   readers and form semantics all keep working; only the pixels change.
   It ships UNCHECKED — a pre-ticked box is not consent under DPDP Rule 3,
   and js/components/consent.js never sets .checked = true on first run. --- */

.nc-switch {
  flex: 0 0 auto;
  align-self: center;
  position: relative;
  width: 51px;
  height: 31px;
}

.nc-switch input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: 1;
}

.nc-switch-track {
  position: absolute;
  inset: 0;
  background: var(--surface-pebble);
  border-radius: 999px;
  transition: background 200ms ease;
  pointer-events: none;
}

.nc-switch-track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  background: #ffffff;
  border-radius: 50%;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.22);
  transition: transform 220ms cubic-bezier(0.32, 0.72, 0, 1);
}

.nc-switch input:checked + .nc-switch-track {
  background: var(--accent-fill);
}

.nc-switch input:checked + .nc-switch-track::after {
  transform: translateX(20px);
}

.nc-switch input:focus-visible + .nc-switch-track {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.nc-sheet-actions {
  display: flex;
  gap: 8px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

/* Status line after a save — announced via role="status" in the markup. */
.nc-note {
  margin: 12px 0 0;
  font-size: var(--text-caption);
  color: var(--mist);
  min-height: 1em;
}

/* Desktop: a compact card in the bottom-left corner rather than a wide bar
   across the middle of the screen, where it sat on top of the hero art. The
   tour launcher lives bottom-right, so the two never collide. */
@media (min-width: 861px) {
  .nc-bar {
    left: 24px;
    right: auto;
    bottom: 24px;
    margin-inline: 0;
    max-width: 400px;
    padding: 18px 20px;
  }
}

/* --------------------------------------------------------------------------
   4. Phones

   Below 480px the three actions stack. Accept and Reject stay adjacent and
   identical; "Manage" drops to its own line underneath.
   -------------------------------------------------------------------------- */

@media (max-width: 480px) {
  .nc-bar {
    left: 10px;
    right: 10px;
    bottom: 10px;
    padding: 18px 18px 16px;
  }

  .nc-actions { gap: 8px; }

  .nc-btn { flex: 1 1 calc(50% - 4px); }

  .nc-btn-link {
    flex: 1 1 100%;
    order: 3;
    text-align: center;
  }

  .nc-sheet {
    width: calc(100vw - 20px);
    padding: 22px 20px 18px;
    max-height: calc(100dvh - 32px);
  }

  .nc-sheet-actions { flex-direction: column-reverse; }
}

/* --------------------------------------------------------------------------
   5. Reduced motion

   The bar and sheet still appear and disappear — they just do it instantly.
   Never suppress the element itself, only the travel.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .nc-bar,
  .nc-sheet,
  .nc-scrim,
  .nc-switch-track,
  .nc-switch-track::after {
    transition-duration: 0.01ms !important;
  }

  .nc-bar { transform: none; }
  .nc-sheet { transform: translate(-50%, -50%); }
}

/* --------------------------------------------------------------------------
   Footer "Cookie preferences" control

   It has to be a <button> — it opens a dialog, it does not navigate, and a
   link with href="#" that runs JS is exactly the pattern that breaks for
   keyboard and screen-reader users. But it sits in a row of links, so it is
   styled to be indistinguishable from its neighbours.
   -------------------------------------------------------------------------- */

.footer-legal-btn {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: color var(--transition);
}

.footer-legal-btn:hover { color: var(--accent); }

.footer-legal-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

/* ==========================================================================
   Contact-form consent block (contact.html)

   Separate from the cookie banner above, and legally a different thing: this
   is DPDP s.6 consent for the personal data in the form, not cookie consent.
   Styled to read as part of the form rather than as fine print — buried
   consent is contested consent.
   ========================================================================== */

.form-consent {
  margin: 4px 0 22px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--fill-subtle);
  text-align: left;
}

.form-consent-legend {
  padding: 0 8px;
  margin-left: -8px;
  font-size: var(--text-caption);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--mist);
}

.form-consent-notice {
  margin: 0 0 16px;
  font-size: var(--text-caption);
  line-height: 1.55;
  color: var(--mist);
}

.form-consent-notice strong { color: var(--ink); font-weight: var(--font-weight-semibold); }

.form-consent-notice a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* --- a consent row ---

   The checkbox is a real input at its native size, not a restyled span, and
   the label is clickable. 20px is above the 16px minimum that keeps a tick
   box usable on a phone without hitting the wrong one.
   --------------------------------------------------------------------- */

.form-consent-row {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  margin-bottom: 12px;
}

.form-consent-row:last-of-type { margin-bottom: 0; }

.form-consent-row input[type="checkbox"] {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin: 1px 0 0;
  accent-color: var(--accent-fill);
  cursor: pointer;
}

.form-consent-row label {
  font-size: var(--text-body-sm);
  line-height: 1.45;
  color: var(--ink);
  cursor: pointer;
}

.form-consent-req,
.form-consent-opt {
  display: block;
  margin-top: 2px;
  font-size: var(--text-caption);
  color: var(--mist);
}

.form-consent-req { color: var(--accent); font-weight: var(--font-weight-semibold); }

.form-consent-row input[type="checkbox"][aria-invalid="true"] {
  outline: 2px solid #ff3b30;
  outline-offset: 2px;
}

.form-consent-row input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (max-width: 480px) {
  .form-consent { padding: 16px; }
}
