/* Omnigate motion and friendly empty states. Builds on takelan.css tokens (colours are always --tk-* custom properties).
 *
 * Rules every animation here follows:
 *   - it only exists inside  @media (prefers-reduced-motion: no-preference)  and  html:not([data-motion="off"])
 *     (motion.js sets data-motion="off" for the "Animations" switch and for prefers-reduced-motion);
 *     without motion the same information is shown as a still picture
 *   - it never moves layout (transform, opacity on shapes, or absolutely positioned bits) and never changes the colour
 *     of text, so contrast checks give the same result at every moment
 *   - loops can be paused (diagram) or switched off (Animations switch in the sidebar) */

/* ---------- background: static mesh under a canvas of slow lines (motion.js) ---------- */
.bg-canvas {
  position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: -1; pointer-events: none;
  background:
    radial-gradient(60% 55% at 92% -5%, rgba(99, 44, 166, .10), transparent 70%),
    radial-gradient(55% 50% at -5% 105%, rgba(47, 111, 214, .08), transparent 70%);
}
@media (prefers-color-scheme: dark) {
  .bg-canvas {
    background:
      radial-gradient(60% 55% at 92% -5%, rgba(122, 53, 214, .20), transparent 70%),
      radial-gradient(55% 50% at -5% 105%, rgba(58, 110, 220, .14), transparent 70%);
  }
}

[hidden] { display: none !important; }

/* ---------- user switch for animations ---------- */
html[data-motion="off"] *, html[data-motion="off"] *::before, html[data-motion="off"] *::after {
  animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important;
}
#motionToggle .motion-state { margin-left: auto; font-size: 11px; color: var(--tk-side-muted); text-align: right; }
#motionToggle[disabled] { cursor: default; opacity: .8; }
.sidebar-foot .nav-item + .nav-item { margin-top: 2px; }

