/* Homepage composition. Product images are captures of the public dashboard. */
.hero__poster,
.company__painting {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.hero__poster { z-index: 0; }
.hero__video { opacity: 0; transition: opacity 400ms ease; }
.hero__video.is-playing { opacity: 1; }
/* The loop's seam. script.js paints the clip's last frame here, restarts the
   video underneath, then lifts this away. No z-index: at the hero's own level
   a later sibling already paints over the video, and the veil's z-index: 1
   keeps it tinting both alike. */
.hero__tail {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  opacity: 0;
  transition: opacity 900ms linear;
}
/* Held with the transition suppressed, so the frame lands whole and only the
   release is animated. */
.hero__tail.is-holding { opacity: 1; transition: none; }
.hero__eyebrow { margin-bottom: 20px; color: rgba(255, 255, 255, .8); }
.hero h1 { max-width: 720px; }
.hero__lede { max-width: 620px; }
.hero .phbadge { margin-bottom: 20px; }
.company.world-section { background-image: none; }
.company__painting { z-index: -2; }
.company__inner > .eyebrow { margin-top: 20px; }
.company__inner > img { margin-inline: auto; }

.product-story,
.why-honestly,
.pipeline {
  padding-block: var(--section-y);
  color: var(--ink);
  background: var(--paper);
}
.section-heading > .eyebrow { margin-bottom: 16px; }
.product-story__intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-10);
  align-items: start;
}
.product-story__intro > div > .eyebrow { margin: 0 0 16px; color: var(--cobalt); font-size: 12px; }
.product-story__intro > .product-story__explanation > p:first-child { margin-top: 0; }
.product-story__intro > .product-story__explanation > p + p { margin-top: 20px; }
.why-honestly__reasons {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-7) var(--space-6);
  margin-top: var(--space-8);
  align-items: start;
}
.why-reason { min-width: 0; }
.why-reason__plate {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  margin-bottom: var(--space-4);
  object-fit: contain;
  object-position: center top;
}
.why-reason h3 {
  margin: 0 0 var(--space-2);
  font: 400 var(--text-lg)/1.25 var(--serif);
  letter-spacing: var(--tracking-display);
}
.why-reason p {
  margin: 0;
  color: var(--ink-soft);
  font-size: var(--text-base);
  line-height: 1.5;
}
.pipeline > .section-shell > .section-heading { margin-bottom: var(--space-9); }

/* Staggered entrances. The parent holds still and its children rise in turn,
   so nothing moves twice; only transform and opacity change. */
.reveal-ready [data-reveal="stagger"] { opacity: 1; transform: none; transition: none; }
.reveal-ready [data-reveal="stagger"] > * { opacity: 0; transform: translateY(14px); transition: opacity 650ms ease, transform 650ms cubic-bezier(0.2, 0.76, 0.24, 1); }
.reveal-ready [data-reveal="stagger"].is-revealed > * { opacity: 1; transform: none; }
.reveal-ready [data-reveal="stagger"] > :nth-child(2) { transition-delay: 70ms; }
.reveal-ready [data-reveal="stagger"] > :nth-child(3) { transition-delay: 140ms; }
.reveal-ready [data-reveal="stagger"] > :nth-child(4) { transition-delay: 210ms; }
.reveal-ready [data-reveal="stagger"] > :nth-child(5) { transition-delay: 280ms; }

@media (max-width: 980px) {
  .product-story__intro { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .why-honestly__reasons { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-7); }
  .hero__video { display: none; }
}
@media (max-width: 720px) {
  .why-honestly__reasons { grid-template-columns: minmax(0, 1fr); margin-top: var(--space-7); gap: var(--space-7); }
  .dashboard-capture { margin-top: 32px; }
  .pipeline > .section-shell > .section-heading { margin-bottom: 32px; }
}
@media (prefers-reduced-motion: reduce) {
  .hero__video { transition: none; }
  .reveal-ready [data-reveal="stagger"] > * { opacity: 1; transform: none; transition: none; }
}

/* Standalone Opinions cards. Markup is generated by the dashboard's own
   signal-card renderer; these are the scoped card atoms from posts.css. */
