/* ==========================================================================
   Callix hero + logo strip — Figma 878:4932 / 878:5008, 1:1 at 1920
   --------------------------------------------------------------------------
   Loaded after tokens.css. Every number is a measurement off the Figma frames
   named above. Offsets are relative to the 1280 column (a 1360 container with
   a 40px gutter); Figma's column starts at x=351, so x_here = x_figma − 351.

   Pass 8 replaces pass 4 (dark ground, centred lockup) entirely: the Figma hero
   is LIGHT, two-column, left-aligned. The header keeps its default light
   treatment — no overrides here; its restyle to the 72px Figma nav is the next
   section.

   Deferred to the effects pass by decision (2026-09-15): the gradient-art
   recipe on the panel (kept as a flat #ddee5a box at exact geometry) and the
   hero sticker (878:4987).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Hero section — 878:4932 (922 tall incl. 72 nav → 850 body)

   The two-column layout below is placed against the 1280 content column: the
   visual is absolutely positioned at left 721 and is 580 wide, so its right
   edge lands at 1301. That column only exists once the 1360 container stops
   growing, i.e. from a 1360 viewport — below it the visual hung off the right
   of the screen and the whole page scrolled sideways (fixed 2026-09-18). So
   the visual is anchored to the column's right edge now, so it holds its 1920
   position and moves inward as the column narrows. Two columns from 1280 (553
   copy + 580 visual still fit); below that the stacked layout tablets had.
   -------------------------------------------------------------------------- */
.cx-hero {
  position: relative;
  display: block;
  padding: 0 40px;                 /* the standing 40px gutter */
  background: var(--cx-page);
  color: var(--cx-ink);
}
@media (min-width: 1280px) {
  /* The hero's vertical breathing room is one number, derived, not three hardcoded ones.
     It used to be min-height 1020 (850 × 1.2, request 2026-09-15) with the copy at 342 and
     the visual at 150 — a WIDTH query deciding a HEIGHT question, so a 14" laptop (778px
     under the nav) clipped 33px off the card and 81px off the panel (fixed 2026-09-21).

     --cx-hero-pad is the space above the 661px lockup. 0.4178 is Figma's own top:bottom
     split of the slack (150 : 209), so the lockup keeps its weighting at every height;
     192px is the copy's offset from the visual (342 − 150), which is the lockup itself and
     never moves. At a viewport of 1092 or more every value below resolves to exactly the
     1020 / 342 / 150 it was, so nothing changes on a large display. */
  .cx-hero {
    --cx-hero-h: min(1020px, calc(100svh - 72px));
    --cx-hero-pad: max(40px, calc((var(--cx-hero-h) - 661px) * 0.4178));
    /* 709 = the panel's extent (52 top + 657): it hangs 48px below the card, so it and not
       the card is what the section has to contain once the pad bottoms out at 40. */
    min-height: max(var(--cx-hero-h), calc(var(--cx-hero-pad) + 709px));
  }
}

/* left column — Figma tops 329 / 580 / 682 from the frame; minus the 72 nav
   → 257 / 508 / 610 from the section top; gaps therefore 38 / 38 */
.cx-hero__copy {
  width: 553px;
  max-width: 100%;
  padding-top: 96px;
}
@media (min-width: 1280px) {
  .cx-hero__copy { padding-top: calc(var(--cx-hero-pad) + 192px); }  /* 192 = 342 − 150: the copy's offset from the visual, the lockup */
}
.cx-hero__h1   { margin: 0; color: var(--cx-ink); }
.cx-hero__lead { margin: 38px 0 0; width: 447px; max-width: 100%; color: var(--cx-ink); }
.cx-hero__cta  { margin-top: 38px; }

/* right column — a 580×661 stage: panel behind at (1148,189), card in front at (1032,137) */
.cx-hero__visual {
  position: relative;
  width: 580px;
  max-width: 100%;
  height: 661px;
  margin: 48px 0 64px;
}
@media (min-width: 1280px) {
  .cx-hero__visual {
    position: absolute;
    top: var(--cx-hero-pad);       /* was 150px: (137 − 72) + 85, which is what it still resolves to at 1092+ */
    right: 59px;                   /* 1360 − (40 + 681 + 580): the same box at 1360 and above, and
                                      it moves in with the column instead of off the screen below it */
    margin: 0;
  }
}
.cx-hero__panel {                  /* 878:4947 — flat stand-in for the gradient art */
  position: absolute;
  left: 116px;                     /* 1148 − 1032 */
  top: 52px;                       /* 189 − 137 */
  width: 463px;
  height: 657px;
  border-radius: var(--cx-r-2xl);
  background: #ddee5a;
  overflow: clip;
}
@media (max-width: 1279px) {
  .cx-hero__panel { display: none; }
}