/* ---------- friendly empty state ---------- */
.empty-rich { display: flex; align-items: center; justify-content: center; gap: 20px; flex-wrap: wrap; padding: 22px 16px; text-align: left; color: var(--tk-muted); }
.empty-rich .art { flex: none; width: 150px; color: var(--tk-c1); }
.empty-rich.is-compact { padding: 12px; gap: 12px; }
.empty-rich.is-compact .art { width: 92px; }
.empty-copy { flex: 1 1 260px; max-width: 520px; min-width: 0; }
.empty-copy p { margin: 0 0 10px; }
.empty-copy .empty-title { color: var(--tk-text); font-size: 15px; margin: 0 0 4px; }
.empty-copy .snippet-block { margin: 10px 0; text-align: left; }
.empty-copy .btn { margin-top: 4px; }
.empty-live { margin-bottom: 6px; }
.chart-empty { align-items: stretch; }
.chart-empty .empty-rich { width: 100%; }
.logview .empty-rich { color: #c9c4e2; }
.logview .empty-rich .art { color: #b69cff; }
.logview .empty-copy .empty-title { color: #fff; }
.logview .live-dot.is-live { color: #7fe0aa; }
.logview .snippet { border: 1px solid #4a4268; }
.art svg { display: block; width: 100%; height: auto; max-width: none; }
.a-grid { stroke: var(--tk-border); stroke-width: 1.5; }
.a-axis { stroke: var(--tk-muted); stroke-width: 2; }
.a-ghost { fill: var(--tk-surface-2); stroke: var(--tk-border); stroke-width: 1.5; }
.a-acc { stroke: var(--tk-c1); stroke-width: 2.5; }
.a-dot { fill: var(--tk-c1); stroke: none; }
.a-dash { stroke-dasharray: 4 6; }
.sample-ctl { margin-top: 12px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.sample-ctl .hint { flex: 1 1 200px; margin: 0; font-size: 12px; color: var(--tk-muted); }

.unavailable-act { margin-top: 8px; }
.health-wait { margin: 10px 0 0; }
.table-note { margin: 0; padding: 8px 14px 10px; }
.ck-foot { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; margin-top: 8px; border-top: 1px solid var(--tk-border); padding-top: 8px; }
.check-dots .wait { background: transparent; border: 1px dashed var(--tk-border); }
.alert .sample-ctl { margin-top: 6px; }
.alert-info .sample-ctl .btn { color: inherit; border-color: currentColor; }

/* tiny marks */
button.chip, button.tag { font-family: inherit; cursor: help; }
button.chip.chip-reset { border: 0; }
.tag-sample { background: var(--tk-info-bg); color: var(--tk-info-fg); border-color: transparent; font-weight: 600; }

/* ---------- onboarding and checklist ---------- */
.onboard-grid { display: grid; gap: 16px; grid-template-columns: minmax(0, 1fr); max-width: 980px; margin: 0 auto; }
.onboarding { background: var(--tk-surface); border: 1px solid var(--tk-border); border-radius: var(--tk-radius); box-shadow: var(--tk-shadow-1); }
.how-card .widget-body { padding: 14px; }
.checklist-card { background: var(--tk-surface); border: 1px solid var(--tk-border); border-radius: var(--tk-radius); box-shadow: var(--tk-shadow-1); padding: 14px 16px; min-width: 0; }
.ck-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.ck-head h2 { margin: 0; font-size: 15px; }
.ck-bar { margin: 8px 0 10px; }
.ck-bar > span { transition: width .5s ease; }
.checklist { list-style: none; margin: 0; padding: 0; }
.checklist > li { border-top: 1px solid var(--tk-border); }
.ck-step > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px; padding: 8px 2px; min-height: 40px; }
.ck-step > summary::-webkit-details-marker { display: none; }
.ck-step > summary::after { content: ""; width: 8px; height: 8px; border-right: 2px solid var(--tk-muted); border-bottom: 2px solid var(--tk-muted); transform: rotate(45deg); margin: -3px 4px 0 2px; flex: none; }
.ck-step[open] > summary::after { transform: rotate(-135deg); margin-top: 3px; }
.ck-mark { width: 26px; height: 26px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 12px; background: var(--tk-surface-2); border: 1px solid var(--tk-border); color: var(--tk-text); }
.ck-mark .icon { width: 14px; height: 14px; }
.ck-step.is-done .ck-mark { background: var(--tk-ok-bg); color: var(--tk-ok-fg); border-color: var(--tk-ok-dot); }
.ck-step.is-next .ck-mark { background: var(--tk-primary); color: var(--tk-on-primary); border-color: var(--tk-primary); }
.ck-title { font-weight: 600; flex: 1; min-width: 0; }
.ck-body { padding: 0 0 12px 36px; min-width: 0; }
.ck-body > p { margin: 0 0 8px; }
.ck-body .seg { margin-bottom: 8px; max-width: 100%; flex-wrap: wrap; }
.ck-body .check { margin-top: 10px; display: flex; gap: 6px; align-items: center; }
.ck-body .snippet-block + .btn, .ck-body .client-cmds + .btn { margin-top: 10px; }

/* ---------- the "How it works" diagram ---------- */
.hiw { container: hiw / inline-size; min-width: 0; }
.hiw-head { display: flex; gap: 10px; align-items: center; justify-content: space-between; flex-wrap: wrap; margin-bottom: 12px; }
.hiw-head .seg { max-width: 100%; flex-wrap: wrap; }
.hiw-static-note { display: none; margin: 0 0 8px; }
.hiw-stage { display: flex; align-items: center; padding: 34px 12px 30px; border: 1px solid var(--tk-border); border-radius: var(--tk-radius); background: var(--tk-surface-2); }
.hiw-node { flex: 0 0 128px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 3px; padding: 10px 6px; background: var(--tk-surface); border: 1px solid var(--tk-border); border-radius: 8px; position: relative; z-index: 2; min-width: 0; line-height: 1.3; }
.hiw-node strong { font-size: 13px; }
.hiw-node .small { overflow-wrap: anywhere; }
.hiw-ico { width: 40px; height: 40px; color: var(--tk-link); display: inline-flex; flex: none; }
.hiw-ico svg { width: 100%; height: 100%; max-width: none; }
.hiw-pipe { flex: 1 1 0; min-width: 96px; position: relative; height: 84px; }
.hiw-line { position: absolute; left: 0; right: 0; top: calc(50% - 1.5px); height: 3px; border-radius: 2px; background: repeating-linear-gradient(90deg, var(--tk-muted) 0 7px, transparent 7px 12px); opacity: .6; }
.hiw-addr { position: absolute; left: 50%; bottom: calc(50% + 22px); transform: translateX(-50%); width: max-content; max-width: 100%; text-align: center; font-size: 11px; line-height: 1.3; padding: 1px 6px; border: 1px solid var(--tk-border); border-radius: 4px; background: var(--tk-surface); color: var(--tk-text); overflow-wrap: anywhere; z-index: 1; }
.hiw-tube .hiw-line { top: calc(50% - 17px); height: 34px; border-radius: 17px; opacity: 1; background: var(--tk-row-hover); border: 2px solid var(--tk-c1); }
.hiw-lock { position: absolute; left: 50%; top: 50%; width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%; background: var(--tk-primary); color: var(--tk-on-primary); display: inline-flex; align-items: center; justify-content: center; z-index: 3; }
.hiw-lock .hiw-ico { width: 16px; height: 16px; color: inherit; }
.hiw-tube-label { position: absolute; left: 50%; top: calc(50% + 24px); transform: translateX(-50%); font-size: 11px; font-weight: 600; white-space: nowrap; color: var(--tk-link); }
.pk { position: absolute; z-index: 2; width: 14px; height: 14px; border-radius: 4px; background: var(--tk-c1); display: flex; align-items: center; justify-content: center; gap: 1px; }
.pk-back { background: var(--tk-c3); }
.pk i { width: 3px; height: 3px; border-radius: 50%; background: #fff; display: block; }
.hiw[data-variant="udp"] .pk { background: transparent; width: 22px; gap: 3px; }
.hiw[data-variant="udp"] .pk i { width: 5px; height: 5px; background: var(--tk-c1); }
.hiw[data-variant="udp"] .pk-back i { background: var(--tk-c3); }
.pk { box-shadow: 0 0 7px 1px color-mix(in srgb, var(--tk-c1) 55%, transparent); }
.pk-back { box-shadow: 0 0 7px 1px color-mix(in srgb, var(--tk-c3) 55%, transparent); }
.hiw[data-variant="udp"] .pk, .hiw[data-variant="udp"] .pk-back { box-shadow: none; }
.pk-c { margin-left: calc(var(--k, 0) * -17px); opacity: calc(1 - var(--k, 0) * .18); }
.hiw-line::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .45), transparent) no-repeat; background-size: 35% 100%; background-position: -40% 0; pointer-events: none; }
/* still picture: forward packets above the line, answers below it */
.pk-a-fwd, .pk-b-fwd { top: calc(50% - 18px); left: 30%; }
.pk-a-back, .pk-b-back { top: calc(50% + 4px); left: 60%; }
.hiw-tube .pk-b-fwd { top: calc(50% - 15px); }
.hiw-tube .pk-b-back { top: calc(50% + 2px); }
.hiw-steps { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 4px; counter-reset: none; }
.hiw-steps li { display: flex; gap: 10px; align-items: flex-start; padding: 6px 10px; border-radius: var(--tk-radius); box-shadow: inset 3px 0 0 transparent; }
.hiw-n { flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--tk-primary); color: var(--tk-on-primary); font-size: 12px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; margin-top: 1px; }
.hiw-body { min-width: 0; }
html[data-motion="off"] .hiw-pause { display: none; }
html[data-motion="off"] .hiw-static-note { display: block; }
@media (prefers-reduced-motion: reduce) { .hiw-pause { display: none; } .hiw-static-note { display: block; } }

@container hiw (max-width: 560px) {
  .hiw-stage { flex-direction: column; align-items: stretch; padding: 12px; }
  .hiw-node { flex: none; width: 100%; flex-direction: row; text-align: left; gap: 10px; padding: 8px 10px; flex-wrap: wrap; }
  .hiw-node > :not(.hiw-ico) { flex: 1 1 140px; }
  .hiw-ico { width: 34px; height: 34px; }
  .hiw-pipe { flex: none; width: 100%; height: 96px; min-width: 0; }
  .hiw-line { left: calc(50% - 1.5px); right: auto; top: 0; bottom: 0; width: 3px; height: auto; background: repeating-linear-gradient(180deg, var(--tk-muted) 0 7px, transparent 7px 12px); }
  .hiw-tube .hiw-line { left: calc(50% - 17px); width: 34px; height: auto; top: 0; bottom: 0; }
  .hiw-addr { left: calc(50% + 24px); bottom: auto; top: 50%; transform: translateY(-50%); width: auto; max-width: calc(50% - 30px); text-align: left; }
  .hiw-tube-label { left: calc(50% + 26px); top: 50%; transform: translateY(-50%); white-space: normal; max-width: calc(50% - 30px); }
  .pk-a-fwd, .pk-b-fwd { top: 30%; left: calc(50% - 20px); }
  .pk-a-back, .pk-b-back { top: 60%; left: calc(50% + 6px); }
  .hiw-tube .pk-b-fwd { left: calc(50% - 15px); }
  .hiw-tube .pk-b-back { left: calc(50% + 2px); }
}

/* ---------- animation (all of it lives here) ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* the page and its panels settle in (movement only, no change of colour) */
  html:not([data-motion="off"]) .content { animation: tk-page .26s ease-out; }
  html:not([data-motion="off"]) .kpi { animation: tk-rise .38s ease-out backwards; animation-delay: calc(var(--n, 0) * 45ms); }
  html:not([data-motion="off"]) .logline-new { animation: tk-slide-in .32s ease-out; }
  html:not([data-motion="off"]) .empty-rich .art { animation: tk-rise .5s ease-out backwards; }
  html:not([data-motion="off"]) .live-dot.is-live::before, html:not([data-motion="off"]) .chip-live::before { animation: tk-pulse 1.8s ease-out infinite; }

  /* charts draw themselves once, the first time they get data */
  html:not([data-motion="off"]) .chart-enter .chart-line { stroke-dasharray: 1; stroke-dashoffset: 1; animation: tk-draw 1s ease-out .05s forwards; }
  html:not([data-motion="off"]) .chart-enter .chart-area { animation: tk-area 1s ease-out backwards; }
  html:not([data-motion="off"]) .chart-enter .chart-series rect { transform-box: fill-box; transform-origin: 50% 100%; animation: tk-grow .6s ease-out backwards; }
  html:not([data-motion="off"]) .spark svg { animation: tk-rise .5s ease-out backwards; }

  /* copy button confirmation */
  html:not([data-motion="off"]) .is-copied { animation: tk-pop .3s ease-out; }

  /* dialogs: open and close (Chromium 117+, Safari 17.4+, Firefox 129+; elsewhere they simply appear) */
  html:not([data-motion="off"]) dialog.modal { transition: transform .18s ease, overlay .18s allow-discrete, display .18s allow-discrete; transform: translateY(10px) scale(.985); }
  html:not([data-motion="off"]) dialog.modal[open] { transform: none; }
  @starting-style { html:not([data-motion="off"]) dialog.modal[open] { transform: translateY(10px) scale(.985); } }
  html:not([data-motion="off"]) dialog.modal::backdrop { transition: background-color .18s ease, overlay .18s allow-discrete, display .18s allow-discrete; background-color: transparent; }
  html:not([data-motion="off"]) dialog.modal[open]::backdrop { background-color: rgba(14, 12, 26, .6); }
  @starting-style { html:not([data-motion="off"]) dialog.modal[open]::backdrop { background-color: transparent; } }

  /* illustrations */
  html:not([data-motion="off"]) .a-dash { animation: tk-dash 2.4s linear infinite; }
  html:not([data-motion="off"]) .a-pulse { transform-box: fill-box; transform-origin: center; animation: tk-ping 2s ease-in-out infinite; }
  html:not([data-motion="off"]) .a-blink { animation: tk-blink 1.1s steps(1, end) infinite; }

  /* the diagram: one 10 second journey, five steps of two seconds, request out and answer back */
  html:not([data-motion="off"]) .pk { animation-duration: 10s; animation-iteration-count: infinite; animation-timing-function: linear; animation-fill-mode: both; }
  html:not([data-motion="off"]) .pk-a-fwd { animation-name: hiw-fwd; animation-delay: 0s; }
  html:not([data-motion="off"]) .pk-b-fwd { animation-name: hiw-fwd; animation-delay: 2s; }
  html:not([data-motion="off"]) .pk-b-back { animation-name: hiw-back; animation-delay: 6s; }
  html:not([data-motion="off"]) .pk-a-back { animation-name: hiw-back; animation-delay: 8s; }
  /* streams: the extra chunks leave a fraction of a second behind each other, so several are in the tunnel at once */
  html:not([data-motion="off"]) .pk-c { margin-left: 0; opacity: 1; animation-delay: calc(var(--d, 0s) + var(--k, 0) * .24s); }
  html:not([data-motion="off"]) .pk-a-fwd.pk-c { --d: 0s; }
  html:not([data-motion="off"]) .pk-b-fwd.pk-c { --d: 2s; }
  html:not([data-motion="off"]) .pk-b-back.pk-c { --d: 6s; }
  html:not([data-motion="off"]) .pk-a-back.pk-c { --d: 8s; }
  html:not([data-motion="off"]) .hiw[data-variant="udp"] .pk-c { animation-delay: calc(var(--d, 0s) + var(--k, 0) * .37s); }
  html:not([data-motion="off"]) .hiw[data-variant="udp"] .pk-c:nth-of-type(odd) { animation-delay: calc(var(--d, 0s) + var(--k, 0) * .21s); }
  /* a UDP datagram that never arrives: it fades out in the tunnel and is not resent */
  html:not([data-motion="off"]) .pk-lost { animation-name: hiw-lost; }
  /* light running along the pipes and a gently breathing lock */
  html:not([data-motion="off"]) .hiw-line::after { animation: hiw-flow 2.2s linear infinite; }
  html:not([data-motion="off"]) .hiw-tube .hiw-lock { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tk-c1) 40%, transparent); }
  html:not([data-motion="off"]) .hiw-visitor { animation: hiw-lit-visitor 10s linear infinite both; }
  html:not([data-motion="off"]) .hiw-relay { animation: hiw-lit-relay 10s linear infinite both; }
  html:not([data-motion="off"]) .hiw-app { animation: hiw-lit-app 10s linear infinite both; }
  html:not([data-motion="off"]) .hiw-lock { animation: hiw-lit-lock 10s linear infinite both; }
  html:not([data-motion="off"]) .hiw-steps li { animation: hiw-cap 10s linear infinite both; animation-delay: calc(var(--i, 0) * 2s); }
  html:not([data-motion="off"]) .hiw[data-paused="true"] *, html:not([data-motion="off"]) .hiw[data-paused="true"] *::before { animation-play-state: paused; }

  @container hiw (max-width: 560px) {
    html:not([data-motion="off"]) .pk-a-fwd, html:not([data-motion="off"]) .pk-b-fwd { animation-name: hiw-fwd-y; }
    html:not([data-motion="off"]) .pk-a-back, html:not([data-motion="off"]) .pk-b-back { animation-name: hiw-back-y; }
    html:not([data-motion="off"]) .pk-lost { animation-name: hiw-lost-y; }
    html:not([data-motion="off"]) .hiw-line::after { background: linear-gradient(180deg, transparent, rgba(255, 255, 255, .45), transparent) no-repeat; background-size: 100% 35%; animation-name: hiw-flow-y; }
  }
}

