/* The Voyage: the animated "what happens to a message" explainer, embedded in
   the public marketing site. Same scene engine as the customer portal
   (/assets/js/voyage.js), laid out for the landing page:

   - The stage is a column: a head bar (counters, legend, full screen), the
     scene, and a foot bar (controls, logbook). The HUD lives in the bars and
     never floats over the drawing, so nothing can collide with the scene at
     any width. (It used to be pinned in pixels over an SVG that scales, which
     is exactly how the legend ended up under the controls.)
   - The scene canvas always has the SVG viewBox's aspect ratio, so the drawing
     is never letterboxed inline; in full screen it is sized from the space
     left between the bars with container units.
   - Full screen is the browser's Fullscreen API on #voy-stage, with a fixed
     overlay fallback (.is-pseudo-full) where element full screen is missing.
   Dark only (the landing site has a single theme). */

/* The section is wider than the page container: the scene is ten stages
   across, and every extra pixel of width is legibility. */
.voy-wide { padding-inline: clamp(12px, 2.4vw, 32px); }

.voy-embed {
  --voy-ink: #eaf0fb;
  --voy-muted: #9aa7c0;
  --voy-accent: #2f97ff;
  --voy-glass: rgba(16, 24, 42, 0.72);
  --voy-glass-border: rgba(255, 255, 255, 0.12);
  --voy-good: #36e2a4;
  --voy-bad: #ff5d6c;
  --voy-warn: #ffc24b;
  --voy-pipe: rgba(120, 160, 235, 0.22);
  --voy-grid: rgba(120, 150, 220, 0.06);
  --voy-box: rgba(20, 30, 52, 0.94);
  --voy-box-ink: #e8eefb;
  --voy-box-sub: #a9b8d6;
  --voy-ratio: 3.1864; /* 1880 / 590, the SVG viewBox; keep in step with voyage.js */
  position: relative;
  max-width: 1760px;
  margin-inline: auto;
  font-family: var(--f-text, "Rubik"), system-ui, -apple-system, "Segoe UI", sans-serif;
}

.voy-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  border-radius: 22px;
  overflow: hidden;
  color: var(--voy-ink);
  border: 1px solid var(--voy-glass-border);
  background:
    radial-gradient(1100px 700px at 50% 42%, color-mix(in srgb, var(--voy-accent) 14%, transparent), transparent 70%),
    linear-gradient(180deg, #0b1322, #060a14);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .45), inset 0 0 0 1px rgba(255, 255, 255, .03);
}
.voy-stage * { box-sizing: border-box; }