/* --------------------------------------------------------------------------
   2. Product card — 878:4967 · 514×661 · r-32 · p-16 · drop-shadow 0 0 1px
   -------------------------------------------------------------------------- */
.cx-card {
  position: absolute;
  left: 0; top: 0;
  width: 514px;
  max-width: 100%;
  height: 661px;
  padding: 16px;
  border-radius: var(--cx-r-2xl);
  background: var(--cx-surface);
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.25));
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 8px;
  color: var(--cx-ink);
}
.cx-card__top {                    /* 878:4968 — flex-1, justify-end, py-[var(--6,24px)] */
  flex: 1 0 0;
  min-height: 1px;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 24px 0;
}
/* --------------------------------------------------------------------------
   2b. Chat transcript — 996:19666 "End", the animated board. It supersedes the
   878:4969 setup-issues list that used to fill this card.

   The four blocks (user bubble, Thinking…, answer, chart) are ALWAYS in the
   layout; the animation only reveals them. That is what Figma's own timeline
   does — every keyframe is opacity + a small translate, never a size change —
   and it means the card never reflows while it plays: opacity and transform
   only, so the whole loop stays on the compositor.

   Motion values are the designer's, read off the 2.5s timeline on 996:19666:
   ease-out-expo (0.16, 1, 0.3, 1) for every entrance, per-element rises of
   16 / 8 / 12 / 24px, and the shimmer's 1 → 0.4 → 1 on (0.4, 0, 0.2, 1).
   chat.js owns the ordering; everything below owns the look.
   -------------------------------------------------------------------------- */
/* 996:19667 — flex-1, justify-end, py-24. It clips, because a transcript is a
   scroller: a new block rises in from under the bottom edge rather than fading
   into a slot that was already holding its space. Vertically only — the chart's
   stroke is drawn OUTSIDE its 482px box, so clipping on x shaved it off. */
.cx-chat__log { overflow-x: visible; overflow-y: clip; }
.cx-chat__stack {                  /* the thing that actually moves when the log grows */
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 24px; width: 100%;
}

.cx-chat__row { display: flex; width: 100%; }
.cx-chat__row.me { align-items: center; justify-content: flex-end; }   /* 996:19668 */
.cx-chat__row.ai { align-items: center; gap: 12px; }                   /* 996:19671 */

.cx-chat__bubble {                 /* 996:19669 — #f2f2f1, r-8, p-8 (no Figma variable) */
  display: flex; align-items: center; justify-content: center;
  padding: 8px; border-radius: var(--cx-r-lg); background: #f2f2f1;
}
.cx-chat__mark {                   /* 996:19672 — 20×20 mark, py-2, top-aligned in the row */
  display: flex; align-self: stretch; align-items: flex-start;
  flex: 0 0 20px; padding: 2px 0;
}
/* Body/Regular is 14/20 (size/sm · leading/2). The widths are Figma's and they
   are what set the line breaks: the bubble wraps to two lines at 176, the answer
   at 368. `pretty` would rebalance them, so these opt out of it. */
.cx-chat__t {
  margin: 0; width: 176px;
  font-family: var(--cx-sans); font-weight: 400; font-size: 14px; line-height: 20px;
  letter-spacing: 0; color: var(--cx-ink-2); text-wrap: wrap;
}
.cx-chat__t.ai { width: 368px; }

/* 990:17022 → 990:17203: "Thinking…" is not a message, it is the answer before
   it arrives. Both live in one slot under one mark, and the slot grows from a
   line to two as the answer takes over. */
.cx-chat__swap { position: relative; width: 368px; height: 20px; }
.cx-chat__swap > .cx-chat__t { position: absolute; left: 0; top: 0; }
.cx-chat__answer { opacity: 0; }

/* --------------------------------------------------------------------------
   2c. "Calls this month" card — 996:19675 · 482 × 185.467 · r-16
   The sub-pixel paddings are Figma's: the card is a 0.61529 scale of a 784-wide
   product card, so every inset carries that factor. They are kept as measured.
   -------------------------------------------------------------------------- */