.post-wall.product-ui { background: transparent; border: 0; box-shadow: none; overflow: clip; max-width: 1440px; }
.post-wall.product-ui::after { border: 0; }
.post-wall {
  --text-primary: var(--ink);
  --text-secondary: var(--ink-soft);
  --tiktok: #aae0f0;
  --cp-fs-sm: 12px;
  --cp-fs-base: 12px;
  --cp-line-relaxed: 1.55;
  margin: 48px auto 0;
  max-width: 1440px;
  font-family: var(--sans);
}
/* The dashboard's dark accent is one colour doing two jobs: a fill, and 11-13px
   type on the card surface, where it measures 3.0-3.8:1. The page already splits
   that role — a light --cobalt to read as type, a darker --cobalt-fill to carry a
   white label — so the embedded cards borrow the split rather than ship the one
   number that cannot do both. Scoped to .evidence-ui, the wrapper the dashboard's
   own renderers mount inside, so it reaches the cards and the drawer together. */
html.dark .evidence-ui {
  --accent: var(--cobalt);
}

@media (hover: hover) and (pointer: fine) {
  html.dark .evidence-ui .aff-program-pill:hover {
    background: var(--cobalt-fill);
  }
}

/* The label total sits on a 16% grey chip that darkens with the card behind it,
   so secondary type lands at 3.5:1 on the deeper platform grounds. */
html.dark .evidence-ui .lo-total-label-count {
  color: var(--text-primary);
}

.post-wall__viewport { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; padding: 20px; }
.post-wall__column { display: flex; flex-direction: column; align-self: start; min-width: 0; }
.post-wall__set { display: flex; flex-direction: column; gap: 20px; padding-bottom: 20px; flex-shrink: 0; }
.post-wall.is-enhanced { height: 760px; overflow: clip; position: relative; }
.post-wall:focus-visible { outline: 2px solid var(--cobalt); outline-offset: -2px; }
.post-wall.is-enhanced::before,
.post-wall.is-enhanced::after { content: ''; position: absolute; inset: 0 0 auto; height: 60px; z-index: 3; pointer-events: none; background: linear-gradient(var(--paper), transparent); }
.post-wall.is-enhanced::after { inset: auto 0 0; height: 90px; transform: rotate(180deg); }
.post-wall.is-looped .post-wall__column { animation: post-flow var(--post-flow-duration, 65s) linear infinite; animation-play-state: paused; }
.post-wall.is-looped .post-wall__column:nth-child(even) { animation-direction: reverse; }
.post-wall.is-moving .post-wall__column { animation-play-state: running; }
.post-wall.is-static .post-wall__column { animation: none; }
.post-wall.is-static [data-wall-repeat] { display: none; }
@keyframes post-flow { from { transform: translateY(0); } to { transform: translateY(-50%); } }
.text-link { display: inline-flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 44px; color: var(--cobalt); font-size: var(--text-sm); }
.text-link:hover { text-decoration: underline; text-underline-offset: 4px; }

/* One original video and its native signal-drawer quote cards. */
.product-precision { background: var(--paper); padding-block: var(--section-y); }
.precision-intro { max-width: var(--measure-prose); }
/* Scroll-pinned stepping, shared by the pipeline and the use-case lines. The
   wrapper is stage + space: the stage holds still under the nav for the whole
   range while .pin__space supplies the scroll distance the controller maps
   onto the steps. Pinning is gated here, not in the controller — it reads the
   stage's computed position and stands down wherever this query does not
   apply. Below it, or on a viewport too short to hold the section, the
   sections read as ordinary blocks. */
.pin { background: var(--paper); }
.pin__space { display: none; }
@media (min-width: 981px) and (min-height: 700px) and (prefers-reduced-motion: no-preference) {
  .pin__stage { position: sticky; top: calc(var(--nav-h) + var(--safe-t)); min-height: calc(100svh - var(--nav-h) - var(--safe-t)); display: flex; flex-direction: column; }
  /* Centres the section in the held viewport; its own band padding would
     otherwise double up with the room the stage already gives it. */
  .pin__stage > * { margin-block: auto; padding-block: 0; }
  .pin__space { display: block; height: calc(var(--pin-steps) * var(--pin-step)); }
}

/* Use cases: seven lines, one dark. The active line follows the pin; without
   it the first line stays dark, so the list reads the same with no JavaScript.
   The muted-until-active treatment only holds where the pin can actually run
   (same gate as .pin__stage above) — everywhere else data-active never moves
   past its no-JS fallback, so all lines default to full ink instead of
   sitting under the 3:1 large-text contrast floor. */