@keyframes hiw-flow { from { background-position: -40% 0; } to { background-position: 140% 0; } }
@keyframes hiw-lost { 0% { left: 0; opacity: 0; transform: scale(1); } 2% { opacity: 1; } 10% { opacity: 1; transform: scale(1); } 13% { left: 55%; opacity: 0; transform: scale(.4) rotate(40deg); } 100% { left: 55%; opacity: 0; } }
@keyframes hiw-flow-y { from { background-position: 0 -40%; } to { background-position: 0 140%; } }
@keyframes hiw-lost-y { 0% { top: 0; opacity: 0; transform: scale(1); } 2% { opacity: 1; } 10% { opacity: 1; transform: scale(1); } 13% { top: 55%; opacity: 0; transform: scale(.4) rotate(40deg); } 100% { top: 55%; opacity: 0; } }
@keyframes tk-page { from { transform: translateY(8px); } }
@keyframes tk-rise { from { transform: translateY(10px); } }
@keyframes tk-slide-in { from { transform: translateX(-12px); } }
@keyframes tk-draw { to { stroke-dashoffset: 0; } }
@keyframes tk-area { from { fill-opacity: 0; } }
@keyframes tk-grow { from { transform: scaleY(0); } }
@keyframes tk-pop { 0% { transform: scale(1); } 40% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes tk-dash { to { stroke-dashoffset: -20; } }
@keyframes tk-ping { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.5); } }
@keyframes tk-blink { 50% { opacity: 0; } }
@keyframes hiw-fwd { 0% { left: 0; opacity: 0; } 2% { opacity: 1; } 18% { opacity: 1; } 20%, 100% { left: calc(100% - 14px); opacity: 0; } }
@keyframes hiw-back { 0% { left: calc(100% - 14px); opacity: 0; } 2% { opacity: 1; } 18% { opacity: 1; } 20%, 100% { left: 0; opacity: 0; } }
@keyframes hiw-fwd-y { 0% { top: 0; opacity: 0; } 2% { opacity: 1; } 18% { opacity: 1; } 20%, 100% { top: calc(100% - 14px); opacity: 0; } }
@keyframes hiw-back-y { 0% { top: calc(100% - 14px); opacity: 0; } 2% { opacity: 1; } 18% { opacity: 1; } 20%, 100% { top: 0; opacity: 0; } }
@keyframes hiw-lit-visitor { 0%, 20%, 80%, 100% { box-shadow: 0 0 0 3px var(--tk-focus); border-color: var(--tk-primary); } 20.01%, 79.99% { box-shadow: none; border-color: var(--tk-border); } }
@keyframes hiw-lit-relay { 0%, 14.99%, 30.01%, 69.99%, 85.01%, 100% { box-shadow: none; border-color: var(--tk-border); } 15%, 30%, 70%, 85% { box-shadow: 0 0 0 3px var(--tk-focus); border-color: var(--tk-primary); } }
@keyframes hiw-lit-app { 0%, 39.99%, 60.01%, 100% { box-shadow: none; border-color: var(--tk-border); } 40%, 60% { box-shadow: 0 0 0 3px var(--tk-focus); border-color: var(--tk-primary); } }
@keyframes hiw-lit-lock { 0%, 19.99%, 40.01%, 59.99%, 80.01%, 100% { box-shadow: none; } 20%, 40%, 60%, 80% { box-shadow: 0 0 0 5px rgba(124, 58, 237, .35); } }
@keyframes hiw-cap { 0% { background-color: transparent; box-shadow: inset 3px 0 0 transparent; } 0.01%, 20% { background-color: var(--tk-row-hover); box-shadow: inset 3px 0 0 var(--tk-primary); } 20.01%, 100% { background-color: transparent; box-shadow: inset 3px 0 0 transparent; } }