/* faint grid + drifting glow backdrop */
.voy-stage::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-image:
    linear-gradient(var(--voy-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--voy-grid) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(circle at 50% 45%, #000 35%, transparent 80%);
  pointer-events: none;
}
.voy-stage::after {
  content: ""; position: absolute; inset: -20%; z-index: 0;
  background:
    radial-gradient(36% 36% at 26% 30%, color-mix(in srgb, var(--voy-accent) 22%, transparent), transparent 70%),
    radial-gradient(32% 32% at 78% 70%, color-mix(in srgb, #8a5bff 18%, transparent), transparent 70%);
  filter: blur(46px);
  animation: voy-drift 26s ease-in-out infinite alternate;
  pointer-events: none;
}
@keyframes voy-drift { from { transform: translate3d(-2%, -1%, 0) scale(1); } to { transform: translate3d(2%, 2%, 0) scale(1.08); } }

/* ---- bars ------------------------------------------------------------------ */
.voy-bar {
  position: relative; z-index: 2;
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  padding: 12px 16px;
}
.voy-head { border-bottom: 1px solid rgba(255, 255, 255, .06); }
.voy-foot { border-top: 1px solid rgba(255, 255, 255, .06); }

/* the scene's own title, only needed once the page around it is gone */
.voy-heading { display: none; flex-direction: column; gap: 2px; margin-right: auto; min-width: 0; }
.voy-heading-kicker { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--voy-accent);
  display: inline-flex; align-items: center; gap: 6px; }
.voy-heading-kicker .ti { font-size: 15px; }
.voy-heading-title { font-family: var(--f-display, inherit); font-size: 18px; font-weight: 600; letter-spacing: -.01em; }

.voy-counters { display: flex; gap: 8px; }
.voy-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin-left: auto; font-size: 12.5px; }
.voy-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.voy-log { flex: 0 1 430px; min-width: 260px; margin-left: auto;
  padding: 8px 12px; border-radius: 14px; background: var(--voy-glass);
  border: 1px solid var(--voy-glass-border); backdrop-filter: blur(8px); }

.voy-ctl {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 38px; min-width: 38px; padding: 0 12px;
  border-radius: 11px; border: 1px solid var(--voy-glass-border);
  background: var(--voy-glass); color: var(--voy-ink); font: inherit; font-size: 13.5px; white-space: nowrap;
  cursor: pointer; backdrop-filter: blur(8px); transition: transform .12s ease, border-color .12s ease, background .12s ease;
}
.voy-ctl:hover { transform: translateY(-1px); border-color: color-mix(in srgb, var(--voy-accent) 60%, var(--voy-glass-border)); }
.voy-ctl:focus-visible { outline: 2px solid var(--voy-accent); outline-offset: 2px; }
.voy-full { flex: none; }
.voy-full .ti { font-size: 16px; color: var(--voy-accent); }

/* counters */
.voy-count { display: flex; flex-direction: column; align-items: center; min-width: 92px;
  padding: 5px 12px; border-radius: 12px; background: var(--voy-glass);
  border: 1px solid var(--voy-glass-border); backdrop-filter: blur(8px); }
.voy-count-num { font-size: 19px; line-height: 1.2; font-weight: 700; font-variant-numeric: tabular-nums; }
.voy-count-label { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--voy-muted); white-space: nowrap; }
.voy-count-stopped .voy-count-num { color: var(--voy-bad); }
.voy-count-delivered .voy-count-num { color: var(--voy-good); }
.voy-count-num.voy-bump { animation: voy-bump .42s ease; }
@keyframes voy-bump { 0% { transform: scale(1); } 35% { transform: scale(1.32); } 100% { transform: scale(1); } }

/* legend swatches */
.voy-lg { display: inline-flex; align-items: center; gap: 7px; color: var(--voy-muted); white-space: nowrap; }
.voy-lg i:not(.ti) { width: 12px; height: 12px; border-radius: 50%; display: inline-block; }
.voy-lg-good i:not(.ti) { background: var(--voy-good); box-shadow: 0 0 10px var(--voy-good); }
.voy-lg-bad i:not(.ti) { background: var(--voy-bad); box-shadow: 0 0 10px var(--voy-bad); }
.voy-lg-eye .ti { color: var(--voy-accent); font-size: 16px; }

/* controls */
.voy-speed { display: inline-flex; border-radius: 11px; overflow: hidden; border: 1px solid var(--voy-glass-border); }
.voy-speed-btn { height: 38px; border: none; border-radius: 0; background: transparent; min-width: 44px; backdrop-filter: none; }
.voy-speed-btn:hover { transform: none; background: rgba(255, 255, 255, .05); }
.voy-speed-btn.is-active { background: color-mix(in srgb, var(--voy-accent) 30%, transparent); border-color: transparent; }
.voy-send-good { color: var(--voy-good); }
.voy-send-bad { color: var(--voy-bad); }
.voy-send i { font-size: 16px; }

/* logbook: newest first, older entries fade out under the fold */
.voy-log-head { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--voy-muted);
  display: flex; align-items: center; gap: 7px; margin-bottom: 4px; }