.cx-chart {
  margin: 0; width: 100%; height: 185.467px;
  display: flex; flex-direction: column; align-items: flex-start;
  border-radius: 16px; background: var(--cx-surface); overflow: clip;
  /* the stroke is OUTSIDE on 996:19675 (the composer's, 996:19831, is INSIDE), so it
     must not inset the slots: Slot 3 is 164.833 wide, not 162.833. A ring, not a border. */
  box-shadow: 0 0 0 1px var(--cx-border);
}
.cx-chart__head {                  /* 996:19676 — Slot 1: pt-12.311, px-14.773 */
  width: 100%; height: 32.008px; box-sizing: border-box;
  padding: 12.311px 14.773px 0;
  display: flex; align-items: center;
  font-family: var(--cx-sans); font-weight: 400; font-size: 14px; line-height: 20px;
  color: var(--cx-ink-2); white-space: nowrap;
}
.cx-chart__body {                  /* 996:19681 — Slot 2: flex-1, gap-24.621, px/pb-14.773 */
  flex: 1 0 0; min-height: 1px; width: 100%; box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  gap: 24.621px; padding: 0 14.773px 14.773px; overflow: clip;
}
.cx-chart__stat {                  /* 996:19682 — Slot 3: flex-1, gap-9.849, justify-end, pb-6 */
  flex: 1 0 0; min-width: 1px; align-self: stretch;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-end;
  gap: 9.849px; padding-bottom: 6px; white-space: nowrap;
}
.cx-chart__num {                   /* 996:19683 — Inter Display Medium 24/16.004 */
  margin: 0; font-family: var(--cx-display); font-weight: 500;
  font-size: 24px; line-height: 16.004px; letter-spacing: -0.2893px; color: #000;
  text-box-trim: trim-both; text-box-edge: cap alphabetic;
  font-feature-settings: "ordn" 1, "salt" 1, "cv01" 1, "cv02" 1, "cv03" 1, "cv04" 1,
                         "cv08" 1, "cv09" 1, "dlig" 1, "lnum" 1, "tnum" 1;
}
.cx-chart__delta {                 /* 996:19684 — Badge: 10/12.926, gap-2.462 */
  margin: 0; display: flex; align-items: center; gap: 2.462px;
  font-family: var(--cx-sans); font-weight: 400;
  font-size: 10px; line-height: 12.926px; letter-spacing: -0.0554px;
  text-box-trim: trim-both; text-box-edge: cap alphabetic;
  font-feature-settings: "ordn" 1, "salt" 1, "case" 1, "cpsp" 1, "cv09" 1, "cv04" 1,
                         "cv03" 1, "cv02" 1, "cv01" 1, "ss01" 1, "dlig" 1, "lnum" 1, "tnum" 1;
}
.cx-chart__delta .up { color: #15803d; }                 /* green/700, a raw hex in Figma */
.cx-chart__delta .vs { color: var(--cx-ink-3); } /* Text/Tertiary */

.cx-chart__bars {                  /* 996:19690 — 263 wide, pt-9.849 */
  flex: 0 0 263px; width: 263px; align-self: stretch;
  box-sizing: border-box; padding-top: 9.849px;
  display: flex; align-items: center;
}
/* Figma's 996:19690 plots twelve months; the question asks about last month, so this
   plots its thirty days instead. Everything else in the card is the designer's — box,
   slots, insets, type, the 263px chart area, the three bar colours. Only the three
   numbers the column count drives are ours: the gutter (4px → 1.6px), the bar's minimum
   width (9.849 → none) and the corner (2 → 1), all held at Figma's proportions — a bar
   was 63.5% of its pitch there and is 63.5% of it here. `--pad` per column is the same
   mechanism 996:19760 used to sit one column short. */
.cx-chart__mark { flex: 1 0 0; min-width: 1px; align-self: stretch; display: flex; flex-direction: column; justify-content: flex-end; }
.cx-chart__base { flex: 1 0 0; min-height: 1px; width: 100%; display: flex; flex-direction: column; padding-top: var(--pad, 0); }
.cx-chart__bc {                    /* Bar Container — pt-9.849 is Figma's, px is ours */
  flex: 1 0 0; min-height: 1px; width: 100%; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  padding: 9.849px 1.6px 0; overflow: clip;
}
.cx-chart__slot {                  /* Bar Slot */
  flex: 1 0 0; min-height: 1px; width: 100%;
  display: flex; flex-direction: column; justify-content: flex-end;
  border-radius: 1px; overflow: clip;
}
.cx-chart__bar { flex: 1 0 0; min-height: 1px; width: 100%; }
.cx-chart__bar.o { background: #f97318; }   /* the three outcome colours are raw hexes in Figma */
.cx-chart__bar.g { background: #22c55f; }
.cx-chart__bar.b { background: #3d82f7; }
.cx-chart__day {                   /* Day Text Marker Container — h-19.697, p-4.924 */
  height: 19.697px; width: 100%; box-sizing: border-box;
  display: flex; align-items: center; justify-content: center; padding: 4.924px 0;
  font-family: var(--cx-sans); font-weight: 500; font-size: 8px; line-height: 9.849px;
  color: var(--cx-ink-3); white-space: nowrap;
}

/* "Ask Callix AI anything" input block — 878:4981 · r-24 · Border/Default */
.cx-ask {
  width: 100%;
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-r-xl);
  background: var(--cx-surface);
  overflow: clip;
  display: flex; flex-direction: column;
}
.cx-ask__label {                   /* 878:4982 — h-54, pl-20 pr-8 py-8 */
  height: 54px;
  padding: 8px 8px 8px 20px;
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
  color: var(--cx-ink-2);
  white-space: nowrap;
}
.cx-ask__actions {                 /* 878:4984 — h-48, pl-10 pr-8 py-8, space-between */
  height: 48px;
  padding: 8px 8px 8px 10px;
  display: flex; align-items: center; justify-content: space-between;
  width: 100%;
}
.cx-ask__btn {                     /* 32×32, px-12 py-3 */
  width: 32px; height: 32px;
  padding: 3px 12px;
  display: inline-flex; align-items: center; justify-content: center;
  overflow: clip; border: 0; cursor: pointer;
}
.cx-ask__btn.tertiary { background: var(--cx-btn-ui-tert); border-radius: var(--cx-r-lg); }
.cx-ask__btn.primary  { background: var(--cx-btn-ui);      border-radius: var(--cx-r-full); }
.cx-icon { display: block; flex: 0 0 auto; }
/* base.css caps every image at `max-width: 100%`, and a 32px button with px-12 leaves an
   8px content box — which was shrinking both 16px glyphs to 8. The icon is 16, always. */
.cx-ask__btn .cx-icon { width: 16px; height: 16px; max-width: none; }

/* --------------------------------------------------------------------------
   2d. The composer's text — 990:17406 "Start" shows the placeholder,
   987:16399 "Typing" shows the question in its place, and 991:17662 shows the
   field empty for the beat right after send. Placeholder and typed value share
   one grid cell so swapping them moves nothing.
   -------------------------------------------------------------------------- */
.cx-ask__value { display: grid; }
.cx-ask__value > * { grid-area: 1 / 1; }
.cx-ask__placeholder, .cx-ask__typed { font-size: 14px; line-height: 20px; }  /* Body/Regular = size/sm · leading/2 */
.cx-ask__typed { display: inline-flex; align-items: center; }
.cx-ask__caret {                   /* motion only — the static boards have no caret */
  width: 1px; height: 17px; margin-left: 1px;
  background: currentColor; opacity: 0;
}

/* --------------------------------------------------------------------------
   2e. The loop. A chat builds from the bottom: the question lands above the
   composer, "Thinking…" lands under it and pushes it up, the answer REPLACES
   "Thinking…" in place, and the chart lands under the answer and pushes the
   whole transcript up again. So blocks are genuinely out of the flow until
   their cue — chat.js adds `is-live` to put one in, and the stack is FLIPped
   back to where it was and released, which turns each arrival into one
   composited slide of the whole column.

   The curves and durations are the designer's, off the 2.5s timeline on
   996:19666: ease-out-expo (0.16, 1, 0.3, 1) everywhere, pops of 0.96 on the
   bubble and 0.97 on the chart, 450·500 / 400 / 500·800 ms, and the chart's
   800ms spring (Figma's own linear() list, with the expo curve left standing
   in front of it for browsers without linear()). The shimmer is 1 → 0.4 → 1
   over 1600ms on (0.4, 0, 0.2, 1).
   -------------------------------------------------------------------------- */
.cx-chat { --cx-expo: cubic-bezier(0.16, 1, 0.3, 1); }

.cx-chat [data-cx-step] { display: none; opacity: 0; }
.cx-chat [data-cx-step].is-live { display: flex; }
.cx-chat [data-cx-step].is-in   { opacity: 1; transform: none; }

.cx-chat [data-cx-step="prompt"] {
  transform: scale(0.96);
  transition: opacity 450ms var(--cx-expo), transform 500ms var(--cx-expo);
}
.cx-chat [data-cx-step="reply"],
.cx-chat [data-cx-step="followup"] {
  transition: opacity 400ms var(--cx-expo);
}
.cx-chat [data-cx-step="chart"] {
  transform: scale(0.97);
  transition: opacity 500ms var(--cx-expo), transform 800ms cubic-bezier(0.16, 1, 0.3, 1);
  transition: opacity 500ms var(--cx-expo), transform 800ms linear(0, 0.0154, 0.0556, 0.1126, 0.1802, 0.2536, 0.3291, 0.4038, 0.4759, 0.5439, 0.6068, 0.6644, 0.7162, 0.7623, 0.803, 0.8385, 0.8691, 0.8953, 0.9175, 0.9361, 0.9515, 0.9643, 0.9746, 0.9829, 0.9894, 0.9945, 0.9984, 1.0013, 1.0033, 1.0047, 1.0056, 1.0061, 1.0063, 1.0062, 1.006, 1.0057, 1.0052, 1.0048, 1.0043, 1.0038, 1.0034, 1.003, 1.0026, 1.0022, 1.0019, 1.0016, 1.0013, 1.0011, 1.0009, 1.0007, 1.0005);
}
/* chat.js drives this one directly — it sets the duration and curve per move. */
.cx-chat__stack { will-change: transform; }

/* The bars draw themselves in as the card settles — thirty columns rising off the
   baseline, left to right, 18ms apart. Figma keyframed the card but not its contents,
   so the stagger is ours; it borrows the card's own expo curve so it reads as one move.
   scaleY on the slot takes all three segments with it, and .cx-chart__bc already
   clips, so nothing escapes the column. */
.cx-chart__slot {
  transform: scaleY(0); transform-origin: 50% 100%;
  /* the duration lives here, not on the .is-in rule: that rule is a class more
     specific, and its `transition` shorthand would reset the delay below to 0 */
  transition: transform 420ms var(--cx-expo);
  transition-delay: calc(120ms + var(--i, 0) * 18ms);   /* --i is the column index, set in the markup */
}
.cx-chat [data-cx-step="chart"].is-in .cx-chart__slot { transform: scaleY(1); }

/* the answer taking over from "Thinking…": the slot grows a line, the two texts
   cross-fade, and the growth is what pushes the question up. */
.cx-chat__swap { transition: height 500ms var(--cx-expo); }
.cx-chat__swap > .cx-chat__t { transition: opacity 320ms linear; }
.cx-chat.is-answered .cx-chat__swap   { height: 40px; }
.cx-chat.is-answered .cx-chat__thinking { opacity: 0; }
.cx-chat.is-answered .cx-chat__answer   { opacity: 1; }

/* leaving: one flat fade, no movement, then chat.js takes the blocks back out
   of the flow so the next pass starts from an empty log. */
.cx-chat[data-cx-phase="reset"] [data-cx-step] {
  opacity: 0; transform: none;
  transition: opacity 400ms linear;
}

/* 996:20059 — the shimmer holds for as long as Callix is thinking, and stops
   the moment there is something to read. */
@keyframes cx-chat-shimmer { 0% { opacity: 1; } 50% { opacity: 0.4; } 100% { opacity: 1; } }
.cx-chat[data-cx-phase="thinking"] .cx-chat__thinking {
  animation: cx-chat-shimmer 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

/* typing — the caret is the one thing here with no Figma node behind it */
@keyframes cx-chat-caret { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
.cx-chat[data-cx-phase="typing"] .cx-ask__caret { animation: cx-chat-caret 1s step-end infinite; }
.cx-ask__placeholder { opacity: 0.5; transition: opacity 240ms linear; }   /* it is a placeholder, not a message */
.cx-chat[data-cx-phase="typing"] .cx-ask__placeholder,
.cx-chat[data-cx-phase="send"]   .cx-ask__placeholder { opacity: 0; }

/* the send press — 990:16841 is a still, so the press itself is ours: down fast,
   back on the same expo curve every entrance uses */
.cx-ask__btn.primary { transition: transform 260ms var(--cx-expo); }
.cx-ask__btn.primary.is-pressed { transform: scale(0.9); transition-duration: 90ms; }

@media (prefers-reduced-motion: reduce) {
  /* the finished exchange, held still. chat.js does not start. */
  .cx-chat [data-cx-step] { display: flex; opacity: 1; transform: none; transition: none; }
  .cx-chat__swap { height: 40px; }
  .cx-chart__slot { transform: none; transition: none; }
  .cx-chat__thinking { opacity: 0; }
  .cx-chat__answer { opacity: 1; }
  .cx-chat__stack { will-change: auto; }
  .cx-chat__thinking, .cx-ask__caret, .cx-ask__btn.primary { animation: none; transition: none; }
  .cx-ask__typed { display: none; }
}

/* --------------------------------------------------------------------------
   3. Logo strip — 878:5008 and 878:5222
   Figma 878:5223: ONE bordered row 1224 × 82 (rgba(38,38,38,.11)); cells sit
   inside the line, 80 tall: eyebrow cell (262 in Figma → flex-1 here) with the
   text 155 wide at (24,19), then six 160 × 80 cells p-24, border-right on all
   but the last. Section py-24 → 130 tall.
   -------------------------------------------------------------------------- */
.cx-strip { padding: 24px 40px; }
.cx-strip__row {
  display: flex; align-items: stretch;
  box-sizing: border-box; height: 82px;
  border: 1px solid var(--cx-line-strong);
}
.cx-strip__eyebrow {
  flex: 1 1 0; min-width: 0; margin: 0;
  padding: 24px; border-right: 1px solid var(--cx-line-strong);
  display: flex; align-items: center;
  color: var(--cx-ink);
}
.cx-strip__eyebrow > span { display: block; width: 155px; }
/* the logos live in a track so the phone can scroll them as one strip (mobile.css). On every other
   width the track is a pass-through — the cells stay flex items of .cx-strip__row, laid out exactly as
   they were — and the duplicate half that makes the loop seamless is not rendered at all. */
.cx-strip__track { display: contents; }
.cx-strip__cell.is-dup { display: none; }

.cx-strip__cell {
  /* 0 1 rather than 0 0: five of these want 800px, which the 1280 column has and a 1024 one has not.
     They shrink instead of pushing the page sideways (fixed 2026-09-18); the logos inside are all
     under 110px, so a squeezed cell still holds its mark. */
  flex: 0 1 160px; width: 160px; min-width: 0; height: 80px; box-sizing: border-box;
  padding: 24px; border-right: 1px solid var(--cx-line-strong);
  display: flex; align-items: center; justify-content: center;
}
.cx-strip__cell:nth-child(5) { border-right: 0; }
.cx-strip__cell > img {
  display: block; max-width: none; object-fit: contain;
  /* Every mark in the cloud is one solid #262626 in its own file; the strength lives
     here so all five match and there is a single number to move. Figma paints the light
     strip's logos at #262626 a=0.40 (878:5435) — it is only inconsistent there because
     Whop was dropped in at pure black. The dark strip's 0.5 is in pages.css and wins
     on specificity. */
  opacity: 0.4;
}
/* exact Figma boxes */
.cx-strip__cell:nth-child(1) img { width: 79.254px; height: 17.378px; } /* Whop — 941:14683 */
.cx-strip__cell:nth-child(2) img { width: 93px;    height: 24px; }     /* Oneleet */
.cx-strip__cell:nth-child(3) img { width: 106.584px; height: 22px; }  /* Commas — 877:4191 */
.cx-strip__cell:nth-child(4) img { width: 23.31px; height: 17.99px; }  /* mark */
.cx-strip__cell:nth-child(5) img { width: 88px;    height: 24px; }     /* EasyAudit */

/* Below 1280 the in-a-row strip used to wrap, which left the rows with no rule between
   them — the cloud read as two loose sets. It is a ticker there
   now instead (mobile.css), the same one the phone has, so there is nothing to wrap. */
