/* Opt-in default theme for the embed widget v1.
 *
 * One file, two modes: every rule below scopes to both `.ue-library`
 * (library mode) and `.ue-microsite` (microsite mode). The token block
 * lives inside a single `:where(.ue-library, .ue-microsite)` so token
 * specificity stays at 0 — customer brand stylesheets scoped to their
 * own `rootClass` always win regardless of stylesheet order.
 *
 * Bundles three layers:
 *   1. Reset: neutralize host-page CSS (broad rules on lists, forms,
 *      headings, inputs) so the widget renders predictably wherever it
 *      lives.
 *   2. Structure: layout shell, grid, search/filter shells, pagination
 *      geometry. Filters apply only to library mode; microsite header
 *      rules apply only to microsite mode.
 *   3. Visual taste: colour, typography, borders, radii — all driven by
 *      CSS custom properties so customers rebrand by overriding the
 *      vars on their own `rootClass`, not by rewriting structural rules.
 *
 * Customers load this via:
 *   <link rel="stylesheet" href="/embed/v1/default.css">
 *
 * Mode-specific rules:
 *   * `.ue-library__*` selectors  — library shell, filters panel
 *   * `.ue-microsite__*` selectors — microsite header / CTA
 * Shared rules (`.ue-asset*`, `.ue-search*`, `.ue-pagination`, etc.)
 * apply to both modes via a comma-list selector at the top.
 *
 * Specificity contract: component rules scope through
 * `:where(.ue-library, .ue-microsite)`, which contributes ZERO
 * specificity — every component rule weighs a single class
 * (0-1-0). Customers override any of them with just the bare class
 * (`.ue-asset__title { … }`) in a stylesheet loaded after this one, no
 * parent repetition needed; a rootClass-scoped override
 * (`.acme .ue-asset__title`) beats them outright. Only the reset layer
 * below keeps full-weight selectors — it is the armour against host-page
 * CSS, not an override surface.
 */

/* --- Root + custom properties + universal reset -------------------- */

/* Brand-able tokens live inside :where() so their specificity is 0.
   When `default.css` loads after the customer's brand stylesheet,
   tokens declared on `.<rootClass>` (specificity 0-1-0) win over the
   defaults below regardless of stylesheet order — which is the whole
   point of letting customers theme via CSS variables on rootClass. */