/* the diagram keeps still when motion is off: no animation at all, packets stay where the still picture puts them */
html[data-motion="off"] .hiw *, html[data-motion="off"] .hiw *::before { animation: none !important; }
@media (prefers-reduced-motion: reduce) { .hiw *, .hiw *::before { animation: none !important; } }

/* ---------- no layout jumps: containers keep a sensible height while their content loads ---------- */
.kpis[aria-busy="true"] .kpi, #kpis .kpi { min-height: 150px; }
#detailKpis:empty, #checkKpis:empty { min-height: 120px; }
.skeleton-block { height: 256px; }
#chartRequests, #chartBandwidth, #chartStatus { min-height: 256px; }
#dChartReq:empty, #dChartBw:empty, #dChartLat:empty, #dChartStatus:empty, #checkChart:empty { min-height: 256px; }
#endpointsBox:empty, #checkTable:empty { min-height: 120px; }
#topTunnels, #topEndpoints { min-height: 200px; }
#recentAudit { min-height: 240px; }
#healthBox { min-height: 200px; }
.empty-copy .snippet { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-all; }
.fact-skel dt.skeleton { width: 60%; height: 14px; margin: 0; } .fact-skel dd.skeleton { height: 20px; width: 80%; margin: 6px 0 0; }
.empty h2 { color: var(--tk-text); font-size: 15px; margin-bottom: 4px; }
#usageBox { min-height: 190px; }
#auditBox { min-height: 200px; }
#tunnelsList { min-height: 140px; }
.pill-skel { width: 64px; height: 22px; border-radius: 999px; margin: 0 !important; }
.btn-skel { width: 118px; height: 30px; margin: 0 !important; }
.facts > div, .fact-skel { min-height: 44px; }
.logview .empty-rich { font-family: var(--tk-font); }