.use-cases { padding-block: var(--section-y); color: var(--ink); text-align: center; }
.use-cases > .eyebrow { margin: 0 0 var(--space-7); color: var(--cobalt); }
.use-cases__list { margin: 0; font: 400 32px/1.2 var(--serif); letter-spacing: var(--tracking-display); }
.use-cases .line { display: block; color: var(--ink); text-decoration: none; transition: color .3s ease; }
.use-cases > .button { margin-top: var(--space-9); }
@media (min-width: 981px) and (min-height: 700px) and (prefers-reduced-motion: no-preference) {
  .use-cases .line { color: rgba(17, 21, 22, .38); }
  /* rgba(17,21,22,.38) is light-mode ink at this rule's own alpha; on dark paper
     that reads as near-black on near-black, so dark keeps the alpha and swaps in
     dark-mode ink instead. Held off the line the pin has raised: an html.dark
     prefix out-specifies a bare [data-active], so without the guard the resting
     grey would swallow the one line the section exists to point at. */
  html.dark .use-cases .line:not([data-active]) { color: rgba(232, 234, 244, .38); }
  .use-cases .line[data-active] { color: var(--ink); }
}
@media (max-width: 430px) {
  .use-cases__list { font-size: min(28px, 7.8vw); }
}
@media (prefers-reduced-motion: reduce) {
  .use-cases .line { transition: none; }
}

/* The stage list, its description and the plate are one radio group: the
   checked stage is the only state, so this reads the same with or without
   JavaScript and keyboard support is the browser's own. */
.pipeline__explorer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: var(--space-10);
  align-items: start;
}
.pipeline__list { grid-area: 1 / 1; display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); margin: 0; padding: 0; border: 0; }
.pipeline__descs { grid-area: 2 / 1; display: grid; align-items: start; padding-top: var(--space-7); width: calc(100% + var(--space-8)); }
.pipeline__plates { grid-area: 1 / 2 / 3 / 3; position: relative; align-self: stretch; min-height: 420px; margin-top: calc((44px - 1.2 * var(--text-2xl)) / 2); }

.pipeline__stage { position: relative; min-height: 44px; display: flex; align-items: center; color: var(--ink); opacity: .38; font: 400 var(--text-2xl)/1.2 var(--serif); letter-spacing: var(--tracking-display); cursor: pointer; transition: opacity .3s ease; }
.pipeline__stage:hover { opacity: .7; }
:checked + .pipeline__stage { opacity: 1; }
/* One square, parked in the page gutter so it can never reflow a stage. It
   closes up with the gutter rather than crossing the viewport edge. */
:checked + .pipeline__stage::before { content: ""; position: absolute; left: calc(-1 * min(22px, var(--gutter-safe) - 8px)); width: 7px; height: 7px; background: currentColor; }
:focus-visible + .pipeline__stage { outline: 2px solid var(--cobalt); outline-offset: 4px; }

/* Descriptions and plates each share one grid cell, so the cell is as tall as
   the longest of them and switching stages never moves the layout. */
.pipeline__descs > p { grid-area: 1 / 1; }
.pipeline__plates > img { position: absolute; inset: 0; }
.pipeline__descs > p,
.pipeline__plates > img { opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility .3s ease; }
.pipeline__descs > p { color: var(--ink-soft); font-size: var(--text-md); line-height: 1.55; }
.pipeline__plates > img { width: 100%; height: 100%; object-fit: contain; object-position: right center; }

/* Each plate is one ink colour living only in its alpha channel (image-system.md);
   the pale shapes are holes, not paint, so a plain background swap leaves them navy
   on near-black. Inverted, a plate reads as its own cyanotype negative in the
   brand's blue. */
html.dark .why-reason__plate,
html.dark .pipeline__plates > img {
  filter: invert(1) hue-rotate(180deg);
}

