/* 05 · Votre étape · integration hub.
   TonIAssistant's mark in the centre, real app logos on two slow orbits, on phones too.
   Click a logo: a beam lights between it and the centre and the card says what we would plug in.
   The frame has a fixed height in every state, so the text column beside it never moves. */

@property --hub-spin { syntax: "<angle>"; inherits: true; initial-value: 0deg; }

.hub {
  --hub-ink: var(--sc-ink, #0a1020);
  --hub-soft: var(--sc-ink-soft, #4b5670);
  --hub-accent: var(--sc-accent, #2152ff);
  --hub-glow: var(--glow, #62d8ff);
  --hub-line: color-mix(in oklab, var(--hub-ink) 10%, transparent);
  --hub-ease: var(--sc-ease-out, cubic-bezier(0.23, 1, 0.32, 1));
  --hub-h: 440px;          /* same height as the other row visuals */
  --hub-card-h: 92px;
  --hub-chip: 46px;
  container-type: inline-size;
  container-name: hub;
}
.hub *, .hub *::before, .hub *::after { box-sizing: border-box; }
.hub-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.hub-frame {
  position: relative; z-index: 1;
  height: var(--hub-h);
  display: grid; grid-template-rows: minmax(0, 1fr) var(--hub-card-h);
  background: #fff; border-radius: 18px; overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--hub-line), 0 1px 0 var(--hub-line), 0 28px 60px -32px color-mix(in oklab, var(--hub-ink) 40%, transparent);
}

/* ---------- stage ---------- */
.hub-stage {
  position: relative; min-height: 0;
  container-type: size;
  background:
    radial-gradient(42% 46% at 50% 50%, color-mix(in oklab, var(--hub-glow) 20%, transparent), transparent 72%),
    radial-gradient(circle at 1px 1px, color-mix(in oklab, var(--hub-ink) 9%, transparent) 1px, transparent 1.4px) 0 0 / 18px 18px;
  --rx-out: calc(50cqw - 40px); --ry-out: calc(50cqh - 32px);
  --rx-in: 31cqw;               --ry-in: 23cqh;
  animation: hubSpin 160s linear infinite;
}
.hub-stage:hover, .hub:focus-within .hub-stage, .hub.is-off .hub-stage { animation-play-state: paused; }
@keyframes hubSpin { to { --hub-spin: 360deg; } }

.hub-orbit { position: absolute; left: 50%; top: 50%; translate: -50% -50%; border-radius: 50%; pointer-events: none;
  border: 1px dashed color-mix(in oklab, var(--hub-accent) 22%, transparent); }
.hub-orbit--in  { width: calc(var(--rx-in) * 2);  height: calc(var(--ry-in) * 2); }
.hub-orbit--out { width: calc(var(--rx-out) * 2); height: calc(var(--ry-out) * 2); border-style: solid; border-color: var(--hub-line); }


/* centre: the TonIAssistant mark */
.hub-core { position: absolute; left: 50%; top: 50%; translate: -50% -50%; z-index: 2; display: grid; justify-items: center; gap: 6px; pointer-events: none; }
.hub-mark { position: relative; display: block; width: 64px; height: 64px; border-radius: 16px;
  box-shadow: 0 0 0 6px #fff, 0 0 0 7px color-mix(in oklab, var(--hub-accent) 18%, transparent), 0 18px 40px -12px color-mix(in oklab, var(--hub-accent) 70%, transparent); }
.hub-mark svg { display: block; width: 100%; height: 100%; }
.hub-mark::after { content: ""; position: absolute; inset: -7px; border-radius: 22px; border: 2px solid var(--hub-c, var(--hub-accent)); opacity: 0; }
.hub-core.is-hit .hub-mark::after { animation: hubRipple 900ms var(--hub-ease); }
@keyframes hubRipple { 0% { opacity: .9; scale: 1; } 100% { opacity: 0; scale: 1.55; } }
.hub-core__name { font: 600 11px/1 var(--sc-font-display, "Bricolage Grotesque", system-ui, sans-serif); letter-spacing: -0.01em; color: var(--hub-ink);
  padding: 4px 8px; border-radius: 999px; background: #fff; box-shadow: inset 0 0 0 1px var(--hub-line); }
.hub-core__name b { color: var(--hub-accent); font-weight: 600; }

/* beams */
.hub-beams { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; overflow: visible; }
.hub-beams path { fill: none; stroke-linecap: round; }
.hub-beam-base { stroke: var(--hub-c); stroke-width: 2.5; stroke-opacity: .38; }
.hub-beam-in  { stroke: var(--hub-c); stroke-width: 3; stroke-dasharray: 16 100; animation: hubFlowIn 1.6s linear infinite; filter: drop-shadow(0 0 4px var(--hub-c)); }
.hub-beam-out { stroke: var(--hub-accent); stroke-width: 3; stroke-dasharray: 12 100; animation: hubFlowOut 1.6s linear infinite .8s; stroke-dashoffset: 120; filter: drop-shadow(0 0 4px var(--hub-glow)); }
.hub-ghost { stroke: var(--hub-c); stroke-width: 2; stroke-dasharray: 14 100; stroke-dashoffset: 14; opacity: .55; animation: hubFlowIn 1.5s var(--hub-ease) forwards; }
@keyframes hubFlowIn  { from { stroke-dashoffset: 14; } to { stroke-dashoffset: -100; } }
@keyframes hubFlowOut { from { stroke-dashoffset: -100; } to { stroke-dashoffset: 14; } }

/* apps on the orbits: both rings turn together, so inner logos always sit between two outer ones */
.hub-apps { position: absolute; inset: 0; z-index: 2; }
.hub-app {
  --ang: calc(var(--a) + var(--hub-spin));
  position: absolute; left: 50%; top: 50%;
  translate: calc(-50% + cos(var(--ang)) * var(--rx-out)) calc(-50% + sin(var(--ang)) * var(--ry-out));
  border: 0; background: none; padding: 0; cursor: pointer; color: var(--hub-ink);
  display: grid; justify-items: center; font: inherit;
  transition: opacity 240ms;
}
.hub-app--in { --ang: calc(var(--a) + var(--hub-spin)); translate: calc(-50% + cos(var(--ang)) * var(--rx-in)) calc(-50% + sin(var(--ang)) * var(--ry-in)); }
.hub-chip { width: var(--hub-chip); height: var(--hub-chip); border-radius: 14px; display: grid; place-items: center; background: #fff;
  box-shadow: inset 0 0 0 1px var(--hub-line), 0 8px 20px -10px color-mix(in oklab, var(--hub-ink) 45%, transparent);
  transition: transform 260ms var(--hub-ease), box-shadow 260ms var(--hub-ease); }
.hub-logo { width: 24px; height: 24px; display: block; }
.hub-name { position: absolute; top: calc(100% + 6px); left: 50%; translate: -50% 0; white-space: nowrap; pointer-events: none;
  font-size: 11px; font-weight: 500; line-height: 1; padding: 4px 7px; border-radius: 6px; background: var(--hub-ink); color: #fff;
  opacity: 0; transform: translateY(-3px); transition: opacity 160ms, transform 160ms var(--hub-ease); }
.hub-app:hover, .hub-app:focus-visible { z-index: 4; }
.hub-app:hover .hub-chip, .hub-app:focus-visible .hub-chip { transform: translateY(-3px) scale(1.1); }
.hub-app:hover .hub-name, .hub-app:focus-visible .hub-name { opacity: 1; transform: none; }
.hub-app:focus-visible { outline: none; }
.hub-app:focus-visible .hub-chip { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--hub-accent); }
.hub-app[aria-pressed="true"] { z-index: 3; }
.hub-app[aria-pressed="true"] .hub-chip { transform: scale(1.14);
  box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--hub-c), 0 14px 28px -12px var(--hub-c); }
.hub.has-pick .hub-app:not([aria-pressed="true"]) { opacity: .62; }
.hub.has-pick .hub-app:not([aria-pressed="true"]):hover, .hub.has-pick .hub-app:not([aria-pressed="true"]):focus-visible { opacity: 1; }
.hub-app--yours .hub-chip { background: color-mix(in oklab, var(--hub-accent) 7%, #fff); color: var(--hub-accent); box-shadow: none;
  outline: 1.5px dashed color-mix(in oklab, var(--hub-accent) 55%, transparent); outline-offset: -1.5px; }

/* ---------- detail card: fixed height, text clamped ---------- */
.hub-card { display: grid; grid-template-columns: 40px minmax(0, 1fr); align-items: center; gap: 14px; padding: 0 18px;
  border-top: 1px solid var(--hub-line); background: #fff; overflow: hidden; }
.hub-card__chip { width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; background: #fff; color: var(--hub-accent);
  box-shadow: inset 0 0 0 1px var(--hub-line); }
.hub-card__chip .hub-logo { width: 22px; height: 22px; }
.hub-card__txt { margin: 0; display: grid; gap: 2px; font-size: 14px; line-height: 20px; min-width: 0; }
.hub-card__txt b { display: flex; align-items: center; gap: 6px; min-width: 0; font-weight: 600; color: var(--hub-ink); white-space: nowrap; overflow: hidden; }
.hub-card__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.hub-card__ex { margin-left: auto; flex: none; font-size: 10.5px; font-weight: 500; letter-spacing: .06em; text-transform: uppercase; color: var(--hub-accent); padding: 2px 7px; border-radius: 999px; background: color-mix(in oklab, var(--hub-accent) 8%, #fff); }
.hub-card__txt b i { margin-left: .35em; font-style: normal; font-weight: 500; color: var(--hub-soft); }
.hub-card__txt > span { color: var(--hub-soft); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; height: 40px; text-wrap: pretty; }
.hub-card.is-swap .hub-card__txt, .hub-card.is-swap .hub-card__chip { animation: hubSwap 320ms var(--hub-ease); }
@keyframes hubSwap { from { opacity: 0; transform: translateY(4px); } }

/* ---------- narrow: the same orbit, smaller; names show in the card when a logo is tapped ---------- */
@container hub (max-width: 440px) {
  .hub-frame { --hub-h: 470px; --hub-card-h: 104px; --hub-chip: 38px; }
  .hub-stage { --rx-out: calc(50cqw - 26px); --ry-out: calc(50cqh - 26px); --rx-in: 30cqw; --ry-in: 27cqh; }
  .hub-logo { width: 20px; height: 20px; }
  .hub-mark { width: 56px; height: 56px; border-radius: 14px; }
  .hub-card { padding: 0 14px; gap: 12px; }
  .hub-card__txt { font-size: 13.5px; line-height: 19px; }
  .hub-card__txt > span { -webkit-line-clamp: 3; line-clamp: 3; height: 57px; }
}

@media (prefers-reduced-motion: reduce) {
  .hub-stage { animation: none; }
  .hub-beam-in, .hub-beam-out, .hub-ghost { display: none; }
  .hub-beam-base { stroke-opacity: .7; }
  .hub-core.is-hit .hub-mark::after, .hub-card.is-swap .hub-card__txt, .hub-card.is-swap .hub-card__chip { animation: none; }
  .hub-chip, .hub-name { transition: none; }
}

/* wordmark-only brands get a wider tile so the name stays readable */
.hub-app--wide .hub-chip { width: 80px; }
.hub-app--wide .hub-logo { width: 64px; height: 26px; }
@media (max-width: 860px) { .hub-app--wide .hub-chip { width: var(--hub-chip); } .hub-app--wide .hub-logo { width: 40px; } }