/* ---------- Security tab explainer ("what your app sees"): packets cross, the log line slides in; transforms only ---------- */
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="off"]) .rip-pk { animation: rip-go 4s linear infinite; }
  html:not([data-motion="off"]) .rip-log-text { display: inline-block; animation: rip-line 4s linear infinite both; }
  html:not([data-motion="off"]) .rip[data-paused="true"] *, html:not([data-motion="off"]) .rip[data-paused="true"] *::before { animation-play-state: paused; }
}
@keyframes rip-go { 0% { transform: translateX(-24px); } 100% { transform: translateX(24px); } }
@keyframes rip-line { 0%, 55% { transform: translateX(-8px); } 70%, 100% { transform: none; } }
html[data-motion="off"] .rip *, html[data-motion="off"] .rip *::before { animation: none !important; }
@media (prefers-reduced-motion: reduce) { .rip *, .rip *::before { animation: none !important; } }


/* ---------- Animated flows on the Security and Direct tabs (TK.flow in guide.js) ---------- */
.fl { min-width: 0; }
.fl-stage { border: 1px solid var(--tk-border); border-radius: var(--tk-radius); background: var(--tk-surface-2); padding: 14px 8px 12px; overflow: hidden; }
.fl-nodes { display: grid; gap: 4px; }
.fl-node { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 3px; min-width: 0; padding: 0 2px; }
.fl-node strong { font-size: 12.5px; }
.fl-node .small { overflow-wrap: anywhere; font-size: 11.5px; }
.fl-node .hiw-ico { width: 34px; height: 34px; }
.fl-lanes { display: grid; margin-top: 10px; row-gap: 2px; }
.fl-lane { position: relative; height: 52px; }
.fl-text { position: absolute; left: -6px; right: -6px; top: 0; text-align: center; font-size: 11.5px; line-height: 1.25; color: var(--tk-muted); }
.fl-text b { display: inline-block; min-width: 16px; height: 16px; line-height: 16px; border-radius: 50%; background: var(--tk-primary); color: var(--tk-on-primary); font-size: 10.5px; margin-right: 2px; }
.fl-line { position: absolute; left: 0; right: 0; bottom: 9px; height: 3px; border-radius: 2px; background: var(--tk-border); }
.fl-line::after { content: ""; position: absolute; right: -2px; top: -4px; border-left: 8px solid var(--tk-border); border-top: 5.5px solid transparent; border-bottom: 5.5px solid transparent; }
.fl-rev .fl-line::after { right: auto; left: -2px; border-left: 0; border-right: 8px solid var(--tk-border); }
.fl-direct .fl-line { background: var(--tk-ok-dot); } .fl-direct .fl-line::after { border-left-color: var(--tk-ok-dot); }
.fl-rev.fl-direct .fl-line::after { border-left-color: transparent; border-right-color: var(--tk-ok-dot); }
.fl-dim .fl-line { background: repeating-linear-gradient(90deg, var(--tk-border) 0 6px, transparent 6px 10px); }
.fl-dots { position: absolute; left: 0; right: 0; bottom: 4px; height: 13px; overflow: hidden; display: none; }
.fl-dot { position: absolute; left: 0; top: 0; width: 100%; height: 13px; transform: translateX(-100%); }
.fl-dot::after { content: ""; position: absolute; right: 0; top: 1px; width: 11px; height: 11px; border-radius: 50%; background: var(--tk-c1); }
.fl-rev .fl-dot { transform: translateX(100%); } .fl-rev .fl-dot::after { right: auto; left: 0; background: var(--tk-c3); }
.fl-direct .fl-dot::after { background: var(--tk-ok-dot); }
.fl-ctl { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.fl-static { display: none; }
.fl-steps { margin-top: 8px; }
html[data-motion="off"] .fl-pause { display: none; }
html[data-motion="off"] .fl-static { display: inline; }
@media (prefers-reduced-motion: reduce) { .fl-pause { display: none; } .fl-static { display: inline; } }
@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="off"]) .fl-dots { display: block; }
  html:not([data-motion="off"]) .fl-dot { animation: fl-run 8s linear infinite; animation-delay: var(--d, 0s); }
  html:not([data-motion="off"]) .fl-rev .fl-dot { animation-name: fl-run-rev; }
  html:not([data-motion="off"]) .fl[data-paused="true"] .fl-dot { animation-play-state: paused; }
}
@keyframes fl-run { 0% { transform: translateX(-100%); } 18% { transform: translateX(0); } 18.01%, 100% { transform: translateX(-100%); } }
@keyframes fl-run-rev { 0% { transform: translateX(100%); } 18% { transform: translateX(0); } 18.01%, 100% { transform: translateX(100%); } }
@media (max-width: 520px) { .fl-text { font-size: 10.5px; } .fl-lane { height: 58px; } .fl-node .hiw-ico { width: 28px; height: 28px; } }


