/* ============================================================================
   COOKIE CONSENT & PREFERENCES (CC-01, CC-02)
   ----------------------------------------------------------------------------
   `.tr-consent*` — the preferences dialog and the reusable "Manage cookies"
   trigger. There is no consent banner: CC-02 removed it, so the dialog is
   reached on demand only.

   WHAT THIS FILE DELIBERATELY DOES NOT CONTAIN
   --------------------------------------------
   No modal shell, no overlay, no scroll lock, no transition, no button, no
   checkbox and no focus ring. Those are `unified/modal.css`, `unified/buttons.css`
   and `unified/fields.css`, and this component uses them as they are. What is
   here is the composition: how a category card is laid out, and the places the
   shared dialog needs refining to hold a form.

   CASCADE POSITION
   ----------------
   Enqueued with `tiorai-unified-modal` declared as a dependency, so this file's
   <link> is guaranteed to print after modal.css. The `.tr-consent-modal`
   overrides below raise specificity to 0,2,0 against modal.css's 0,1,0 anyway,
   but the declared dependency is what stops the two files' relative order from
   depending on which hook callback happened to run first (CLAUDE.md §5).

   All values are tokens. No new colour, radius, shadow or spacing value is
   introduced by this component.
   ========================================================================== */

/* ============================================================================
   1. THE REUSABLE TRIGGER
   ----------------------------------------------------------------------------
   A <button> that has to sit among <a> elements and not look like an intruder.

   This rule is a RESET ONLY — it strips the UA button chrome and inherits
   everything else. It deliberately sets no font-size and no colour, because the
   surface that hosts the trigger owns those: the footer styles it alongside its
   own links in `modules/footer/assets/css/footer.css`.

   `font: inherit` is not sufficient on its own, and that is the trap CC-02 fixed.
   The footer puts `font-size: 0.875rem` on `.bottom-links a` — on the ANCHOR, not
   on the `<li>` — so a `<button>` sibling inherits the list item's 1rem instead
   and renders visibly larger than every link beside it. A component that borrows
   a container's look has to be named in that container's own selectors; inherit
   only reaches what the parent actually declares.
   ============================================================================ */

.tr-consent-trigger {
  padding: 0;
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  text-decoration: inherit;
}

.tr-consent-trigger:focus-visible {
  outline: var(--tiorai-focus-ring-width) solid var(--tiorai-focus-ring-color);
  outline-offset: var(--tiorai-focus-ring-offset);
  border-radius: var(--radius-sm);
}

/* ============================================================================
   2. PREFERENCES DIALOG
   ----------------------------------------------------------------------------
   Three refinements to the shared `.ui-modal` shell, all scoped to this dialog:

   1. A narrower width than the 640px default — this is a short decision, not a
      content surface.
   2. Column layout, so the BODY scrolls and the actions stay reachable. The
      shared dialog scrolls as one block, which on a 320px screen can push
      "Save preferences" below the fold with no way to reach it without
      scrolling past every category.
   3. `dvh` for the height cap. `vh` on mobile is the viewport WITHOUT the
      browser's collapsing chrome, so a 92vh dialog is taller than the space
      actually visible and its footer hides behind the URL bar.
   ============================================================================ */

/* No `background` here on purpose: modal.css already paints the dialog
   `--color-bg-secondary`, which is opaque in both themes. Do not "improve" this
   with `--surface-card`: in dark that token is
   `linear-gradient(145deg, rgba(255,255,255,.04), rgba(255,255,255,.01))`, a
   translucent film meant to sit ON an opaque parent, and it made the whole
   dialog see-through over the page. Measured, in dark, during CC-01. */
.tr-consent-modal .ui-modal__dialog {
  --ui-modal-width: 34rem;
  display: flex;
  flex-direction: column;
  max-height: min(90vh, 100%);
}

@supports (height: 100dvh) {
  .tr-consent-modal .ui-modal__dialog {
    max-height: min(88dvh, 100%);
  }
}

.tr-consent-modal__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-5) var(--space-3);
  border-bottom: 1px solid var(--border-default, var(--color-border));
}

.tr-consent-modal__title {
  margin: 0;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-snug);
  color: var(--color-text-primary);
}

.tr-consent-modal__close {
  /* 44px, the same target the shared `.btn` uses. The shared `.ui-modal__close`
     sets appearance only and leaves sizing to the consumer. */
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  margin: calc(var(--space-2) * -1) calc(var(--space-2) * -1) 0 0;
  color: var(--color-text-secondary);
  border-radius: var(--radius-default);
}