:where(.ue-library, .ue-microsite) {
  /* ── Brand-able tokens ───────────────────────────────────────────
     Customers override any of these on `.<rootClass>` to rebrand
     without touching structural rules. Default values are deliberately
     neutral — no brand colour ships in default.css.

     ── Colours ─── */
  --ue-color-text: #111;
  --ue-color-muted: #666;
  --ue-color-border: hsl(200, 24%, 90%);
  --ue-color-surface: #fff;
  --ue-color-error: #b00020;

  /* Accent — used by chart bar fills + stat headlines. Defaults to
     the body text colour so no brand colour ships. */
  --ue-color-link: var(--ue-color-text);

  /* ── Type label on each card ───
     Ships as an icon + muted uppercase caption (mirrors the original
     embedded research library). Brands can re-enable a filled pill by
     overriding `--ue-pill-bg` / `--ue-pill-padding` on their rootClass. */
  --ue-pill-bg: transparent;
  --ue-pill-color: var(--ue-color-link);
  --ue-pill-icon-color: var(--ue-color-link);
  --ue-pill-padding: 0;
  --ue-pill-border-radius: 999px;
  --ue-pill-font-size: 10px;

  /* ── Asset card chrome ───
     Hover matches the original embed: the border tints to the accent, with
     no lift / shadow. Brands can opt back into a shadow / transform by
     overriding the hover tokens on their rootClass. */
  --ue-asset-border: var(--ue-color-border);
  --ue-asset-padding: 24px 20px 16px;
  --ue-asset-gap: 1rem;
  --ue-asset-hover-border: var(--ue-color-link);
  --ue-asset-hover-shadow: none;
  --ue-asset-hover-transform: none;

  /* ── Card preview image ─── */
  --ue-preview-aspect-ratio: 16 / 9;
  --ue-preview-background: color-mix(in srgb, var(--ue-color-border) 30%, var(--ue-color-surface));

  /* ── Avatar (testimonials) ─── */
  --ue-avatar-size: 48px;

  /* ── Asset grid layout ───
     `grid-min` controls how dense the grid is — smaller values pack
     more cards across, larger values give each card more room. */
  --ue-grid-min: 16rem;
  --ue-grid-gap: 1rem;

  /* ── Typography ─── */
  /* No font-family here on purpose: the widget inherits the host page's font. */
  --ue-font-size-base: 1rem;
  --ue-font-size-title: 20px;
  --ue-font-size-description: 0.875rem;
  --ue-font-size-meta: 0.75rem;
  --ue-font-size-stat-headline: 2rem;
  --ue-line-height: 1.5;

  /* ── Geometry ───
     `--ue-border-radius` is the master roundness knob: cards, the CTA
     button, preview images and form controls derive from it. The default
     is square (0); brands opt into rounding by overriding the master once
     (or `--ue-control-border-radius` individually). Fixed-shape details —
     pill/tag chips, chart bars, avatars, the × clear buttons, the
     spinner — keep their own values regardless. */
  --ue-border-radius: 0;
  --ue-control-border-radius: var(--ue-border-radius);

  /* ── Form controls — same height/border across search, selects,
     pagination buttons. */
  --ue-control-height: 2.5rem;
  --ue-control-padding-x: 0.75rem;
  --ue-control-border: 1px solid var(--ue-color-border);
}

/* Block-level wrapper styling shared across modes. The :where() block
   above is specificity 0, which means a host page's `div { ... }` rule
   would override `display`/`width`. The explicit selectors here run at
   normal specificity so the widget keeps its block layout. */
.ue-library,
.ue-microsite {
  display: block;
  width: 100%;
  box-sizing: border-box;
  color: var(--ue-color-text);
  font-size: var(--ue-font-size-base);
  line-height: var(--ue-line-height);
}

/* Scoped reset — an explicit reset (in the spirit of Meyer/normalize),
   applied to every descendant of the widget root. It zeroes the decorative
   and inheritable properties a host page (or the browser) commonly sets —
   margins, padding, borders, backgrounds, fonts, text decoration, list
   markers — so nothing leaks into the widget, while deliberately leaving
   FUNCTIONAL properties untouched (`display`, `width`/`height`, `fill`,
   the SVG `d` geometry, `object-fit`, `appearance`, `position`, flex/grid).
   A blanket `all: revert`/`unset` was tried first but it also resets the
   SVG `d` property to `none`, which overrides the path's `d` attribute and
   makes every icon vanish — hence the explicit list here. The widget's own
   component rules (equal specificity, later in the file) re-skin on top. */
.ue-library *,
.ue-library *::before,
.ue-library *::after,
.ue-microsite *,
.ue-microsite *::before,
.ue-microsite *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  border: 0 solid transparent;
  background: transparent;
  font-size: 100%;
  line-height: inherit;
  color: inherit;
  text-align: inherit;
  text-decoration: none;
  text-transform: none;
  letter-spacing: normal;
  list-style: none;
  vertical-align: baseline;
  box-shadow: none;
}

/* Reset elements the host might be styling globally. */
.ue-library h1,
.ue-library h2,
.ue-library h3,
.ue-library h4,
.ue-library h5,
.ue-library h6,
.ue-library p,
.ue-library figure,
.ue-library blockquote,
.ue-microsite h1,
.ue-microsite h2,
.ue-microsite h3,
.ue-microsite h4,
.ue-microsite h5,
.ue-microsite h6,
.ue-microsite p,
.ue-microsite figure,
.ue-microsite blockquote {
  margin: 0;
  padding: 0;
  /* Host pages often style <blockquote> with a left border/indent — zero
     borders here so that decoration can't leak into the widget. */
  border: 0;
}