/* ---------- Packet-flow panel of the create-tunnel dialog and the tunnel page (sec-flow.js, built on the diagram above) ----------
   One loop = six slots (--slot each). A packet flies during its own slot only (first sixth of its animation). */
.sf { --slot: 2.2s; }
.sf .sf-stranger, .sf .sf-adm { display: none; }
.sf .sf-blocked { background: var(--tk-err-dot); box-shadow: 0 0 7px 1px color-mix(in srgb, var(--tk-err-dot) 55%, transparent); left: calc(100% - 30px); }
.sf .sf-blocked.sf-fwd ~ .sf-blocked.sf-fwd { display: none; }
.sf .sf-stranger { background: var(--tk-warn-dot); }
.sf .sf-adm { background: var(--tk-warn-dot); }
.sf .hiw-relay { border-color: var(--tk-ok-dot); }
.sf[data-mode="open"] .hiw-relay { border-color: var(--tk-warn-dot); }
.hiw.sf[data-variant="udp"] .sf-blocked, .hiw.sf[data-variant="udp"] .sf-stranger, .hiw.sf[data-variant="udp"] .sf-adm { background: transparent; box-shadow: none; }
.hiw.sf[data-variant="udp"] .sf-blocked i { background: var(--tk-err-dot); }
.hiw.sf[data-variant="udp"] .sf-stranger i, .hiw.sf[data-variant="udp"] .sf-adm i { background: var(--tk-warn-dot); }
.sf-head { margin-bottom: 8px; }
.sf-warn { margin-top: 10px; }
html[data-motion="off"] .sf-pause { display: none; }
html[data-motion="off"] .sf .hiw-static-note { display: block; }
@media (prefers-reduced-motion: reduce) { .sf-pause { display: none; } .sf .hiw-static-note { display: block; } }