.voy-log-head .ti { font-size: 15px; }
.voy-log-list { list-style: none; margin: 0; padding: 0; max-height: 58px; overflow: hidden; display: flex; flex-direction: column; gap: 4px;
  mask-image: linear-gradient(#000 62%, transparent); }
/* resting state is visible (opacity 1); the keyframe is only an entrance
   flourish, so entries stay readable even if animations are suppressed.
   Colours are literal (not color-mix) so they render on every browser. */
.voy-log-list li { font-size: 12px; line-height: 1.34; color: #eaf0fb; animation: voy-log-in .4s ease; }
.voy-log-list li.is-bad { color: #ff8a93; }
.voy-log-list li.is-good { color: #57e6a9; }
.voy-log-list li.is-note { color: #8fb6ff; font-style: italic; }
@keyframes voy-log-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

/* ---- the scene -------------------------------------------------------------- */
.voy-scene { position: relative; z-index: 1; }
.voy-canvas { position: relative; width: 100%; aspect-ratio: 1880 / 590; }
.voy-svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* interaction hint, parked in the scene's empty top-left corner */
.voy-hint { position: absolute; z-index: 5; top: 14px; left: 16px;
  padding: 7px 13px; border-radius: 999px; background: var(--voy-glass); border: 1px solid var(--voy-glass-border);
  backdrop-filter: blur(8px); font-size: 12.5px; color: var(--voy-muted); display: flex; align-items: center; gap: 8px;
  animation: voy-hint-pulse 2.6s ease-in-out infinite; transition: opacity .4s ease; pointer-events: none; }
.voy-hint .ti { font-size: 16px; color: var(--voy-accent); }
.voy-hint.is-gone { opacity: 0; }
@keyframes voy-hint-pulse { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }

/* ---- full screen ------------------------------------------------------------ */
.voy-stage.is-full { width: 100%; height: 100%; border: 0; border-radius: 0; box-shadow: none; }
.voy-stage.is-pseudo-full { position: fixed; inset: 0; z-index: 2000; height: 100vh; height: 100dvh; }
html.voy-lock, html.voy-lock body { overflow: hidden; }
.voy-stage.is-full .voy-bar { padding: 14px clamp(16px, 2vw, 28px); }
.voy-stage.is-full .voy-heading { display: flex; }
.voy-stage.is-full .voy-legend { margin-left: 0; }
.voy-stage.is-full .voy-log-list { max-height: 96px; }
/* the canvas takes the largest viewBox-shaped box that fits between the bars */
.voy-stage.is-full .voy-scene { flex: 1 1 auto; min-height: 0; container-type: size;
  display: grid; place-items: center; padding: 8px clamp(8px, 1.5vw, 24px); }
.voy-stage.is-full .voy-canvas { width: min(100cqw, 100cqh * var(--voy-ratio)); }
.voy-rotate { display: none; }

/* ---- explainer panel (covers the stage) ------------------------------------- */
.voy-panel { position: absolute; inset: 0; z-index: 20; display: none; }
.voy-panel.is-open { display: block; }
.voy-panel-backdrop { position: absolute; inset: 0; background: rgba(4, 8, 16, 0.55); backdrop-filter: blur(2px);
  animation: voy-fade .25s ease; }
.voy-panel-card { position: absolute; top: 50%; left: 50%; width: min(440px, 88%);
  transform: translate(-50%, -50%); padding: 24px 24px 20px; border-radius: 20px;
  background: var(--voy-box); border: 1px solid var(--voy-glass-border);
  box-shadow: 0 30px 80px rgba(0,0,0,.55); color: var(--voy-box-ink);
  animation: voy-pop .32s cubic-bezier(.2,.9,.3,1.2); }
@keyframes voy-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes voy-pop { from { opacity: 0; transform: translate(-50%, -46%) scale(.94); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
.voy-panel-x { position: absolute; top: 12px; right: 12px; width: 34px; height: 34px; border-radius: 9px;
  border: 1px solid var(--voy-glass-border); background: transparent; color: var(--voy-box-sub); cursor: pointer; }
.voy-panel-x:hover { color: var(--voy-box-ink); }
.voy-panel-badge { width: 54px; height: 54px; border-radius: 16px; display: grid; place-items: center;
  background: color-mix(in srgb, var(--voy-accent) 22%, transparent); color: var(--voy-accent); margin-bottom: 12px; }
.voy-panel-badge .ti { font-size: 29px; }
.voy-panel-kicker { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--voy-accent); }
.voy-panel-title { margin: 4px 0 10px; font-size: 22px; }
.voy-panel-body { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--voy-box-sub); }
.voy-panel-foot { margin-top: 16px; padding-top: 13px; border-top: 1px solid var(--voy-glass-border);
  display: flex; gap: 9px; align-items: flex-start; font-size: 12px; color: var(--voy-box-sub); }
.voy-panel-foot .ti { color: var(--voy-good); font-size: 16px; flex: none; margin-top: 1px; }

/* ---- SVG scene styling (classes used by voyage.js) -------------------------- */
.voy-pipe-base { fill: none; stroke: var(--voy-pipe); stroke-linecap: round; stroke-width: 13; }
.voy-pipe-flow { fill: none; stroke: color-mix(in srgb, var(--voy-accent) 70%, transparent);
  stroke-linecap: round; stroke-width: 4; stroke-dasharray: 2 16; opacity: .7; animation: voy-flow 1.1s linear infinite; }
@keyframes voy-flow { to { stroke-dashoffset: -18; } }

.voy-box-shape { fill: var(--voy-box); stroke: var(--voy-glass-border); stroke-width: 1.5;
  transition: stroke .18s ease, filter .18s ease; cursor: pointer; }
.voy-box-group:hover .voy-box-shape { stroke: var(--voy-accent); filter: drop-shadow(0 0 14px color-mix(in srgb, var(--voy-accent) 45%, transparent)); }
.voy-box-group.is-flash .voy-box-shape { animation: voy-box-flash .6s ease; }
@keyframes voy-box-flash { 0% { stroke: var(--voy-accent); filter: drop-shadow(0 0 20px var(--voy-accent)); } 100% { } }
.voy-box-title { fill: var(--voy-box-ink); font-family: var(--f-display, inherit); font-weight: 600; pointer-events: none; }
.voy-box-sub { fill: var(--voy-box-sub); pointer-events: none; }
.voy-box-accent { stroke-width: 3.5; stroke-linecap: round; }
/* the lane through the middle of a box: the message passes here, clear of the text */
.voy-box-lane { stroke: rgba(120, 160, 235, .2); stroke-width: 2; stroke-dasharray: 2 7; stroke-linecap: round; pointer-events: none; }
/* node captions sit beside the pipes, so they get a halo to stay readable
   while a packet slides past */
.voy-node-label { fill: var(--voy-box-sub); paint-order: stroke; stroke: #0a1120; stroke-width: 4px; stroke-linejoin: round; pointer-events: none; }

.voy-node-dot { stroke: var(--voy-glass-border); stroke-width: 1.5;
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--voy-accent) 55%, transparent)); }

/* The Admiralty: the remote hub in the distance */
.voy-adm-halo { fill: rgba(138, 123, 255, 0.14); }
.voy-adm-core { fill: var(--voy-box); stroke: #8a7bff; stroke-width: 1.5; }
.voy-box-group:hover .voy-adm-core { stroke: #8a7bff; filter: drop-shadow(0 0 14px #8a7bff); }
.voy-adm-ring { fill: none; stroke: #8a7bff; stroke-width: 1.5; opacity: 0;
  transform-box: fill-box; transform-origin: center; animation: voy-adm-idle 3s ease-out infinite; }
.voy-adm-ring-2 { animation-delay: 1.5s; }
@keyframes voy-adm-idle { 0% { opacity: .5; transform: scale(.7); } 100% { opacity: 0; transform: scale(1.9); } }
.voy-adm-hit { fill: none; stroke: #8a7bff; stroke-width: 3; opacity: 0;
  transform-box: fill-box; transform-origin: center; }
.voy-adm-hit.is-hit { animation: voy-adm-pulse .7s ease-out; }
@keyframes voy-adm-pulse { 0% { opacity: .95; transform: scale(.6); } 100% { opacity: 0; transform: scale(2.7); } }
.voy-adm-core.is-hit { animation: voy-adm-flash .55s ease; }
@keyframes voy-adm-flash { 0% { filter: drop-shadow(0 0 18px #8a7bff); } 100% { } }

/* the sealed parcel that carries a caught threat away to The Admiralty */
.voy-report-box { fill: #4a141c; stroke: var(--voy-bad); stroke-width: 1.5;
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--voy-bad) 70%, transparent)); }
.voy-report-strap { stroke: rgba(255, 255, 255, .8); stroke-width: 1.4; fill: none; }

/* Tabler webfont icon rendered inside an SVG <foreignObject> */
.voy-fo-ico { display: flex; align-items: center; justify-content: center; overflow: visible; pointer-events: none; }
.voy-fo-ico i { display: block; }

/* dissolve puff */
.voy-puff { transform-box: fill-box; transform-origin: center; animation: voy-puff .64s ease-out forwards; }
.voy-puff-bad { fill: var(--voy-bad); }
.voy-puff-good { fill: var(--voy-good); }
@keyframes voy-puff { from { opacity: .85; transform: scale(.4); } to { opacity: 0; transform: scale(2.7); } }

/* packets */
.voy-packet-good { fill: var(--voy-good); filter: drop-shadow(0 0 7px color-mix(in srgb, var(--voy-good) 80%, transparent)); }
.voy-packet-bad  { fill: var(--voy-bad);  filter: drop-shadow(0 0 7px color-mix(in srgb, var(--voy-bad) 85%, transparent)); }
.voy-packet-core { fill: rgba(255,255,255,.85); }
.voy-packet.is-followed .voy-packet-ring { stroke: var(--voy-warn); stroke-width: 2; fill: none; opacity: .9; }

/* eyes */
.voy-eye-sclera { fill: #f4f8ff; stroke: color-mix(in srgb, var(--voy-accent) 50%, #20304e); stroke-width: 1.5; }
.voy-eye-iris { fill: var(--voy-accent); transition: fill .2s ease; }
.voy-eye-pupil { fill: #0a1326; }
.voy-eye.is-alert .voy-eye-iris { fill: var(--voy-bad); }
.voy-eye-ring { fill: none; stroke: var(--voy-bad); stroke-width: 2.5; opacity: 0;
  transform-box: fill-box; transform-origin: center; }
.voy-eyeball { transform-box: fill-box; transform-origin: center; transition: transform .09s ease; }
.voy-pupil { transition: transform .04s linear; }
.voy-eye.is-alert .voy-eye-ring { animation: voy-scan-ring .6s ease-out; }
@keyframes voy-scan-ring { 0% { opacity: .9; transform: scale(.4); } 100% { opacity: 0; transform: scale(1.9); } }
.voy-eye-float { animation: voy-eye-bob 4.2s ease-in-out infinite; }
@keyframes voy-eye-bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }

@media (prefers-reduced-motion: reduce) { .voy-stage::after, .voy-eye-float, .voy-hint { animation: none; } }

/* ---- narrow screens ----------------------------------------------------------- */
/* Below this the whole journey cannot be read at once, so the scene keeps a
   readable size and scrolls sideways instead of shrinking to a sliver. */
@media (max-width: 760px) {
  .voy-stage { border-radius: 16px; }
  .voy-bar { padding: 10px 12px; }
  .voy-count { min-width: 0; flex: 1 1 0; padding: 5px 8px; }
  .voy-count-label { white-space: normal; text-align: center; line-height: 1.2; }
  .voy-counters { flex: 1 1 100%; }
  .voy-legend { margin-left: 0; }
  .voy-full { margin-left: auto; }
  .voy-log { flex: 1 1 100%; min-width: 0; margin-left: 0; }
  .voy-scene { overflow-x: auto; overscroll-behavior-x: contain; }
  .voy-canvas { width: 1100px; }
  .voy-stage.is-full .voy-scene { place-items: center start; }
  .voy-stage.is-full .voy-canvas { width: max(900px, min(100cqw, 100cqh * var(--voy-ratio))); }
  .voy-stage.is-full .voy-legend { display: none; }
}
@media (max-width: 760px) and (orientation: portrait) {
  .voy-stage.is-full .voy-rotate { display: flex; align-items: center; justify-content: center; gap: 8px;
    position: relative; z-index: 2; padding: 6px 12px; font-size: 12.5px; color: var(--voy-muted); }
  .voy-rotate .ti { color: var(--voy-accent); font-size: 16px; }
}
/* phones held sideways in full screen: give the scene every spare pixel */
@media (max-height: 520px) {
  .voy-stage.is-full .voy-bar { padding: 6px 12px; gap: 6px 10px; }
  .voy-stage.is-full .voy-heading,
  .voy-stage.is-full .voy-legend,
  .voy-stage.is-full .voy-log { display: none; }
  .voy-stage.is-full .voy-count { padding: 2px 8px; min-width: 0; }
  .voy-stage.is-full .voy-count-num { font-size: 15px; }
  .voy-stage.is-full .voy-ctl { height: 32px; min-width: 32px; }
}
