/*
 * The people row and the Clubs row of the Stream (8 October 2026). Markup: src/web/connect-row.ts. Motion hooks: connect.js.
 * docs/people-and-clubs-rows-20261008.md says what each lane is; this sheet only paints it.
 *
 * The owner's mockup, rendered live: no card, no box, no border, no panel. The page's own painted ground shows through. A hand-written
 * header with a small glowing dot, a muted line under it, a quiet "See all"; then clusters of three huge round portraits in a loose
 * staggered triangle (upper left, upper right a little higher, lower centre), each a natural photo in a smooth gradient ring with a soft aura that spills
 * past its edge, the warm sky tint inside the circle, faint dashed orbit lines between them with two glossy orbs riding them, and under
 * each portrait its name, a tiny reason with the real faces behind it, and a slim outlined "+ Follow". The next cluster's first portrait
 * is cut by the edge of the screen: that is the invitation to swipe. Plenty of empty space round all of it.
 *
 * Everything that moves moves with transform, opacity or stroke-dashoffset only, runs only while the row is on screen (connect.js sets
 * .is-live), and is off under reduced motion, Save-Data and Motion Off. No inline style (CSP): positions are class rules. The ink is
 * --pk-ink and the quiet --pk-muted, so every look and the light look (Matinee) keep their contrast.
 */
