/* "Works with every app" connection map (homepage): a mind map built by feature-connect.js. The ESHLON wordmark
   sits in the middle with no frame; hubs are plain labels with an icon; white app tiles keep every logo in its
   own colours and sources without a logo are grey text. Lines stop short of what they point at. Self-contained so
   it renders the same on any page. Sizes inside the map are in cqi (per cent of the stage width) because the layout
   was solved at 1200px wide: a 42px tile there is 3.5cqi, so the spacing holds at every desktop width. */
.feature-connect{background:#111;color:#eee;padding:100px 0 110px;scroll-margin-top:90px;font-family:"Eshlon Sans",Arial,sans-serif;--cx-ease:cubic-bezier(.22,1,.36,1)}
.feature-connect,.feature-connect *{box-sizing:border-box}
.cx-wrap{width:100%;max-width:1256px;margin:0 auto;padding:0 28px}
.cx-heading{display:grid;grid-template-columns:1.2fr 1fr;gap:70px;align-items:end;padding-bottom:34px}
.cx-heading h2{margin:0;font-size:clamp(36px,4.1vw,54px);font-weight:500;letter-spacing:-.045em;line-height:1.08;color:#eee}
.cx-heading h2 span{color:#909090}
.cx-heading>div{max-width:410px;justify-self:end}
.cx-heading p{margin:0;font-size:16px;line-height:1.7;color:#aaa}
@media(max-width:1000px){.cx-heading{gap:36px}}

.cx-stage{position:relative;width:100%;aspect-ratio:1200/700;margin:8px 0 0;user-select:none;container-type:inline-size;--cx-tile:3.5cqi}
.cx-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}

/* Lines: core to hub (spokes), hub to app (branches) and one hub-to-hub link, all one quiet grey. They fade in
   with the hubs, then the apps, and brighten for hover, light-ups and routes. */
.cx-line{stroke:#383838;stroke-width:1;vector-effect:non-scaling-stroke;stroke-linecap:round;opacity:0;transition:stroke 200ms ease,opacity 600ms ease;transition-delay:0ms,450ms}
.cx-spoke{stroke:#444;transition-delay:0ms,var(--d,0ms)}
.cx-link{transition-delay:0ms,700ms}
.feature-connect.is-in .cx-line{opacity:1}
.feature-connect.is-settled .cx-line{transition-delay:0ms}
.cx-line.is-lit:not(.is-route){stroke:#666}
.cx-line.is-hot{stroke:#9a9a9a}
.cx-line.is-route{stroke:#fff}
.cx-pulse{fill:#bdbdbd}
.cx-pulse.is-strong{fill:#fff;filter:drop-shadow(0 0 4px rgba(255,255,255,.9))}

/* Centre: the wordmark, large, like a title in the middle of the map. It glows briefly as a pulse lands. */
.cx-core{position:absolute;left:50%;top:50%;z-index:2;display:block;transform:translate(-50%,-50%);pointer-events:none}
.cx-core img{display:block;width:auto;height:2.6cqi}
.cx-core.is-ping img{animation:cx-glow 700ms var(--cx-ease)}
@keyframes cx-glow{from{filter:drop-shadow(0 0 .8cqi rgba(255,255,255,.55))}to{filter:drop-shadow(0 0 0 rgba(255,255,255,0))}}

/* Hubs: the group's icon and name as a plain label in open space. */
.cx-hub{position:absolute;z-index:3;display:inline-flex;align-items:center;gap:.42em;padding:.15em .1em;color:#ededed;font:500 1.667cqi/1.1 "Eshlon Sans",Arial,sans-serif;letter-spacing:-.025em;white-space:nowrap;cursor:default;opacity:0;transform:translate(-50%,-50%) scale(.92);transition:opacity 420ms ease,transform 520ms var(--cx-ease),color 200ms ease,text-shadow 200ms ease;transition-delay:calc(var(--i) * 70ms + 120ms)}
.cx-hub svg{flex-shrink:0;width:1em;height:1em;fill:none;stroke:#a8a8a8;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;transition:stroke 200ms ease}
.feature-connect.is-in .cx-hub{opacity:1;transform:translate(-50%,-50%) scale(1)}
.feature-connect.is-settled .cx-hub{transition-delay:0ms}
.cx-hub.is-hot,.cx-hub.is-hover,.cx-hub.is-route{color:#fff}
.cx-hub.is-hot svg,.cx-hub.is-hover svg,.cx-hub.is-route svg{stroke:#fff}
.cx-hub.is-route{text-shadow:0 0 18px rgba(255,255,255,.35)}

/* Apps: white tiles; data sources without a logo are grey text, like the reference leaves. */
.cx-node{position:absolute;z-index:3;display:grid;place-items:center;width:var(--cx-tile);height:var(--cx-tile);padding:0;border:0;border-radius:calc(var(--cx-tile) * .26);background:#fff;cursor:default;opacity:0;transform:translate(-50%,-50%) scale(.6);transition:opacity 420ms ease,transform 520ms var(--cx-ease),box-shadow 200ms ease;transition-delay:calc(var(--i) * 22ms + 380ms);box-shadow:0 0 0 1px rgba(255,255,255,.06),0 8px 24px rgba(0,0,0,.35)}
.feature-connect.is-in .cx-node{opacity:1;transform:translate(-50%,-50%) scale(1)}
.cx-node .cx-logo{display:grid;place-items:center;width:58%;height:58%}
.cx-node .cx-logo svg{width:100%;height:100%;display:block}
.cx-node .cx-logo img{width:118%;height:118%;border-radius:22%;display:block;object-fit:cover}
.cx-text{width:auto;height:auto;padding:.2em .1em;border-radius:4px;background:none;color:#9a9a9a;font:400 max(11px,1.25cqi)/1.2 "Eshlon Sans",Arial,sans-serif;letter-spacing:.005em;white-space:nowrap;transition:opacity 420ms ease,transform 520ms var(--cx-ease),color 200ms ease;transition-delay:calc(var(--i) * 22ms + 380ms)}
.cx-text-label{display:block}
.cx-node:focus-visible{outline:2px solid #fff;outline-offset:3px}

/* Hover an app: it stays bright, its lines light, everything else steps back. Hover a hub: its group comes forward. */
.cx-stage.is-focus .cx-node:not(.is-hover),.feature-connect.is-routing .cx-stage .cx-node:not(.is-route){opacity:.55}
.cx-stage.is-focus .cx-node.is-hover{transform:translate(-50%,-50%) scale(1.08);transition-delay:0ms}
.cx-stage.is-group .cx-node:not(.is-member){opacity:.3}
.cx-stage.is-group .cx-hub:not(.is-hover){opacity:.45}
.feature-connect.is-routing .cx-stage.is-group .cx-node.is-member{opacity:1}
.cx-stage.is-group .cx-node.is-member{transform:translate(-50%,-50%) scale(1.06)}
.feature-connect.is-routing .cx-node{transition-delay:0ms}
.feature-connect.is-routing .cx-stage .cx-node.is-route{opacity:1;transform:translate(-50%,-50%) scale(1.1);box-shadow:0 0 0 2px #fff,0 0 28px rgba(255,255,255,.28)}
.cx-step{position:absolute;top:-8px;right:-8px;display:none;place-items:center;min-width:20px;height:20px;padding:0 5px;border-radius:999px;background:#fff;color:#000;font:700 11px/1 "Eshlon Sans",Arial,sans-serif;box-shadow:0 0 0 2px #111}
.is-route .cx-step{display:grid}

.cx-tip{position:absolute;z-index:5;width:max-content;max-width:240px;padding:10px 12px;border:1px solid #2e2e2e;border-radius:10px;background:#1a1a1a;color:#a8a8a8;font-size:12.5px;line-height:1.45;pointer-events:none;opacity:0;transform:translate(-50%,calc(-100% - var(--cx-tile) * .62 - 6px)) scale(.97);transition:opacity 150ms ease,transform 150ms ease}
.cx-tip.is-below{transform:translate(-50%,calc(var(--cx-tile) * .62 + 6px)) scale(.97)}
.cx-tip.is-shown{opacity:1;transform:translate(-50%,calc(-100% - var(--cx-tile) * .62)) scale(1)}
.cx-tip.is-below.is-shown{transform:translate(-50%,calc(var(--cx-tile) * .62)) scale(1)}
.cx-tip strong{display:block;margin-bottom:3px;color:#fff;font-size:13px;font-weight:500}

/* Controls: example tasks, centred under the map. */
.cx-controls{display:flex;align-items:center;justify-content:center;margin-top:22px}
.cx-routes{position:relative;display:inline-flex;align-items:center;padding:4px;border:1px solid #262626;border-radius:999px;background:#1a1a1a}
.cx-routes button,.cx-routes-overlay b{display:inline-flex;align-items:center;height:34px;padding:0 16px;border:0;border-radius:999px;background:transparent;font:500 13.5px/1 "Eshlon Sans",Arial,sans-serif;letter-spacing:.01em;white-space:nowrap}
.cx-routes button{color:#9e9e9e;cursor:pointer;transition:color 150ms ease}
.cx-routes button:hover:not([aria-pressed=true]){color:#fff}
.cx-routes button:focus-visible{outline:2px solid #8a8a8a;outline-offset:3px}
.cx-routes-overlay{position:absolute;inset:0;display:flex;align-items:center;padding:4px;border-radius:999px;background:#fff;color:#000;pointer-events:none;opacity:0;clip-path:inset(0 100% 0 0 round 999px);transition:clip-path 280ms cubic-bezier(.2,.7,.2,1)}
.cx-routes-overlay.is-on{opacity:1}
.cx-routes-overlay.is-still{transition:none}

/* Apps light up as a pulse leaves them: brighter, a soft glow, a small lift. Wins over the route and hover dimming.
   Text sources have no tile, so they only turn white. */
.feature-connect.is-settled .cx-node{transition-delay:0ms}
.cx-stage .cx-node.is-lit,.feature-connect.is-routing .cx-stage .cx-node.is-lit:not(.is-route),.cx-stage.is-focus .cx-node.is-lit:not(.is-hover){opacity:1;transform:translate(-50%,-50%) scale(1.07);box-shadow:0 0 0 1px rgba(255,255,255,.55),0 0 24px rgba(255,255,255,.22);transition:opacity 260ms ease,transform 360ms var(--cx-ease),box-shadow 260ms ease}

.cx-stage .cx-node.cx-text{box-shadow:none!important}
.cx-text.is-lit,.cx-text.is-hover,.cx-text.is-route{color:#fff}
.cx-text .cx-step{top:-12px;right:-16px}

/* Phones: the map needs the width, so the section is not shown there. */
@media(max-width:760px){.feature-connect{display:none}}
@media(prefers-reduced-motion:reduce){.cx-node,.cx-hub,.cx-line,.cx-tip,.cx-routes button,.cx-routes-overlay{transition:none}.cx-core.is-ping img{animation:none}}