.pipeline__explorer:has(#pipeline-define:checked) .pipeline__descs > :nth-child(1),
.pipeline__explorer:has(#pipeline-define:checked) .pipeline__plates > :nth-child(1) { opacity: 1; visibility: visible; }
.pipeline__explorer:has(#pipeline-discovery:checked) .pipeline__descs > :nth-child(2),
.pipeline__explorer:has(#pipeline-discovery:checked) .pipeline__plates > :nth-child(2) { opacity: 1; visibility: visible; }
.pipeline__explorer:has(#pipeline-filtering:checked) .pipeline__descs > :nth-child(3),
.pipeline__explorer:has(#pipeline-filtering:checked) .pipeline__plates > :nth-child(3) { opacity: 1; visibility: visible; }
.pipeline__explorer:has(#pipeline-enrichment:checked) .pipeline__descs > :nth-child(4),
.pipeline__explorer:has(#pipeline-enrichment:checked) .pipeline__plates > :nth-child(4) { opacity: 1; visibility: visible; }
.pipeline__explorer:has(#pipeline-extraction:checked) .pipeline__descs > :nth-child(5),
.pipeline__explorer:has(#pipeline-extraction:checked) .pipeline__plates > :nth-child(5) { opacity: 1; visibility: visible; }
.pipeline__explorer:has(#pipeline-verification:checked) .pipeline__descs > :nth-child(6),
.pipeline__explorer:has(#pipeline-verification:checked) .pipeline__plates > :nth-child(6) { opacity: 1; visibility: visible; }
.pipeline__explorer:has(#pipeline-insights:checked) .pipeline__descs > :nth-child(7),
.pipeline__explorer:has(#pipeline-insights:checked) .pipeline__plates > :nth-child(7) { opacity: 1; visibility: visible; }

/* Tucked beside the list: the stage names keep their own column, the plate
   takes the rest and stretches (align-self) to the list's row height — the
   plates div has no intrinsic height of its own since its images are
   absolutely positioned, so it always inherits exactly what the list needs.
   The description reads across the full width, below the pair. */
@media (max-width: 980px) {
  .pipeline__explorer { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); column-gap: var(--space-5); row-gap: var(--space-6); }
  .pipeline__list { grid-area: 1 / 1; gap: 16px; }
  .pipeline__plates { grid-area: 1 / 2; align-self: stretch; min-height: 0; height: auto; margin-top: 0; }
  .pipeline__descs { grid-row: 2; grid-column: 1 / -1; align-items: start; width: auto; max-width: none; padding-top: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .pipeline__stage,
  .pipeline__descs > p,
  .pipeline__plates > img { transition: none; }
}

@media (max-width: 1180px) {
  .post-wall__viewport { gap: 16px; padding-inline: 16px; }
  .post-wall__set { gap: 16px; padding-bottom: 16px; }
}
@media (max-width: 980px) {
  .post-wall.is-enhanced { height: 610px; }
  .post-wall__viewport { grid-template-columns: repeat(3, minmax(0,1fr)); }
}
@media (max-width: 720px) {
  .post-wall { margin-top: 32px; }
  .post-wall__viewport { grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px; padding: 12px; }
  .post-wall__set { gap: 12px; padding-bottom: 12px; }

  .post-wall.is-enhanced { height: 540px; }
}
@media (max-width: 430px) {
  .post-wall.is-enhanced { height: 460px; }
}
@media (prefers-reduced-motion: reduce) {
  .post-wall.is-enhanced .post-wall__column { animation: none; }
}

/* Logos only, single row that never wraps — an ellipsis tile closes it out.
   Gap/logo size shrink at narrow widths instead of wrapping to a second row;
   overflow-x is a hidden-scrollbar safety net if 320px ever gets tighter
   than the shrink alone can absorb. */
.hero__coverage { display: block; max-width: 600px; margin-top: 40px; }
.hero__coverage-label { display: block; margin-bottom: 14px; font-size: 12px; }
.hero__platforms { display: flex; align-items: center; flex-wrap: nowrap; gap: 16px; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -ms-overflow-style: none; }
.hero__platforms::-webkit-scrollbar { display: none; }
.hero__platforms li { flex: 0 0 auto; height: 20px; padding: 0; border: 0; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
.hero__platforms img, .hero__platforms svg { display: block; width: 20px; height: 20px; object-fit: contain; }
.hero__platforms img[src$="/x.svg"], .hero__platforms img[src$="/threads.svg"] { filter: brightness(0) invert(1); }
.hero__platforms img[src$="/amazon.svg"] { filter: brightness(0) invert(1); }
@media (max-width: 430px) {
  .hero__platforms { gap: 5px; }
  .hero__platforms li { height: 14px; }
  .hero__platforms img, .hero__platforms svg { width: 14px; height: 14px; }
}

/* Website placement around the unchanged native source and quote atoms. */
.evidence-source { display: block; min-width: 0; color: inherit; text-decoration: none; outline-offset: 5px; }
.evidence-source:focus-visible { outline: 2px solid var(--accent); }
.evidence-ui .cp-card { width: 100%; }
.evidence-ui .cd-quote-text { font-family: 'DM Sans', system-ui, sans-serif; }
/* The wall shows the shipped card, so it only owns placement: full column
   width, no hover lift, and no pointer affordance the site cannot honour. */
.post-wall .cp-card-detail > .label-briefing { padding: 0; }
.post-wall .cp-card { cursor: default; }
.post-wall .cp-card:hover { transform: none; }
.post-wall.is-static { height: auto; }
.post-wall.is-static::before, .post-wall.is-static::after { display: none; }
.post-wall.is-static .post-wall__column { transform: none; }
.post-wall.is-static [data-wall-repeat] { display: none; }
/* A source stays beside a single evidence trail. Native quote atoms remain intact. */
.source-extraction.product-ui { --source-nav-offset: calc(var(--nav-h) + var(--safe-t)); margin-top: 64px; border: 0; background: transparent; box-shadow: none; overflow: visible; }
.source-extraction.product-ui::after { display: none; }
.source-extraction.is-enhanced { overflow-anchor: none; }
.source-extraction__panel { display: grid; grid-template-columns: minmax(0, 380px) minmax(0, 1fr); gap: 80px; align-items: start; }
.source-dock { min-width: 0; position: sticky; top: calc(var(--source-nav-offset) + 24px); }
/* The card is the one control in the dock: it opens the drawer. */
.timeline-video { display: block; color: inherit; text-decoration: none; outline-offset: 4px; }
.timeline-video:focus-visible { outline: 2px solid var(--accent); }
.timeline-video .cp-card { width: 100%; margin: 0; cursor: pointer; box-shadow: none; }
.timeline-video .cp-yt-thumb { aspect-ratio: 16 / 9; height: auto; }
.timeline-video .cp-yt-thumb > img { width: 100%; height: 100%; object-fit: contain; }
.timeline-video .cp-yt-play { opacity: 1; }
.timeline-video .cp-yt-title { display: block; -webkit-line-clamp: unset; font-size: 17px; line-height: 1.5; }
.timeline-video .cp-yt-handle { font-size: 12px; }
.timeline-video .cp-stat-item { font-size: 12px; }
.source-extraction__quotes { min-width: 0; }
/* Leave enough reading room after the final quote for its source to stay in
   view. This is normal page scroll, with no pinned container or scroll trap. */
.source-extraction.is-enhanced .source-extraction__quotes { padding-bottom: max(0px, calc(var(--source-dock-height, 240px) - 240px)); }
.opinion-timeline { list-style: none; position: relative; display: grid; gap: 32px; margin: 0; padding: 0 0 0 28px; }
.opinion-timeline::before { content: ""; position: absolute; top: 22px; bottom: 16px; left: 0; width: 1px; background: var(--line); }
.opinion-moment { position: relative; min-width: 0; scroll-margin-top: calc(var(--source-nav-offset) + 24px); }
.opinion-moment::before { content: ""; position: absolute; top: 22px; left: -28px; width: 20px; height: 1px; background: var(--line); }
.opinion-moment__node { position: absolute; top: 18px; left: -32px; width: 9px; height: 9px; border: 1px solid var(--border-default); border-radius: 50%; background: var(--paper); }
.opinion-moment.is-reached > .opinion-moment__node { background: var(--accent); border-color: var(--accent); }
.opinion-moment.is-current > .opinion-moment__node::after { content: ""; position: absolute; inset: -5px; border: 1px solid var(--accent-border); border-radius: 50%; }
.opinion-moment.is-current::before { background: var(--accent); }
.opinion-moment__time { display: inline-flex; align-items: center; gap: 8px; min-width: 64px; min-height: 44px; margin-bottom: 8px; color: var(--ink-soft); font: 400 13px/1 var(--sans); font-variant-numeric: tabular-nums; text-decoration: none; }
.opinion-moment__time svg { width: 14px; height: 14px; }
.opinion-moment.is-current > .opinion-moment__time { color: var(--accent); }
.source-extraction__quotes .cd-hl-unit { margin: 0; }
.source-extraction__quotes .cd-quote-text { font-size: 17px; line-height: 1.65; }
.source-extraction__quotes .cd-hl-chip { font-size: 12px; min-height: 25px; }
.source-extraction__quotes .evidence-attribution { padding-top: 14px; }
/* The list ends mid-thought: the last comment fades out because the drawer
   holds the rest of the conversation. */
.opinion-timeline > .opinion-moment:last-child { -webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent); mask-image: linear-gradient(to bottom, #000 45%, transparent); }
@media (prefers-reduced-motion: no-preference) {
  .source-extraction.is-enhanced .opinion-moment.is-entered > .cd-highlight { animation: evidence-appear 420ms both; }
  @keyframes evidence-appear { from { opacity: .5; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
}
/* The panel inside is the shipped dashboard drawer. dashboard/posts.css owns
   its position, size, border, shadow, tinted glass and slide — copied verbatim
   into evidence-native.css — so the dialog is only a transparent full-viewport
   host that gives the floating panel somewhere to live in the top layer. */
.evidence-dialog { position: fixed; inset: 0; width: auto; height: auto; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: transparent; overflow: visible; }
.evidence-dialog::backdrop { background: rgba(18,22,34,.22); }
/* The dashboard caps the drawer at calc(100vw - 268px) to clear its 220px app
   sidebar. There is no sidebar here, so the panel holds its native 460px with
   page showing past it, and below 492px narrows to the same 16px inset it
   already keeps on the other three edges — which is what keeps the close
   control on screen down to 320px. */
.evidence-dialog .card-drawer { min-width: 0; max-width: calc(100vw - 32px); overscroll-behavior: contain; }
/* Icon-only drawer controls keep the dashboard's 32px face; only the hit area
   grows to the 44px touch minimum. */
.evidence-dialog .cd-thread-close, .evidence-dialog .cd-thread-nav-badge { position: relative; }
.evidence-dialog .cd-thread-close::after, .evidence-dialog .cd-thread-nav-badge::after { content: ""; position: absolute; top: 50%; left: 50%; width: 44px; height: 44px; min-width: 100%; min-height: 100%; transform: translate(-50%, -50%); }
@media (prefers-reduced-motion: reduce) { .evidence-dialog .card-drawer { transition: none; } }
.evidence-play { display: block; position: relative; width: 100%; height: 100%; min-height: 180px; color: white; background: #171923; }
.evidence-play > img { display: block; width: 100%; height: 100%; object-fit: cover; }
.evidence-play--full > img { object-fit: contain; }
.evidence-play > span { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 8px; background: rgba(15,20,30,.24); color: white; font: 400 16px/1.4 var(--sans); }
.evidence-play svg { width: 32px; height: 32px; }
/* Who said a comment, above its quote on the page's timeline only. */
.evidence-attribution { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 10px 12px 0; color: var(--text-secondary); font: 400 12px/1.4 var(--sans); overflow-wrap: anywhere; }
.evidence-attribution .badge { padding: 2px 6px; font-size: 10px; }
.evidence-loading { padding: 24px; }
.evidence-loading button { min-width: 44px; min-height: 44px; margin-bottom: 24px; }
.evidence-loading p { font-size: 16px; line-height: 1.6; }
@media (max-width: 1180px) {
  .source-extraction__panel { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: 48px; }
}
@media (max-width: 980px) {
  .source-extraction__panel { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .source-dock { position: static; width: min(100%, 540px); margin-inline: auto; }
  .source-extraction.is-enhanced .source-extraction__quotes { padding-bottom: 0; }
  .post-wall__viewport { grid-template-columns: repeat(2, minmax(0,1fr)); max-width: 800px; margin: auto; }
}
@media (max-width: 720px) {
  .source-extraction.product-ui { margin-top: 40px; }
  .source-extraction__panel { gap: 24px; }
  .timeline-video .cp-yt-title { font-size: 15px; }
  .opinion-timeline { padding-left: 20px; gap: 24px; }
  .opinion-moment::before { left: -20px; width: 12px; }
  .opinion-moment__node { left: -24px; }
  .source-extraction__quotes .cd-quote-text { font-size: 15px; }
  .source-extraction__quotes .cd-hl-chip { font-size: 11px; }
  .post-wall__viewport { grid-template-columns: 1fr; max-width: 420px; margin: auto; padding-inline: 24px; }
  .post-wall.is-enhanced:not(.is-static) { height: 620px; }
  .post-wall.is-static .post-wall__column { display: contents; }
}