.pk-feed-connect { list-style: none; }
/* The old row's wrapper padding and rule (home.css) are gone for these rows: the space around a row is the feed's own gap between two posts, plus the few pixels the header needs. */
.pk-home .pk-feed-connect:has(> .pk-connect) { padding: 0; border-bottom: 0; }
.pk-connect {
  --conn-run: paused;
  --conn-violet: #7b4de0; --conn-indigo: #3d34c8; --conn-coral: #ff7a59; --conn-lav: #cdb8ff; --conn-orb1: #e6d8ff; --conn-orb2: #a98cf0; --conn-orb3: #6c4fc4; --conn-warm: 255, 130, 90; --conn-tone1: rgba(255, 140, 90, .55); --conn-tone2: rgba(110, 56, 200, .5);
  position: relative; isolation: isolate; margin: 0; padding: 8px 0 0; color: var(--pk-ink, #f5f2f1);
  /* The constellation's orbit arms are square boxes that turn about their centre: their painted dot always sits on the ellipse, but the turning box's
     corners reach about 45 px past the screen at 360 px and widened the whole document (a phone could scroll sideways). Clip, never hidden: the row
     is not a scroll container (so nothing sticky or fixed changes), the strip's own scroller is untouched, and the vertical axis stays visible for the
     rings and bob that spill above and below. Guarded by test/web/phone-width.test.mjs. */
  overflow-x: clip;
}
.pk-connect.is-live { --conn-head: running; }
/* Only what is on screen moves: the people and Club marks of a cluster run while that cluster is in view (connect.js sets .is-vis), the other looks while the row is. */
.pk-connect.is-live .pk-connect-cluster.is-vis, .pk-connect--orbit.is-live, .pk-connect--strip.is-live { --conn-run: running; }
/* The Clubs row is the people row's sibling in amber and plum, so the two are told apart at a glance. */
.pk-connect--clubs { --conn-violet: #f0a43a; --conn-indigo: #b2306f; --conn-coral: #ff6a4d; --conn-lav: #ffd9a0; --conn-orb1: #fff0cf; --conn-orb2: #f0a43a; --conn-orb3: #b2306f; --conn-warm: 255, 176, 80; --conn-tone1: rgba(255, 176, 70, .55); --conn-tone2: rgba(178, 48, 111, .5); }
@media (max-width: 759px) { .pk-connect { margin-inline: -16px; } }
.pk-connect-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---------- the head: hand-lettered title with a small glowing dot, a muted line, a quiet See all ---------- */
.pk-connect-head { position: relative; z-index: 3; display: flex; align-items: flex-start; gap: 12px; padding-inline: 16px; }
.pk-connect-titles { min-width: 0; flex: 1 1 auto; }
.pk-connect-title { margin: 0; display: flex; align-items: flex-start; gap: 7px; font-weight: 400; font-style: normal; letter-spacing: .005em; line-height: .95;
  font-family: "Caveat", "Bradley Hand", "Segoe Script", "Snell Roundhand", "Apple Chancery", "Brush Script MT", cursive;
  font-size: clamp(27px, 8.2vw, 44px); color: var(--pk-ink, #f5f2f1); text-wrap: balance; }
.pk-connect-title > span { display: inline-block; }
.pk-connect-glow { flex: none; width: 9px; height: 9px; margin-top: .34em; border-radius: 50%; background: var(--conn-coral);
  box-shadow: 0 0 12px 3px color-mix(in srgb, var(--conn-coral) 70%, transparent); }
.pk-connect-sub { margin: 8px 0 0; color: var(--pk-muted, #b6b3b5); font-size: 14px; line-height: 1.3; }
.pk-connect-all { flex: none; display: inline-flex; align-items: center; gap: 1px; min-height: 44px; margin-top: 4px; padding-inline: 4px; margin-inline-end: -4px; white-space: nowrap;
  color: color-mix(in srgb, var(--conn-coral) 88%, var(--pk-ink, #f5f2f1)); font-size: 15px; font-weight: 500; text-decoration: none; }
.pk-connect-all svg { width: 16px; height: 16px; }
@media (hover: hover) { .pk-connect-all:hover { color: var(--pk-ink, #f5f2f1); } }
html[dir="rtl"] .pk-connect-all svg { transform: scaleX(-1); }
.pk-connect .pk-social-arrows { display: none; gap: 4px; }
.pk-connect .pk-social-arrows button { width: 32px; height: 32px; border: 0; border-radius: 50%; background: transparent; color: var(--pk-muted, #b6b3b5); display: grid; place-items: center; cursor: pointer; }
.pk-connect .pk-social-arrows button[disabled] { opacity: .3; cursor: default; }
.pk-connect .pk-social-arrows svg { width: 18px; height: 18px; }
@media (min-width: 760px) and (hover: hover) and (pointer: fine) { .pk-connect .pk-social-arrows { display: inline-flex; } }

/* ---------- the track: a swipe, scroll-snapped on whole clusters, momentum scrolling, no scrollbar ---------- */
/* The strip scrolls sideways, so its box clips: the padding is the room the painted rings, their spill, the orbit lines and the bob need (top 34, bottom 28, left 28, right 22), and the negative top margin gives that room back to the layout, so the rhythm stays tight and nothing painted is ever cut. */
.pk-connect-track { list-style: none; margin: -22px 0 0; padding: 40px max(16px, env(safe-area-inset-right)) 28px max(16px, env(safe-area-inset-left)); display: flex; align-items: flex-start; gap: 0; position: relative;
  overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; scroll-padding-inline: 16px; scrollbar-width: none; }
.pk-connect-track::-webkit-scrollbar { display: none; }
/* No hard edge anywhere: the scroller's own edges are feathered by a mask (cheap, no blur). The side fades only where there is more to scroll (connect.js sets
   data-more-left / data-more-right on the row from the scroll position; the markup starts a strip with data-more-right), over 36 px, and the top and bottom fade
   over the padding the painted rings already have. @property lets the fade ease in and out. */
@property --pk-fl { syntax: "<length>"; inherits: true; initial-value: 14px; }
@property --pk-fr { syntax: "<length>"; inherits: true; initial-value: 14px; }
.pk-connect { --pk-ft: 0px; --pk-fb: 0px; }
.pk-connect { --pk-fl: 14px; --pk-fr: 14px; }
.pk-connect[data-more-left] { --pk-fl: 36px; }
.pk-connect[data-more-right] { --pk-fr: 36px; }
.pk-connect-track {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--pk-fl, 0px), #000 calc(100% - var(--pk-fr, 0px)), transparent 100%), linear-gradient(to bottom, transparent 0, #000 var(--pk-ft), #000 calc(100% - var(--pk-fb)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 var(--pk-fl, 0px), #000 calc(100% - var(--pk-fr, 0px)), transparent 100%), linear-gradient(to bottom, transparent 0, #000 var(--pk-ft), #000 calc(100% - var(--pk-fb)), transparent 100%);
  -webkit-mask-composite: source-in; mask-composite: intersect; }
.pk-connect--through { --pk-ft: 12px; --pk-fb: 8px; }
.pk-connect--strip { --pk-ft: 8px; --pk-fb: 8px; }
/* The constellation does not scroll: nothing clips it, so nothing is masked. */
.pk-connect--orbit .pk-connect-track { -webkit-mask-image: none; mask-image: none; }
@media (prefers-reduced-motion: no-preference) { .pk-connect { transition: --pk-fl 320ms ease, --pk-fr 320ms ease; } }
.pk-connect-track:focus-visible { outline-offset: -2px; border-radius: 12px; }
.pk-connect-track.is-nudging { scroll-snap-type: none; }

/* ---------- the faint painted orbit lines and the glossy orbs on them ---------- */
.pk-connect-art { position: absolute; inset: 0; pointer-events: none; z-index: 0; list-style: none; }
.pk-connect-orbit { position: absolute; width: var(--ow); height: var(--ow); left: var(--ox); top: calc(var(--oy) - var(--ow) / 2); transform: rotate(var(--rot)) scaleY(var(--sq)); opacity: .75; }
.pk-connect-orbit svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; fill: none; stroke-linecap: round; }
.pk-connect-stroke { stroke: var(--conn-lav); stroke-width: 1.5; stroke-opacity: .5; vector-effect: non-scaling-stroke; stroke-dasharray: 1; stroke-dashoffset: 0; }
.pk-connect-stroke-dash { stroke: var(--conn-coral); stroke-width: 1.3; stroke-opacity: .62; vector-effect: non-scaling-stroke; stroke-dasharray: 3 8; stroke-dashoffset: 0; }
.pk-connect-lead, .pk-connect-arm { position: absolute; inset: 0; display: block; }
.pk-connect-dot { position: absolute; left: 50%; top: 0; width: 13px; height: 13px; margin: -6px 0 0 -6px; border-radius: 50%; transform: scaleY(calc(1 / var(--sq)));
  background: radial-gradient(circle at 34% 28%, #fff 0, var(--conn-orb1) 22%, var(--conn-orb2) 62%, var(--conn-orb3) 100%); box-shadow: 0 0 14px 4px color-mix(in srgb, var(--conn-orb2) 50%, transparent); }
.pk-connect-orbit--b .pk-connect-dot { width: 9px; height: 9px; margin: -4px 0 0 -4px;
  background: radial-gradient(circle at 34% 28%, #fff 0, #ffd2bd 24%, #ff7a59 66%, #c93f2c 100%); box-shadow: 0 0 12px 3px rgba(255, 122, 89, .55); }
.pk-connect-fleck { position: absolute; width: 5px; height: 5px; border-radius: 50%; background: var(--conn-coral); opacity: .8; box-shadow: 0 0 9px 2px rgba(255, 122, 89, .5); }
.pk-connect-centre { display: none; }

/* ---------- a person: a natural photo in a gradient ring with an aura; a name, one light reason, a slim outlined Follow ---------- */
.pk-connect-people { list-style: none; margin: 0; padding: 0; }
.pk-connect-card { position: relative; margin: 0; padding: 0; }
/* The card is deliberately NOT a stacking context (no z-index, no transform, no opacity of its own): the aura is its child at z-index -1, so every portrait's photo
   and ring sit above every aura on the row, and a neighbour's glow never paints across a face. The entrance, the drift and the float therefore run on the card's
   children (the aura, the figure, the meta), in step. */
.pk-connect-figure { position: relative; width: var(--d, 140px); height: var(--d, 140px); }
.pk-connect-face { position: absolute; inset: 0; display: block; border-radius: 50%; text-decoration: none; color: inherit; }
/* ---------- AURA GLOW (9 October direction): a clean natural photo in a perfect circle, a crisp smooth gradient ring, a soft aura bleeding outward, a small glossy orb.
   Nothing touches the photo (no filter, no texture, no mask, no overlay): the character is the ring, the aura and the mist behind. Everything is CSS gradients
   (the page's CSP has no data: images); connect-row.ts `portraitLook` picks four classes per person: a palette (pk-h0..7), the turn of the ring (pk-r0..7),
   how strong the aura is (pk-i0..2) and where the orb floats (pk-o0..5). ---------- */
.pk-connect-card { --pk-c1: #ff9a3c; --pk-c2: #ff3d7f; --pk-c3: #8b3dff; --ra: 0deg; --ai: .8; --oa: 40deg; --pk-glow-mid: var(--pk-c1);
  --rw: clamp(2px, calc(var(--d, 110px) * .062), 8px); --ow: clamp(7px, calc(var(--d, 110px) * .1), 12px); }
.pk-connect-figure { border-radius: 50%; }
.pk-h0 { --pk-c1: #ff9a3c; --pk-c2: #ff3d7f; --pk-c3: #8b3dff; }           /* sunset */
.pk-h1 { --pk-c1: #ff7ad9; --pk-c2: #b04bff; --pk-c3: #5a6bff; }           /* orchid */
.pk-h2 { --pk-c1: #ffb347; --pk-c2: #ff5a3c; --pk-c3: #c2185b; }           /* ember */
.pk-h3 { --pk-c1: #36d1dc; --pk-c2: #6a5cff; --pk-c3: #c04bff; }           /* lagoon-violet */
.pk-h4 { --pk-c1: #ffcfa0; --pk-c2: #ff7aa8; --pk-c3: #a14bff; }           /* rose-gold */
.pk-h5 { --pk-c1: #ffc23c; --pk-c2: #ff6a3d; --pk-c3: #8b3dff; }           /* amber-violet */
.pk-h6 { --pk-c1: #ff5fa2; --pk-c2: #c13dff; --pk-c3: #4b5bff; }           /* magenta-dusk */
.pk-h7 { --pk-c1: #ff7a59; --pk-c2: #e04aa0; --pk-c3: #5b3fd0; }           /* coral-indigo */
.pk-r0 { --ra: 0deg; } .pk-r1 { --ra: 47deg; } .pk-r2 { --ra: 92deg; } .pk-r3 { --ra: 138deg; } .pk-r4 { --ra: 181deg; } .pk-r5 { --ra: 223deg; } .pk-r6 { --ra: 271deg; } .pk-r7 { --ra: 316deg; }
.pk-i0 { --ai: .62; } .pk-i1 { --ai: .8; } .pk-i2 { --ai: .98; }
.pk-o0 { --oa: 28deg; } .pk-o1 { --oa: 61deg; } .pk-o2 { --oa: 112deg; } .pk-o3 { --oa: 205deg; } .pk-o4 { --oa: 262deg; } .pk-o5 { --oa: 318deg; }

/* The aura is a SOFT MIST, not a glow disc: one element whose radial gradient falls off over more than half a portrait (many stops, a low alpha near the ring, nothing
   solid, so no shape edge), a radial mask that feathers it to nothing at its own box, and two large wisps (its pseudo-elements, a few percent of alpha) that drift and
   swell at 14 s and 19 s, so three overlapping hazes per portrait and nine across a cluster. Plain alpha (no blend mode, no filter), the ring's own palette, transform and
   opacity only, paused off screen. The ring itself stays crisp. */
.pk-connect-aura { position: absolute; z-index: -1; left: calc(50% - var(--d, 110px) * 1.1); top: calc(var(--d, 110px) * -.6); width: calc(var(--d, 110px) * 2.2); height: calc(var(--d, 110px) * 2.2); pointer-events: none; display: block; border-radius: 50%; opacity: var(--ai);
  -webkit-mask-image: radial-gradient(circle closest-side, #000 30%, transparent 100%); mask-image: radial-gradient(circle closest-side, #000 30%, transparent 100%);
  background: radial-gradient(circle closest-side, color-mix(in srgb, var(--pk-c2) 26%, transparent) 40%, color-mix(in srgb, var(--pk-c1) 24%, transparent) 46%, color-mix(in srgb, var(--pk-c1) 17%, transparent) 52%,
    color-mix(in srgb, var(--pk-c2) 11.5%, transparent) 59%, color-mix(in srgb, var(--pk-c2) 7.5%, transparent) 67%, color-mix(in srgb, var(--pk-c3) 4.5%, transparent) 76%,
    color-mix(in srgb, var(--pk-c3) 2.2%, transparent) 86%, color-mix(in srgb, var(--pk-c3) .8%, transparent) 94%, transparent 100%); }
.pk-connect-aura::before, .pk-connect-aura::after { content: ""; position: absolute; inset: -8%; pointer-events: none; }
.pk-connect-aura::before { background: radial-gradient(circle closest-side at 32% 66%, color-mix(in srgb, var(--pk-c1) 15%, transparent), transparent); }
.pk-connect-aura::after { background: radial-gradient(circle closest-side at 70% 32%, color-mix(in srgb, var(--pk-c3) 13%, transparent), transparent); }
/* The ring: a crisp, smooth conic gradient (coral to magenta to violet, turned a different way for each person), cut to a ring by a radial mask (a circular hole, so it is a true ring at every size). */
.pk-connect-ring { position: absolute; inset: 0; z-index: 3; pointer-events: none; display: block; border-radius: 50%;
  background: conic-gradient(from var(--ra), var(--pk-c1), var(--pk-c2) 36%, var(--pk-c3) 64%, var(--pk-c2) 86%, var(--pk-c1));
  -webkit-mask-image: radial-gradient(circle closest-side, transparent calc(100% - var(--rw) - .5px), #000 calc(100% - var(--rw) + .5px));
  mask-image: radial-gradient(circle closest-side, transparent calc(100% - var(--rw) - .5px), #000 calc(100% - var(--rw) + .5px)); }
/* The photo: a perfect circle, inside the ring, exactly as it was uploaded. */
.pk-connect-photo { position: absolute; inset: calc(var(--rw) - 1px); z-index: 2; display: block; border-radius: 50%; overflow: hidden; isolation: isolate; background: linear-gradient(150deg, #ff9a6b, #c04a7a 60%, #4a2c9a); }
.pk-connect-photo > .pk-avatar, .pk-connect-photo > .pk-house-face, .pk-connect-photo > img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; border-radius: 0; object-fit: cover; display: grid; place-items: center; font-size: 44px; }
/* A letter (no photo) is a painted gradient and a large initial. */
html body.pk-obsidian .pk-connect .pk-connect-photo > .pk-avatar--initial { background: linear-gradient(150deg, #ff9566, #c64d84 58%, #5a38b0); color: #fff; box-shadow: none; font-weight: 700; }
html[data-look="matinee"] .pk-connect .pk-connect-photo > .pk-avatar--initial { background: linear-gradient(150deg, #ff9566, #c64d84 58%, #5a38b0); color: #fff; box-shadow: none; font-weight: 700; }
html[data-look="matinee"] .pk-connect--clubs .pk-connect-photo > .pk-avatar--initial, html[data-look="matinee"] .pk-connect--clubs .pk-connect-photo--letter > .pk-house-face { background: linear-gradient(150deg, #ffbe5f, #d8564a 58%, #7a2d73); color: #fff; box-shadow: none; }
html body.pk-obsidian .pk-connect--clubs .pk-connect-photo--letter > .pk-house-face { background: linear-gradient(150deg, #ffbe5f, #d8564a 58%, #7a2d73); color: #fff; box-shadow: none; }
html body.pk-obsidian .pk-connect--clubs .pk-connect-photo > .pk-avatar--initial { background: linear-gradient(150deg, #ffbe5f, #d8564a 58%, #7a2d73); }
.pk-connect-photo--club > * { font-size: 40px; }
.pk-connect--clubs .pk-connect-photo { background: linear-gradient(150deg, #ffc15a, #d9553f 60%, #7a2a73); }
/* The orb: a small glossy sphere that floats off the ring at its own angle. */
.pk-connect-orb { position: absolute; left: 50%; top: 50%; z-index: 4; width: var(--ow); height: var(--ow); margin: calc(var(--ow) / -2) 0 0 calc(var(--ow) / -2); border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 34% 28%, #fff 0, color-mix(in srgb, var(--pk-c1) 55%, #fff) 22%, var(--pk-c1) 58%, var(--pk-c3) 100%);
  box-shadow: 0 0 calc(var(--ow) * 1.2) color-mix(in srgb, var(--pk-c1) 60%, transparent); transform: rotate(var(--oa)) translateY(calc(var(--d, 110px) * -.64)); }
/* Following or joining: the aura swells and the ring brightens (the page's follow glow, data-glow-host, rides the same palette through --pk-glow-mid). */
.pk-connect-card.is-done .pk-connect-aura { opacity: 1; scale: 1.12; transition: scale 600ms cubic-bezier(.34, 1.45, .64, 1), opacity 400ms ease; }
.pk-connect-meta { position: relative; min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 5px; justify-items: start; }
.pk-connect-meta > * { max-width: 100%; }
.pk-connect-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; color: var(--pk-ink, #f5f2f1); font-size: 17px; font-weight: 500; line-height: 1.16; text-decoration: none; overflow-wrap: break-word; word-break: normal; hyphens: manual; }
@media (hover: hover) { .pk-connect-name:hover { text-decoration: underline; text-underline-offset: 3px; } }
/* The reason is one short sentence: it may take two lines (never three) rather than be cut mid-word, and the faces sit beside its first line. */
.pk-connect-reason { margin: 0; display: flex; align-items: flex-start; gap: 6px; min-width: 0; color: var(--pk-muted, #b6b3b5); font-size: 13px; line-height: 1.25; }
.pk-connect-reason > span:last-child { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; min-width: 0; overflow-wrap: anywhere; }
.pk-connect-reason > .pk-connect-faces { margin-top: 1px; }
.pk-connect-faces { flex: none; display: inline-flex; }
.pk-connect-faces > img, .pk-connect-faces > .pk-avatar { width: 20px; height: 20px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 1.5px #1a1230; font-size: 11px; }
.pk-connect-faces > :not(:first-child) { margin-inline-start: -7px; }

/* Follow: slim and outlined, a thin coral-to-violet hairline with a transparent fill (the ring is a masked layer, so nothing fills the pill), and 44 px to touch.
   It springs when pressed. The Follow client sets its text; a + comes first while it is an invitation. */
.pk-connect-action { display: flex; align-items: center; flex-wrap: wrap; gap: 0; position: relative; }
.pk-connect-follow { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 13px; margin: 0; border: 0; background: none; color: var(--pk-ink, #f5f2f1);
  font: 500 13.5px/1 inherit; white-space: nowrap; text-decoration: none; cursor: pointer; transition: transform 240ms cubic-bezier(.34, 1.45, .64, 1); }
.pk-connect-follow::before { content: ""; position: absolute; inset: 7px 0; border-radius: 999px; padding: 1px; pointer-events: none;
  background: linear-gradient(100deg, var(--conn-coral), var(--conn-violet)); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
/* The press is the app's one recipe (redesign.css: a hair smaller, a shade deeper, 90 ms), which already covers every button. */
.pk-connect-follow[aria-pressed="false"]::after, a.pk-connect-follow::after { content: "+\00a0"; order: -1; opacity: .85; }
.pk-connect-follow[aria-busy="true"] { opacity: .65; }
.pk-connect-watch .pk-server-watch-on, .pk-connect-watch[aria-pressed="true"] .pk-server-watch-off { display: none; }
.pk-connect-watch[aria-pressed="true"] .pk-server-watch-on { display: inline; }
/* A followed person's pill carries a soft glow. */
.pk-connect-card.is-done .pk-connect-follow[aria-pressed="true"]::after { content: ""; position: absolute; inset: 7px 0; border-radius: 999px; pointer-events: none; background: color-mix(in srgb, var(--conn-violet) 24%, transparent); box-shadow: 0 0 16px 2px color-mix(in srgb, var(--conn-violet) 45%, transparent); }
/* The dismissal: a tiny quiet x at the portrait's upper right edge (as in the reference, but no disc, no fill). It looks small and is 44 x 44 px to touch. */
.pk-connect-x { position: absolute; z-index: 5; top: 1%; right: -3%; display: grid; place-items: center; width: 22px; height: 22px; margin: 0; padding: 0; border: 0; border-radius: 50%; background: transparent;
  color: var(--pk-muted, #b6b3b5); opacity: .7; cursor: pointer; }
.pk-connect-x::after { content: ""; position: absolute; inset: -11px; }
.pk-connect-x svg { width: 10px; height: 10px; }
.pk-connect-x:focus-visible { opacity: 1; color: var(--pk-ink, #f5f2f1); }
@media (hover: hover) { .pk-connect-x:hover { opacity: 1; color: var(--pk-ink, #f5f2f1); } }
.pk-connect .pk-social-action-status { flex-basis: 100%; margin: 2px 0 0; font-size: 12px; color: var(--pk-muted, #b6b3b5); }
.pk-connect .pk-social-action-status:empty { display: none; }
.pk-connect :is(a, button):focus-visible { outline: var(--pk-focus-width) solid var(--pk-focus); outline-offset: 3px; border-radius: 999px; }
.pk-connect-name:focus-visible { border-radius: 4px; }

/* ---------- the mockup's cluster: three huge portraits in a loose triangle, names offset with their own portrait ---------- */
.pk-connect--through { --W: min(calc(100vw - 72px), 440px); --d: calc(var(--W) * .348); }
.pk-connect-cluster { position: relative; flex: none; width: var(--W); margin: 0; scroll-snap-align: start; list-style: none; }
.pk-connect-cluster[hidden] { display: none; }
.pk-connect--through .pk-connect-track { gap: 26px; padding-bottom: 12px; }
/* The three share one grid cell and are nudged by their own margins, so the cluster is exactly as tall as the lowest pill: no fixed height anywhere. */
.pk-connect--through .pk-connect-people { display: grid; grid-template-columns: var(--W); grid-template-rows: auto; }
.pk-connect--through .pk-connect-card { grid-area: 1 / 1; width: var(--d); align-self: start; justify-self: start; }
.pk-connect--through .pk-connect-meta { margin-top: 6px; }
.pk-connect--through .pk-slot-0 { margin-top: calc(var(--d) * .19); }
.pk-connect--through .pk-slot-0 .pk-connect-meta { width: calc(var(--d) * .92); }
.pk-connect--through .pk-slot-1 { margin-left: calc(var(--W) - var(--d)); }
.pk-connect--through .pk-slot-1 .pk-connect-meta { margin-left: calc(var(--d) * .08); width: calc(var(--d) * .86); }
.pk-connect--through .pk-slot-2 { margin-left: calc(var(--W) * .327); margin-top: calc(var(--d) * .43); }
.pk-connect--through .pk-slot-2 .pk-connect-meta { width: calc(var(--d) * 1.02); }
.pk-connect--through .pk-connect-follow { font-size: 13px; padding-inline: 11px; margin-block: -7px; }
.pk-connect--through .pk-connect-action { flex-wrap: nowrap; }
.pk-connect--orbit .pk-connect-follow { margin-block: -7px; }
.pk-connect--through .pk-connect-art .pk-connect-orbit--a { --ow: var(--W); --ox: 0px; --oy: calc(var(--d) * .95); --rot: -8deg; --sq: .5; }
.pk-connect--through .pk-connect-art .pk-connect-orbit--b { --ow: calc(var(--W) * .7); --ox: calc(var(--W) * .3); --oy: calc(var(--d) * .72); --rot: 16deg; --sq: .55; }
.pk-connect--through .pk-connect-fleck--a { left: calc(var(--W) * .46); top: calc(var(--d) * .04); }
.pk-connect--through .pk-connect-fleck--b { left: calc(var(--W) * .95); top: calc(var(--d) * 1.3); width: 4px; height: 4px; }
/* The painted swipe hint beside the cut-off portrait. It leaves after the first horizontal move (connect.js). */
.pk-connect-hint { position: absolute; z-index: 2; inset-inline-end: -30px; top: 2px; width: 50px; height: 32px; pointer-events: none; color: var(--conn-coral); transition: opacity 400ms; }
.pk-connect-hint svg { width: 100%; height: 100%; overflow: visible; stroke: currentColor; stroke-width: 3; }
.pk-connect[data-swiped] .pk-connect-hint { opacity: 0; }

/* ---------- Your orbit look: the viewer is the quiet centre, a page of four drifts around them ---------- */
.pk-connect--orbit .pk-connect-track { display: grid; grid-template-columns: 1fr 1fr; justify-items: center; column-gap: 8px; row-gap: 0; overflow: visible; margin-top: 0; padding: 8px 16px 20px; scroll-snap-type: none; }
.pk-connect--orbit .pk-connect-card { width: min(150px, 100%); display: grid; justify-items: center; row-gap: 3px; text-align: center; }
.pk-connect--orbit .pk-connect-card { --d: 80px; }
/* The constellation is the compact, playful look: no subtitle, a one-line reason (the full words are its title), so two rows of two stay short. */
.pk-connect--orbit .pk-connect-sub { display: none; }
.pk-connect--orbit .pk-connect-reason > span:last-child { -webkit-line-clamp: 1; line-clamp: 1; }
.pk-connect--orbit .pk-connect-meta { position: relative; width: 100%; justify-items: center; row-gap: 3px; }
.pk-connect--orbit .pk-connect-reason, .pk-connect--orbit .pk-connect-action { justify-content: center; }
.pk-connect--orbit .pk-connect-name { padding-inline: 6px; text-align: center; font-size: 16px; }
/* The art is the first child, so the cards are the even (left) and odd (right) children. The right column rides 18 px lower (a translate: it adds no height; the track's bottom padding holds it). */
.pk-connect--orbit .pk-connect-card:nth-child(odd) { top: 18px; }
/* The orbit lines are sized to the people (the track's own box), never to a fixed number of pixels: two ellipses, the larger one no taller than the four portraits. */
.pk-connect--orbit .pk-connect-art .pk-connect-orbit--a { --ow: min(310px, 86%); --ox: calc(50% - min(310px, 86%) / 2); --oy: 50%; --rot: -7deg; --sq: .56; }
.pk-connect--orbit .pk-connect-art .pk-connect-orbit--b { --ow: min(210px, 60%); --ox: calc(50% - min(210px, 60%) / 2); --oy: 50%; --rot: 12deg; --sq: .66; }
.pk-connect--orbit .pk-connect-centre { display: grid; place-items: center; position: absolute; left: calc(50% - 23px); top: calc(50% - 23px); width: 46px; height: 46px; border-radius: 50%; opacity: .92; z-index: 2;
  box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--conn-violet) 55%, transparent), 0 0 22px 3px color-mix(in srgb, var(--conn-violet) 34%, transparent); overflow: hidden; }
.pk-connect-centre > .pk-avatar { width: 100%; height: 100%; font-size: 20px; }
.pk-connect-centre-glow { width: 14px; height: 14px; border-radius: 50%; background: var(--conn-coral); box-shadow: 0 0 22px 8px rgba(255, 122, 89, .5); }
.pk-connect-card[data-off] { display: none; }

/* ---------- the compact strip: one line, a small ring, the same hooks ---------- */
.pk-connect--strip { padding-block: 18px 12px; }
.pk-connect--strip .pk-connect-head { margin-bottom: 8px; }
.pk-connect--strip .pk-connect-title { font-size: clamp(30px, 8.5vw, 38px); }
.pk-connect--strip .pk-connect-sub { display: none; }
.pk-connect--strip .pk-connect-track { margin-top: 0; padding-block: 14px 16px; gap: 12px; align-items: stretch; }
.pk-connect--strip .pk-connect-card { flex: none; width: 262px; display: grid; grid-template-columns: 56px 1fr; align-items: center; column-gap: 12px; padding: 4px 4px 4px 0; }
.pk-connect--strip .pk-connect-card { --d: 52px; }
.pk-connect--strip .pk-connect-figure { width: 52px; height: 52px; }
.pk-connect--strip .pk-connect-aura { left: calc(0px - var(--d) * .6); top: calc(50% - var(--d) * 1.1); }
.pk-connect--strip .pk-connect-orb { display: none; }
.pk-connect--strip .pk-connect-photo > * { font-size: 17px; }
.pk-connect--strip .pk-connect-meta { grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 8px; }
.pk-connect--strip .pk-connect-name { grid-column: 1; font-size: 15px; padding-inline-end: 0; }
.pk-connect--strip .pk-connect-reason { grid-column: 1; font-size: 12px; }
.pk-connect--strip .pk-connect-reason > span:last-child { -webkit-line-clamp: 1; line-clamp: 1; }
.pk-connect--strip .pk-connect-action { grid-column: 2; grid-row: 1 / span 2; flex-wrap: nowrap; }
.pk-connect--strip .pk-connect-x { top: -9px; right: -12px; }
.pk-connect--strip .pk-connect-follow { min-height: 44px; padding: 0 10px; }
.pk-connect--strip .pk-social-action-status { display: none; }

/* ---------- More people: the loop. A quiet text button; it wraps round to the first. ---------- */
.pk-connect-more { position: absolute; z-index: 2; right: 10px; bottom: 34px; display: flex; align-items: center; gap: 5px; min-height: 44px; margin: 0; padding: 0 6px; border: 0; background: transparent;
  color: var(--pk-muted, #b6b3b5); font: 500 13px/1 inherit; cursor: pointer; }
.pk-connect-more svg { width: 16px; height: 16px; transition: transform 300ms cubic-bezier(.34, 1.45, .64, 1); }
@media (hover: hover) { .pk-connect-more:hover { color: var(--pk-ink, #f5f2f1); } }
@media (hover: hover) { .pk-connect-more:hover svg { transform: translateX(3px); } }
/* In the painted look, More is the last thing in the strip: swipe to the end and it is there; it takes you back round to the first. */
.pk-connect-endcap { flex: none; align-self: center; list-style: none; padding: 0 10px 0 6px; scroll-snap-align: end; }
.pk-connect--through .pk-connect-more { position: static; }
.pk-connect--through .pk-connect-name { font-size: 16px; }
.pk-connect--orbit .pk-connect-more { right: auto; left: 10px; bottom: -14px; }

/* ---------- desktop: the same painting, wider, with the next cluster peeking ---------- */
@media (min-width: 760px) {
  .pk-connect--through { --W: 400px; }
  .pk-connect-title { font-size: 52px; }
  /* Two clusters show at once on desktop: More sits in the head, beside See all and the arrows, so it never covers a person. */
  .pk-connect:not(.pk-connect--through) .pk-connect-more { top: 36px; bottom: auto; right: 196px; }
}

/* ---------- motion: finite, cheap, paused off screen; none under reduced motion, Save-Data or Motion Off ---------- */
/* connect.js sets data-ready only where motion is allowed, and .is-in on the first scroll into view. */
@media (prefers-reduced-motion: no-preference) {
  .pk-connect[data-ready]:not(.is-in) .pk-connect-card > *, .pk-connect[data-ready]:not(.is-in) .pk-connect-orbit { opacity: 0; }
  .pk-connect[data-ready]:not(.is-in) .pk-connect-title > span { clip-path: inset(-20% 100% -30% 0); }
  .pk-connect[data-ready]:not(.is-in) .pk-connect-sub { opacity: 0; }
  /* The first scroll into view: portraits drift in from their own direction on the bars' damped spring, strokes draw, the title writes. */
  .pk-connect[data-ready].is-in .pk-connect-card > * { animation: pk-conn-in 900ms var(--pk-ease-pop, cubic-bezier(.34, 1.45, .64, 1)) var(--ind, 0ms) both; }
  .pk-connect[data-ready].is-in .pk-slot-0, .pk-connect[data-ready].is-in .pk-connect-card:nth-child(3n + 2) { --fx: -26px; --fy: 18px; --ind: 80ms; }
  .pk-connect[data-ready].is-in .pk-slot-1, .pk-connect[data-ready].is-in .pk-connect-card:nth-child(3n) { --fx: 30px; --fy: 36px; --ind: 190ms; }
  .pk-connect[data-ready].is-in .pk-slot-2, .pk-connect[data-ready].is-in .pk-connect-card:nth-child(3n + 1) { --fx: 6px; --fy: 44px; --ind: 300ms; }
  .pk-connect[data-ready].is-in .pk-connect-title > span { animation: pk-conn-write 1200ms cubic-bezier(.5, 0, .2, 1) both; }
  .pk-connect[data-ready].is-in .pk-connect-sub { animation: pk-conn-fade 800ms ease-out 700ms both; --to: 1; }
  .pk-connect[data-ready].is-in .pk-connect-orbit { animation: pk-conn-fade 900ms ease-out 200ms both; --to: .75; }
  .pk-connect[data-ready].is-in .pk-connect-stroke { animation: pk-conn-draw 1800ms cubic-bezier(.5, 0, .2, 1) 150ms both; }
  /* Alive: the portraits bob and breathe on their own phases, the orbs travel their lines. */
  .pk-connect[data-ready].is-in .pk-connect-face { animation: pk-conn-float var(--dur, 7s) ease-in-out var(--delay, 0s) infinite; animation-play-state: var(--conn-run); }
  .pk-connect[data-ready] .pk-slot-0 { --dur: 6.4s; --delay: -1s; }
  .pk-connect[data-ready] .pk-slot-1 { --dur: 8.2s; --delay: -3.4s; }
  .pk-connect[data-ready] .pk-slot-2 { --dur: 7.3s; --delay: -5.2s; }
  /* The aura: two wisps of smoke drift and swell on their own phases (14 s and 19 s), the orb bobs, the section's mist breathes. Transform and opacity only, paused off screen. */
  .pk-connect[data-ready].is-in .pk-connect-aura::before { animation: pk-conn-smoke-a 14s ease-in-out infinite alternate; animation-play-state: var(--conn-run); }
  .pk-connect[data-ready].is-in .pk-connect-aura::after { animation: pk-conn-smoke-b 19s ease-in-out infinite alternate; animation-play-state: var(--conn-run); }
  .pk-connect[data-ready].is-in .pk-slot-1 .pk-connect-aura::before { animation-delay: -6s; }
  .pk-connect[data-ready].is-in .pk-slot-2 .pk-connect-aura::after { animation-delay: -9s; }
  .pk-connect[data-ready].is-in .pk-connect-orb { animation: pk-conn-orb 7s ease-in-out infinite alternate; animation-play-state: var(--conn-run); }
  /* Followed or joined: a slow breathing glow under the pill. */
  .pk-connect[data-ready] .pk-connect-card.is-done .pk-connect-follow[aria-pressed="true"]::after { animation: pk-conn-breathe 3.4s ease-in-out infinite; animation-play-state: var(--conn-run); }
  .pk-connect[data-ready].is-in .pk-connect-arm { animation: pk-conn-turn var(--arm, 34s) linear infinite; animation-play-state: var(--conn-run); }
  .pk-connect[data-ready] .pk-connect-orbit--b .pk-connect-arm { --arm: 46s; animation-direction: reverse; }
  .pk-connect[data-ready] .pk-connect-glow, .pk-connect[data-ready] .pk-connect-fleck { animation: pk-conn-pulse 3.6s ease-in-out infinite; animation-play-state: var(--conn-head, paused); }
  .pk-connect[data-ready] .pk-connect-fleck--b { animation-delay: -2s; animation-duration: 4.6s; }
  /* A person leaving floats away; a page change drifts the next in. */
  /* A little parallax with a pointer (connect.js sets --tilt-x and --tilt-y, -1 to 1). */
  .pk-connect[data-ready] .pk-connect-face { translate: calc(var(--tilt-x, 0) * 6px) calc(var(--tilt-y, 0) * 4px); transition: translate 360ms cubic-bezier(.2, .8, .2, 1); }

  /* The invitation to scroll sideways: as the row travels up the screen, each portrait drifts sideways at its own speed, the strokes shift
     along their dashes and the orbs advance along the lines. The row names the timeline (view-timeline); where it is not supported, connect.js
     sets --conn-p (0 to 1) as the row crosses the screen and the same motion follows it. translate / stroke-dashoffset / rotate only. */
  .pk-connect[data-ready] { --dx: 0px; --conn-p: .5; }
  .pk-connect[data-ready] :is(.pk-slot-0, .pk-slot-1, .pk-slot-2) > * { translate: calc((.5 - var(--conn-p)) * var(--dx) * 2) 0; }
  .pk-connect[data-ready] .pk-slot-0 { --dx: 12px; }
  .pk-connect[data-ready] .pk-slot-1 { --dx: 28px; }
  .pk-connect[data-ready] .pk-slot-2 { --dx: 20px; }
  .pk-connect[data-ready] .pk-connect-cluster ~ .pk-connect-cluster .pk-slot-0 { --dx: 120px; }
  .pk-connect[data-ready] .pk-connect-stroke-dash { stroke-dashoffset: calc(var(--conn-p) * -90); }
  .pk-connect[data-ready] .pk-connect-lead { transform: rotate(calc((var(--conn-p) - .5) * 120deg)); }
  @supports (animation-timeline: view()) {
    .pk-connect[data-ready] { view-timeline: --pk-conn block; }
    .pk-connect[data-ready] :is(.pk-slot-0, .pk-slot-1, .pk-slot-2) > * { translate: none; animation: pk-conn-drift linear both; animation-timeline: --pk-conn; animation-range: cover 0% cover 100%; }
    .pk-connect[data-ready].is-in :is(.pk-slot-0, .pk-slot-1, .pk-slot-2) > * {
      animation-name: pk-conn-in, pk-conn-drift; animation-duration: 900ms, auto; animation-timing-function: var(--pk-ease-pop, cubic-bezier(.34, 1.45, .64, 1)), linear;
      animation-fill-mode: both, both; animation-delay: var(--ind, 0ms), 0s; animation-timeline: auto, --pk-conn; animation-range: normal, cover 0% cover 100%; }
    .pk-connect[data-ready] .pk-connect-stroke-dash { stroke-dashoffset: 0; animation: pk-conn-dash linear both; animation-timeline: --pk-conn; animation-range: cover 0% cover 100%; }
    .pk-connect[data-ready] .pk-connect-lead { transform: none; animation: pk-conn-lead linear both; animation-timeline: --pk-conn; animation-range: cover 0% cover 100%; }
  }
  /* A person leaving floats away; a page change drifts the next in (placed last so it wins over the drift above). */
  .pk-connect[data-ready].is-in .pk-connect-card.is-leaving, .pk-connect[data-ready] .pk-connect-card.is-leaving.is-leaving { animation: pk-conn-leave 420ms cubic-bezier(.4, 0, .8, .6) both; animation-timeline: auto; pointer-events: none; }
  .pk-connect[data-ready] .pk-connect-card.is-entering { --fx: 18px; --fy: 22px; animation: pk-conn-in 720ms var(--pk-ease-pop, cubic-bezier(.34, 1.45, .64, 1)) both; }
}
@keyframes pk-conn-drift { from { translate: var(--dx) 0; } to { translate: calc(var(--dx) * -1) 0; } }
@keyframes pk-conn-dash { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -90; } }
@keyframes pk-conn-lead { from { transform: rotate(-60deg); } to { transform: rotate(60deg); } }
@keyframes pk-conn-in { from { opacity: 0; transform: translate(var(--fx, 0), var(--fy, 20px)) scale(.86); } to { opacity: 1; transform: none; } }
@keyframes pk-conn-leave { to { opacity: 0; transform: translate(14px, -46px) scale(.7) rotate(5deg); } }
@keyframes pk-conn-float { 0%, 100% { transform: translateY(0) scale(1) rotate(0deg); } 50% { transform: translateY(-7px) scale(1.02) rotate(.8deg); } }
@keyframes pk-conn-turn { to { transform: rotate(360deg); } }
@keyframes pk-conn-shimmer { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
@keyframes pk-conn-smoke-a { from { transform: translate(-3%, 2%) scale(.96); opacity: .7; } to { transform: translate(5%, -4%) scale(1.14); opacity: 1; } }
@keyframes pk-conn-smoke-b { from { transform: translate(4%, -3%) scale(1.08); opacity: .95; } to { transform: translate(-5%, 4%) scale(.92); opacity: .65; } }
@keyframes pk-conn-orb { from { translate: 0 0; } to { translate: 2px -5px; } }
@keyframes pk-conn-breathe { 0%, 100% { opacity: .45; transform: scale(.94); } 50% { opacity: 1; transform: scale(1.06); } }
@keyframes pk-conn-pulse { 0%, 100% { opacity: .55; transform: scale(.85); } 50% { opacity: 1; transform: scale(1.15); } }
@keyframes pk-conn-fade { from { opacity: 0; } to { opacity: var(--to, 1); } }
@keyframes pk-conn-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes pk-conn-write { from { clip-path: inset(-20% 100% -30% 0); } to { clip-path: inset(-20% -6% -30% -2%); } }
/* The joyful burst on a follow: a few pigment dots that settle (connect.js builds them with the Web Animations API). */
.pk-conn-spark { position: absolute; width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: var(--conn-coral); pointer-events: none; z-index: 3; }
.pk-conn-spark:nth-child(even) { background: var(--conn-lav); width: 5px; height: 5px; }

/* ---------- the light look, forced colours, Save-Data ---------- */
html[data-look="matinee"] .pk-connect { --conn-violet: #6a3fd1; --conn-indigo: #3a2fb0; --conn-coral: #e8553a; --conn-lav: #8d6fe0; }
html[data-look="matinee"] .pk-connect-glow, html[data-look="matinee"] .pk-connect-dot, html[data-look="matinee"] .pk-connect-fleck { box-shadow: none; }
html[data-look="matinee"] .pk-connect-photo { box-shadow: 0 6px 16px rgba(60, 40, 20, .18); }
/* The light look keeps the crisp rings and a still softer pastel haze. */
html[data-look="matinee"] .pk-connect-aura { opacity: calc(var(--ai) * .55); }
html[data-look="matinee"] .pk-connect-faces > img, html[data-look="matinee"] .pk-connect-faces > .pk-avatar { box-shadow: 0 0 0 1.5px #faf4e9; }
html[data-look="matinee"] .pk-connect-stroke { stroke-opacity: .55; }
html[data-save="1"] .pk-connect-art, html.pk-save-data .pk-connect-art { display: none; }
@media (forced-colors: active) {
  .pk-connect-track { -webkit-mask-image: none; mask-image: none; }
  .pk-connect-art, .pk-connect-aura, .pk-connect-orb, .pk-connect-hint { display: none; }
  .pk-connect-ring { background: CanvasText; }
  .pk-connect-follow { border-color: ButtonText; color: ButtonText; background: ButtonFace; }
  .pk-connect-title, .pk-connect-sub, .pk-connect-name, .pk-connect-reason, .pk-connect-all, .pk-connect-more { color: CanvasText; text-shadow: none; }
  .pk-connect-glow { background: Highlight; box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
  .pk-connect-track { scroll-behavior: auto; }
  .pk-connect-follow, .pk-connect-more svg { transition: none; }
}