.ue-library ul,
.ue-library ol,
.ue-microsite ul,
.ue-microsite ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The hard reset (`all: unset`) strips interaction affordances the browser
   normally provides — pointer cursor on links/controls and the focus ring.
   Re-establish them so the widget stays usable and accessible. */
.ue-library a,
.ue-library button,
.ue-library select,
.ue-library [role='button'],
.ue-microsite a,
.ue-microsite button,
.ue-microsite select,
.ue-microsite [role='button'] {
  cursor: pointer;
}
.ue-library button:disabled,
.ue-microsite button:disabled {
  cursor: not-allowed;
}
.ue-library a:focus-visible,
.ue-library button:focus-visible,
.ue-library select:focus-visible,
.ue-library input:focus-visible,
.ue-microsite a:focus-visible,
.ue-microsite button:focus-visible,
.ue-microsite select:focus-visible,
.ue-microsite input:focus-visible {
  outline: 2px solid var(--ue-color-link);
  outline-offset: 2px;
}

.ue-library img,
.ue-microsite img {
  max-width: 100%;
  height: auto;
  display: block;
}

.ue-library a,
.ue-microsite a {
  color: inherit;
  text-decoration: none;
}

.ue-library input,
.ue-library select,
.ue-library button,
.ue-library textarea,
.ue-microsite input,
.ue-microsite select,
.ue-microsite button,
.ue-microsite textarea {
  /* Form controls don't inherit the surrounding font by default (they render
     in the UA font) — `font: inherit` keeps them on the host page's typeface,
     which is the theme's font story (no font-family is ever set here). */
  font: inherit;
  color: inherit;
  margin: 0;
}

/* --- Layout shell -------------------------------------------------- */