@media (prefers-reduced-motion: no-preference) {
  html:not([data-motion="off"]) .sf .sf-stranger, html:not([data-motion="off"]) .sf .sf-adm { display: flex; }
  html:not([data-motion="off"]) .sf .sf-blocked, html:not([data-motion="off"]) .sf .sf-blocked.sf-fwd ~ .sf-blocked.sf-fwd { display: flex; }
  html:not([data-motion="off"]) .sf .pk.sf-p { animation-duration: calc(var(--slot) * 6); animation-delay: calc(var(--s, 0) * var(--slot)); animation-iteration-count: infinite; animation-timing-function: linear; animation-fill-mode: both; }
  html:not([data-motion="off"]) .sf .pk.sf-fwd { animation-name: sf-fwd; }
  html:not([data-motion="off"]) .sf .pk.sf-back { animation-name: sf-back; }
  html:not([data-motion="off"]) .sf .pk.sf-blocked { animation-name: sf-bounce; }
  html:not([data-motion="off"]) .sf .hiw-visitor, html:not([data-motion="off"]) .sf .hiw-relay, html:not([data-motion="off"]) .sf .hiw-app, html:not([data-motion="off"]) .sf .hiw-lock, html:not([data-motion="off"]) .sf .hiw-steps li { animation: none; }
  html:not([data-motion="off"]) .sf[data-paused="true"] .pk { animation-play-state: paused; }
  @container hiw (max-width: 560px) {
    html:not([data-motion="off"]) .sf .pk.sf-fwd { animation-name: sf-fwd-y; }
    html:not([data-motion="off"]) .sf .pk.sf-back { animation-name: sf-back-y; }
    html:not([data-motion="off"]) .sf .pk.sf-blocked { animation-name: sf-bounce-y; }
  }
}
@keyframes sf-fwd { 0% { left: 0; opacity: 0; } 1% { opacity: 1; } 15% { opacity: 1; } 16.6%, 100% { left: calc(100% - 14px); opacity: 0; } }
@keyframes sf-back { 0% { left: calc(100% - 14px); opacity: 0; } 1% { opacity: 1; } 15% { opacity: 1; } 16.6%, 100% { left: 0; opacity: 0; } }
@keyframes sf-bounce { 0% { left: 0; opacity: 0; transform: none; } 1% { opacity: 1; } 7% { left: calc(100% - 14px); opacity: 1; transform: none; } 8.3% { left: calc(100% - 14px); transform: scale(1.5) rotate(45deg); } 9.5% { left: calc(100% - 22px); transform: rotate(120deg); } 15% { opacity: 1; } 16.6%, 100% { left: 0; opacity: 0; transform: rotate(200deg); } }
@keyframes sf-fwd-y { 0% { top: 0; opacity: 0; } 1% { opacity: 1; } 15% { opacity: 1; } 16.6%, 100% { top: calc(100% - 14px); opacity: 0; } }
@keyframes sf-back-y { 0% { top: calc(100% - 14px); opacity: 0; } 1% { opacity: 1; } 15% { opacity: 1; } 16.6%, 100% { top: 0; opacity: 0; } }
@keyframes sf-bounce-y { 0% { top: 0; opacity: 0; transform: none; } 1% { opacity: 1; } 7% { top: calc(100% - 14px); opacity: 1; transform: none; } 8.3% { top: calc(100% - 14px); transform: scale(1.5) rotate(45deg); } 9.5% { top: calc(100% - 22px); transform: rotate(120deg); } 15% { opacity: 1; } 16.6%, 100% { top: 0; opacity: 0; transform: rotate(200deg); } }
html[data-motion="off"] .sf *, html[data-motion="off"] .sf *::before { animation: none !important; }
@container hiw (max-width: 560px) { .sf .sf-blocked { left: calc(50% - 20px); top: calc(100% - 30px); } }