.tr-consent-modal__close:hover {
  color: var(--color-text-primary);
  background: var(--surface-interactive, var(--color-bg-tertiary));
}

.tr-consent-modal__close:focus-visible {
  outline: var(--tiorai-focus-ring-width) solid var(--tiorai-focus-ring-color);
  outline-offset: var(--tiorai-focus-ring-offset);
}

/* The one scrolling region. `min-height: 0` is required for a flex child to be
   allowed to shrink below its content height, without which `overflow` here
   does nothing and the whole dialog scrolls instead. */
.tr-consent-modal__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: var(--space-4) var(--space-5);
}

.tr-consent-modal__intro {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  color: var(--color-text-secondary);
}

.tr-consent-modal__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-sm);
}

.tr-consent__link {
  color: var(--color-text-link);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.tr-consent__link:hover {
  text-decoration: none;
}

.tr-consent-modal__footer {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--border-default, var(--color-border));
  /* Same surface as the dialog it sits in, so the sticky footer reads as part
     of the panel rather than as a second card. Opaque in both themes. */
  background: var(--color-bg-secondary);
}

.tr-consent-modal__footer .tr-consent__action {
  flex: 1 1 10rem;
}

/* ============================================================================
   3. CATEGORY CARDS
   ============================================================================ */

.tr-consent__categories {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.tr-consent__category {
  padding: var(--space-4);
  border: 1px solid var(--border-default, var(--color-border));
  border-radius: var(--radius-lg);
  /* `--surface-base` IS the card surface (CLAUDE.md → Design System 2026, note
     3): #ffffff on the #f8fafc dialog in light, #070B12 on #101620 in dark.
     Opaque and clearly differentiated in BOTH — unlike `--surface-raised`,
     which resolves to the dialog's own #f8fafc in light and would make the
     card vanish into it. */
  background: var(--surface-base);
}

.tr-consent__category-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

/* The choice field is `flex` from unified/fields.css; it only needs to stop
   shrinking its label to nothing next to the badge. */
.tr-consent__control {
  flex: 1 1 auto;
  min-width: 0;
}

.tr-consent__category-label {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}

.tr-consent__badge {
  flex-shrink: 0;
  padding: var(--space-1) var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  color: var(--color-text-secondary);
  /* Sits ON the category card, so a translucent raise is the right role here
     and reads correctly in both themes. */
  background: var(--surface-raised, var(--color-bg-tertiary));
  border: 1px solid var(--border-default, var(--color-border));
  border-radius: var(--radius-full);
  white-space: nowrap;
}

.tr-consent__category-desc {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  color: var(--color-text-secondary);
}

/* ============================================================================
   4. RESPONSIVE
   ----------------------------------------------------------------------------
   Canonical breakpoints only (CLAUDE.md → Breakpoint Standard). 768px is the
   theme's main mobile boundary and is where the shared modal already switches
   to a bottom sheet; 640px is where the dialog's two actions stop fitting on
   one row.
   ============================================================================ */

@media (max-width: 768px) {

  .tr-consent-modal__header,
  .tr-consent-modal__body,
  .tr-consent-modal__footer {
    padding-inline: var(--space-4);
  }
}

@media (max-width: 640px) {

  .tr-consent-modal__footer .tr-consent__action {
    flex: 1 1 100%;
  }

  /* The badge would otherwise push the category name to one word per line at
     320px. Below the row is the only place left for it. */
  .tr-consent__category-row {
    flex-wrap: wrap;
  }
}

/* ============================================================================
   5. ACCESSIBILITY PREFERENCES
   ============================================================================ */

@media (prefers-reduced-motion: reduce) {

  .tr-consent-trigger,
  .tr-consent-modal__close {
    transition: none;
  }
}

@media (forced-colors: active) {

  .tr-consent__category {
    border: 1px solid CanvasText;
  }

  .tr-consent__badge {
    border: 1px solid CanvasText;
  }

  /* The focus ring is painted with a system colour in forced-colors mode, where
     the theme's ring token is ignored. Without this the ring disappears on the
     one control set that decides a privacy choice. */
  .tr-consent-trigger:focus-visible,
  .tr-consent-modal__close:focus-visible {
    outline: 2px solid CanvasText;
  }
}

/* ============================================================================
   6. PRINT
   ----------------------------------------------------------------------------
   The dialog is already invisible via the shared shell; this is belt and braces
   for a print stylesheet that resets `visibility`.
   ============================================================================ */

@media print {

  .tr-consent-modal {
    display: none !important;
  }
}