/* Library shell carries header (search + filters) over the grid. */
:where(.ue-library, .ue-microsite) .ue-library__inner {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
:where(.ue-library, .ue-microsite) .ue-library__header {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Microsite header (title / description / CTA). */
:where(.ue-library, .ue-microsite) .ue-microsite__inner {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
:where(.ue-library, .ue-microsite) .ue-microsite__header {
  margin-bottom: 0.5rem;
}
:where(.ue-library, .ue-microsite) .ue-microsite__title {
  font-size: 1.5rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}
:where(.ue-library, .ue-microsite) .ue-microsite__description {
  color: var(--ue-color-muted);
  margin-bottom: 0.5rem;
}
:where(.ue-library, .ue-microsite) .ue-microsite__cta {
  display: inline-block;
  padding: 0.5rem 1rem;
  border: 1px solid var(--ue-color-border);
  border-radius: var(--ue-border-radius);
  margin-top: 0.5rem;
}

/* --- Search -------------------------------------------------------- */
:where(.ue-library, .ue-microsite) .ue-search__label {
  display: block;
}

/* Visually hide the label text (kept for screen readers). */
:where(.ue-library, .ue-microsite) .ue-search__label-text {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
:where(.ue-library, .ue-microsite) .ue-search__input,
:where(.ue-library, .ue-microsite) .ue-filters__select,
:where(.ue-library, .ue-microsite) .ue-pagination button {
  display: inline-block;
  height: var(--ue-control-height);
  padding: 0 var(--ue-control-padding-x);
  border: var(--ue-control-border);
  border-radius: var(--ue-control-border-radius);
  background: var(--ue-color-surface);
  color: inherit;
  line-height: 1.5;
}

/* Search field: input + inline clear button overlayed on the right. */
:where(.ue-library, .ue-microsite) .ue-search__field {
  position: relative;
  display: block;
}
:where(.ue-library, .ue-microsite) .ue-search__input {
  display: block;
  width: 100%;
  min-width: 0;
  padding-right: 2.25rem;
}

/* Suppress the browser's native search clear button so we own the affordance. */
:where(.ue-library, .ue-microsite) .ue-search__input::-webkit-search-cancel-button,
:where(.ue-library, .ue-microsite) .ue-search__input::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
}

/* Filter select: select + inline clear button overlayed on the right. */
:where(.ue-library, .ue-microsite) .ue-filters__select-wrap {
  position: relative;
  display: block;
}
:where(.ue-library, .ue-microsite) .ue-filters__select {
  width: 100%;
  /* Truncate a long selected value with an ellipsis instead of a hard cut
     when several filters share a row and each select is narrow. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Extra right padding leaves room for both our "×" button and the
     chevron. */
  padding-right: 3.5rem;
  /* Custom chevron so we control the gap from the border (the native
     arrow sits flush against the edge). Vendor prefixes are required or
     some browsers keep the native arrow AND render ours — two chevrons. */
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23666' stroke-width='2' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
  background-size: 0.7rem;
}

/* Shared inline "×" button for search + select clear actions. */
:where(.ue-library, .ue-microsite) .ue-search__clear,
:where(.ue-library, .ue-microsite) .ue-filters__clear {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ue-color-muted);
  font-size: 1.125rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 999px;
}

/* Search has no native trailing UI, so the × sits at the edge. */
:where(.ue-library, .ue-microsite) .ue-search__clear {
  right: 0.375rem;
}

/* Selects render a native chevron on the right (≈1.5rem wide); leave
   it room so the × button isn't visually glued to it. */
:where(.ue-library, .ue-microsite) .ue-filters__clear {
  right: 1.75rem;
}
:where(.ue-library, .ue-microsite) .ue-search__clear:hover,
:where(.ue-library, .ue-microsite) .ue-filters__clear:hover {
  background: transparent;
  color: inherit;
}

/* Keyboard focus must remain visible — replace the suppressed default
   outline with a tighter focus-visible ring. */
:where(.ue-library, .ue-microsite) .ue-search__clear:focus-visible,
:where(.ue-library, .ue-microsite) .ue-filters__clear:focus-visible {
  outline: 2px solid var(--ue-color-link);
  outline-offset: 2px;
}

/* --- Filters (library only) ---------------------------------------- */
:where(.ue-library, .ue-microsite) .ue-filters__row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem;
}
:where(.ue-library, .ue-microsite) .ue-filters__group {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  flex: 1 1 10rem;
  min-width: 0;
}
:where(.ue-library, .ue-microsite) .ue-filters__clear {
  align-self: flex-end;
  cursor: pointer;
}

/* --- Results wrapper (grid + pagination) --------------------------- */
:where(.ue-library, .ue-microsite) .ue-results {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* During a refetch (new query/filter/page) the previous grid stays
   visible: we dim it and surface a centered spinner instead of blanking
   the page. */
:where(.ue-library, .ue-microsite) .ue-results--refetching .ue-asset-grid,
:where(.ue-library, .ue-microsite) .ue-results--refetching .ue-status {
  opacity: 0.45;
  pointer-events: none;
  transition: opacity 120ms ease-out;
}
:where(.ue-library, .ue-microsite) .ue-results__refetch-indicator {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  background: var(--ue-color-surface);
  border: var(--ue-control-border);
  border-radius: 999px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

/* --- Spinner ------------------------------------------------------- */
:where(.ue-library, .ue-microsite) .ue-spinner {
  display: inline-block;
  width: 1.5rem;
  height: 1.5rem;
  border: 2px solid color-mix(in srgb, var(--ue-color-border) 60%, transparent);
  border-top-color: var(--ue-color-muted);
  border-radius: 50%;
  animation: ue-spin 0.75s linear infinite;
}

@keyframes ue-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Screen-reader-only utility for the spinner's accessible label. */
:where(.ue-library, .ue-microsite) .ue-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Asset grid ---------------------------------------------------- */
:where(.ue-library, .ue-microsite) .ue-asset-grid {
  /* Masonry is applied at runtime by the widget (useMasonry / Macy): it sets
     the container height and absolutely positions each card into balanced,
     fully-used columns — no trailing column ever ends up empty.

     The CSS multi-column declarations below are the PRE-masonry fallback:
     without them the cards render as a stack of full-width blocks for the
     frames between the API response and Macy's first layout — a giant
     single-column flash. Multi-column approximates the final look during
     that window (and covers no-JS). Once Macy runs, every item is
     absolutely positioned, so the column flow has nothing left to lay out. */
  position: relative;
  column-width: var(--ue-grid-min);
  column-gap: var(--ue-grid-gap);
}
:where(.ue-library, .ue-microsite) .ue-asset-grid__item {
  display: block;
  /* Only affects the pre-masonry / no-JS fallback (Macy positions items
     absolutely, so these are ignored once it runs). */
  break-inside: avoid;
  margin-bottom: var(--ue-grid-gap);
}
:where(.ue-library, .ue-microsite) .ue-asset {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--ue-color-surface);
  border: 1px solid var(--ue-asset-border);
  border-radius: var(--ue-border-radius);
  overflow: hidden;
  transition:
    border-color 120ms ease-out,
    box-shadow 120ms ease-out,
    transform 120ms ease-out;
}
:where(.ue-library, .ue-microsite) .ue-asset:hover {
  border-color: var(--ue-asset-hover-border);
  box-shadow: var(--ue-asset-hover-shadow);
  transform: var(--ue-asset-hover-transform);
}
:where(.ue-library, .ue-microsite) .ue-asset__link {
  display: flex;
  flex-direction: column;
  gap: var(--ue-asset-gap);
  flex: 1;
  padding: var(--ue-asset-padding);
  color: inherit;
  text-decoration: none;
}

/* Non-clickable cards (per-asset `embedded_click_behavior: 'off'`) render
 * the link wrapper as a <div>. Strip the hover affordance so the card
 * doesn't pretend to be interactive. */
:where(.ue-library, .ue-microsite) .ue-asset[data-ue-click-behavior='off']:hover {
  border-color: var(--ue-asset-border);
  box-shadow: none;
  transform: none;
}
:where(.ue-library, .ue-microsite) .ue-asset[data-ue-click-behavior='off'] .ue-asset__link {
  cursor: default;
}
:where(.ue-library, .ue-microsite) .ue-asset__type-label {
  display: flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  margin: 0;
  padding: var(--ue-pill-padding);
  background: var(--ue-pill-bg);
  border-radius: var(--ue-pill-border-radius);
  color: var(--ue-pill-color);
  font-size: var(--ue-pill-font-size);
  font-weight: 800;
  letter-spacing: 1.5px;
  line-height: 1;
  text-transform: uppercase;
}
:where(.ue-library, .ue-microsite) .ue-asset__type-icon {
  width: 12px;
  height: 12px;
  flex: none;
  fill: var(--ue-pill-icon-color);
  opacity: 0.5;
}
:where(.ue-library, .ue-microsite) .ue-asset__title {
  margin: 0;
  font-size: var(--ue-font-size-title);
  font-weight: 800;
  line-height: 1.3;
  color: var(--ue-color-text);
  word-break: break-word;
}
:where(.ue-library, .ue-microsite) .ue-asset__quote {
  /* Neutralise host-page <blockquote> styling (border-left bars, indents)
     that leaks past the reset — the quote is a plain text block here. */
  margin: 0;
  padding: 0;
  border: 0;
  quotes: none;
}
:where(.ue-library, .ue-microsite) .ue-asset__quote-text {
  margin: 0;
  font-size: 18px;
  line-height: 27px;
  /* Long unbroken testimonials can blow past the card width on narrow
   * grids — wrap aggressively at word boundaries. */
  overflow-wrap: anywhere;
}

/* Header line (question / title) — bold black, matching the original
   embed's BasicHeader (not an italic muted caption). */
:where(.ue-library, .ue-microsite) .ue-asset__prompt,
:where(.ue-library, .ue-microsite) .ue-asset__question {
  margin: 0;
  color: var(--ue-color-text);
  font-size: 16px;
  font-weight: 600;
  line-height: 24px;
  overflow-wrap: anywhere;
}
:where(.ue-library, .ue-microsite) .ue-asset__attribution {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  margin: 0.5rem 0 0;
}
:where(.ue-library, .ue-microsite) .ue-asset__avatar {
  width: var(--ue-avatar-size);
  height: var(--ue-avatar-size);
  border-radius: 999px;
  border: 1px solid var(--ue-color-text);
  object-fit: cover;
  flex: none;
}

:where(.ue-library, .ue-microsite) .ue-asset__attribution-lines {
  display: flex;
  flex-direction: column;
  font-size: 14px;
  min-width: 0;
}
:where(.ue-library, .ue-microsite) .ue-asset__attribution-name {
  font-size: 22px;
  font-weight: 600;
  line-height: 1;
}
:where(.ue-library, .ue-microsite) .ue-asset__attribution-role,
:where(.ue-library, .ue-microsite) .ue-asset__attribution-company {
  font-size: 14px;
  line-height: 1.25;
}
:where(.ue-library, .ue-microsite) .ue-asset__nps {
  margin-left: auto;
  text-align: center;
}
:where(.ue-library, .ue-microsite) .ue-asset__nps-score {
  display: block;
  font-size: 34px;
  font-weight: 600;
  line-height: 1;
}
:where(.ue-library, .ue-microsite) .ue-asset__nps-label {
  font-size: 18px;
  font-weight: 600;
  line-height: 1;
}
:where(.ue-library, .ue-microsite) .ue-asset__stat-headline {
  margin: 0;
  font-size: var(--ue-font-size-stat-headline);
  line-height: 1.1;
  font-weight: 700;
  color: var(--ue-color-link);
  overflow-wrap: anywhere;
}
:where(.ue-library, .ue-microsite) .ue-asset__stat-sentence {
  margin: 0.5rem 0 0;
  overflow-wrap: anywhere;
}
:where(.ue-library, .ue-microsite) .ue-asset__date,
:where(.ue-library, .ue-microsite) .ue-asset__chart-meta {
  margin: 0.75rem 0 0;
  color: var(--ue-color-muted);
  font-size: var(--ue-font-size-meta);
}

/* Card footer — "UE verified" line + uevi.co share link, mirroring the
   original embedded research library. Pushed to the bottom of the card so
   footers align across a row; the top border reads as a divider. */
:where(.ue-library, .ue-microsite) .ue-asset__footer {
  /* Stacked (verified line above the uevi link), matching the original
     embed's list-view footer (`.as_list .basic-footer` = column). */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
  padding: 0.75rem 20px 1rem;
  border-top: 1px solid var(--ue-color-border);
  font-size: 14px;
  font-weight: 600;
}
:where(.ue-library, .ue-microsite) .ue-asset__verified {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: var(--ue-color-text);
}
:where(.ue-library, .ue-microsite) .ue-asset__ue-mark {
  width: 0.9em;
  height: 0.9em;
  flex: none;
  fill: currentColor;
}
:where(.ue-library, .ue-microsite) .ue-asset__uevi {
  color: var(--ue-color-link);
  text-decoration: none;
  white-space: nowrap;
}
:where(.ue-library, .ue-microsite) .ue-asset__uevi:hover {
  text-decoration: underline;
}
:where(.ue-library, .ue-microsite) .ue-asset__source {
  margin: 0.5rem 0 0;
  font-size: var(--ue-font-size-meta);
  color: var(--ue-color-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:where(.ue-library, .ue-microsite) .ue-asset__source-label {
  margin-right: 0.25rem;
}
:where(.ue-library, .ue-microsite) .ue-asset__description {
  margin: 0;
  /* Body copy, not a caption — follows the main text colour so a brand's
     --ue-color-text override carries the description with it. Only true
     secondary text (dates, meta, source lines) uses --ue-color-muted. */
  color: var(--ue-color-text);
  font-size: var(--ue-font-size-description);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}
:where(.ue-library, .ue-microsite) .ue-asset__preview {
  /* Cap the preview image to the card width and force a fixed aspect
   * ratio so a portrait PDF doesn't blow up the card height. Without
   * `object-fit: cover` the natural image dimensions take over and the
   * card stretches to whatever the source happened to be. */
  width: 100%;
  aspect-ratio: var(--ue-preview-aspect-ratio);
  object-fit: cover;
  background: var(--ue-preview-background);
  border: 1px solid var(--ue-color-border);
  border-radius: calc(var(--ue-border-radius) / 1.5);
}

/* Video card placeholder when no preview_image_url ships */
:where(.ue-library, .ue-microsite) .ue-asset__preview--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  color: var(--ue-color-muted);
}

/* Video card media (mirrors the classic video card): a provider thumbnail
   with a centered play badge that opens the video, or an inline player for
   direct video files. */
:where(.ue-library, .ue-microsite) .ue-asset__video {
  position: relative;
  display: block;
}
:where(.ue-library, .ue-microsite) .ue-asset__video--linked {
  cursor: pointer;
}
:where(.ue-library, .ue-microsite) .ue-asset__video-player {
  display: block;
  width: 100%;
  aspect-ratio: var(--ue-preview-aspect-ratio);
  background: #000;
  border-radius: calc(var(--ue-border-radius) / 1.5);
}
:where(.ue-library, .ue-microsite) .ue-asset__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 2.25rem;
  line-height: 1;
  color: #fff;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}
:where(.ue-library, .ue-microsite) .ue-asset__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}
:where(.ue-library, .ue-microsite) .ue-asset__tag {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  border: 1px solid var(--ue-color-border);
  border-radius: 999px;
  font-size: 0.75rem;
  color: var(--ue-color-muted);
}

/* Chart card bars. */
:where(.ue-library, .ue-microsite) .ue-asset__chart {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
:where(.ue-library, .ue-microsite) .ue-asset__bar {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0.25rem 0.5rem;
}

/* Label + value share the top row; the bar sits full-width on the row below. */
:where(.ue-library, .ue-microsite) .ue-asset__bar-label {
  grid-row: 1;
  grid-column: 1;
}
:where(.ue-library, .ue-microsite) .ue-asset__bar-value {
  grid-row: 1;
  grid-column: 2;
  text-align: right;
}
:where(.ue-library, .ue-microsite) .ue-asset__bar-fill {
  grid-row: 2;
  grid-column: 1 / -1;
  display: block;
  height: 0.75rem;
  width: var(--ue-bar-pct, 0%);
  background: var(--ue-color-link);
  border-radius: 0.25rem;
}

/* The data table is a screen-reader fallback for the bar chart above —
   keep it in the DOM but visually hidden so the card doesn't duplicate
   the same numbers twice. */
:where(.ue-library, .ue-microsite) .ue-asset__chart-table {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Status states ------------------------------------------------- */
:where(.ue-library, .ue-microsite) .ue-status {
  padding: 2rem 0;
  text-align: center;
}
:where(.ue-library, .ue-microsite) .ue-status--loading {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 6rem;
}
:where(.ue-library, .ue-microsite) .ue-status--error {
  color: var(--ue-color-error);
}
:where(.ue-library, .ue-microsite) .ue-status--error .ue-status__message {
  margin: 0;
  font-weight: 600;
}
:where(.ue-library, .ue-microsite) .ue-status--error .ue-status__detail {
  margin: 0.35rem 0 0;
  font-size: 0.85em;
  opacity: 0.75;
}

/* --- Pagination ---------------------------------------------------- */
:where(.ue-library, .ue-microsite) .ue-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
}
:where(.ue-library, .ue-microsite) .ue-pagination button {
  cursor: pointer;
}
:where(.ue-library, .ue-microsite) .ue-pagination button[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}
