/* Card-specific styles for the "gateway" harbor course (class prefix .hb-gateway-).
 * The cluster is a harbour behind a sea wall: boats are clients outside, buoys are Services, doors in the wall are
 * open ports, wooden signs are Ingress rules, picket fences are NetworkPolicies. A request is a dot on a lane. */
.hb-gateway-icon { width:22px; height:22px; flex-shrink:0; overflow:visible; }
.hb-panel-head>b svg.hb-gateway-icon { width:24px; height:24px; }

/* Stops: every station a request passes, on the board and in the demos. */
.hb-gateway-stop { position:relative; display:inline-flex; align-items:center; gap:5px; min-width:0; max-width:100%; padding:3px 9px 3px 4px; border:2px solid #9fb4a6; border-radius:11px; background:#fffbea; box-shadow:0 2px 0 #9fb4a6; color:#2f4f4c; }
.hb-gateway-stop>svg.hb-cube { width:24px; height:27px; flex-shrink:0; }
.hb-gateway-stop-text { display:grid; min-width:0; line-height:1.25; }
.hb-gateway-stop-text b { font:800 11.5px var(--mono); overflow-wrap:anywhere; }
.hb-gateway-stop-text small { font:600 10px var(--mono); color:#5d6a64; overflow-wrap:anywhere; }
.hb-gateway-stop.buoy { border-color:#5aa6c6; box-shadow:0 2px 0 #5aa6c6; }
.hb-gateway-stop.pod { border-color:#b59c61; box-shadow:0 2px 0 #ab905b; background:#fff7d8; }
.hb-gateway-stop.ok { border-color:#6aa274; box-shadow:0 2px 0 #6aa274; }
.hb-gateway-stop.block { border-color:#c76750; box-shadow:0 2px 0 #b76a55; background:#fbe6dc; }
.hb-gateway-stop.block::after { content:'✗'; position:absolute; top:-8px; right:-7px; width:17px; height:17px; border-radius:50%; background:#c76750; color:#fff; font:800 10px/17px var(--sans); text-align:center; }
.hb-gateway-stop.dim { opacity:.55; border-style:dashed; box-shadow:none; }
.hb-gateway-stop.on { border-color:#5c9a68; box-shadow:0 2px 0 #5c9a68,0 0 0 4px #c5e9b488; }
.hb-gateway-stop.bounce { border-color:#c76750; box-shadow:0 2px 0 #b76a55,0 0 0 4px #f8e1da; animation:st-shake .45s; }

/* Tracks between stops; a dot runs along them while the lane plays. */
.hb-gateway-route { display:flex; flex-wrap:wrap; align-items:center; row-gap:8px; min-width:0; }
.hb-gateway-track { position:relative; flex:1 1 18px; min-width:14px; max-width:90px; height:4px; margin:0 3px; border-radius:2px; background:repeating-linear-gradient(90deg,#8eaaa4 0 5px,transparent 5px 9px); }
.hb-gateway-track::before { content:''; position:absolute; inset:0; border-radius:2px; transform-origin:left; }
.hb-gateway-track.pass::before { background:#5c9a68; }
.hb-gateway-track.fail::before { background:#c76750; }
.hb-gateway-track.idle { max-width:none; }
.hb-gateway-dot { position:absolute; top:-4px; left:0; width:12px; height:12px; border-radius:50%; background:#efaa42; border:2px solid #7a5a2f; opacity:0; pointer-events:none; }
.hb-gateway-lane.go .hb-gateway-track.pass::before,.hb-gateway-lane.go .hb-gateway-track.fail::before { animation:hb-gateway-draw .42s calc(var(--i) * .42s) linear both; }
.hb-gateway-lane.go .hb-gateway-track.pass .hb-gateway-dot { animation:hb-gateway-run .42s calc(var(--i) * .42s) linear both; }
.hb-gateway-lane.go .hb-gateway-track.fail .hb-gateway-dot { animation:hb-gateway-bounce .7s calc(var(--i) * .42s) ease-out both; }
.hb-gateway-lane.go .hb-gateway-stop.block { animation:st-shake .45s .55s; }

/* Lanes: one per test request, expected outcome next to the actual one. */
.hb-gateway-lanes { list-style:none; margin:0; padding:0; display:grid; gap:10px; }
.hb-gateway-lane { min-width:0; padding:9px 12px 10px; border:2px solid #b8a576; border-radius:14px; background:linear-gradient(#fffbea,#f8efd2); box-shadow:0 3px 0 #b39a62; display:grid; gap:8px; }
.hb-gateway-lane.go { border-color:#a98048; box-shadow:0 3px 0 #9a7848,0 0 0 4px #ffe4a088; }
.hb-gateway-lane.miss:not(.go) { border-color:#c38a7c; box-shadow:0 3px 0 #b76a55; background:linear-gradient(#fff6f0,#f8e6dc); }
.hb-gateway-lane.match:not(.go) { border-color:#8cb497; box-shadow:0 3px 0 #82a696; }
.hb-gateway-ask { display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; }
.hb-gateway-ask>b { flex:1 1 180px; min-width:0; font:800 12.5px var(--mono); color:#2f4f4c; overflow-wrap:anywhere; }
.hb-gateway-expect,.hb-gateway-code { padding:2px 8px; border-radius:7px; font:700 11px var(--mono); white-space:nowrap; }
.hb-gateway-expect { border:1.5px dashed #9fb4a6; color:#4a675e; background:#f3f7ec; }
.hb-gateway-code.arrive { border:1.5px solid #6aa274; background:#dff2d6; color:#2d694b; }
.hb-gateway-code.stop { border:1.5px solid #c38a7c; background:#f8e1da; color:#9c3d2d; }
/* It got through, but it should not have. */
.hb-gateway-code.leak { border:1.5px solid #c99a3e; background:#ffeab4; color:#7a4f12; }
.hb-gateway-mark { flex-shrink:0; width:22px; height:22px; border-radius:50%; display:grid; place-items:center; font:800 12px var(--sans); color:#fff; background:#5c9a68; box-shadow:0 2px 0 #3f7656; }
.hb-gateway-mark.bad { background:#c76750; box-shadow:0 2px 0 #8f4f36; }
.hb-gateway-detail { display:block; padding:5px 8px; border-radius:8px; background:#fffcf0; border:1.5px dashed #d8c9a0; font:600 11px/1.5 var(--mono); color:#6b4d2a; overflow-wrap:anywhere; }
.hb-gateway-lane.miss .hb-gateway-detail { color:#8b3f30; }

/* The harbour: internet outside, the sea wall with its doors, the cluster inside. */
.hb-gateway-scene { border:3px solid #5c7e7d; border-radius:20px; overflow:hidden; background:#fffdf4; box-shadow:0 5px 0 #567979; }
.hb-gateway-out,.hb-gateway-in { display:flex; flex-wrap:wrap; align-items:center; gap:10px; padding:12px 14px; }
.hb-gateway-out { background:repeating-radial-gradient(ellipse at 50% 120%,transparent 0 18px,#ffffff30 19px 21px,transparent 23px 34px),#79b4c8; }
.hb-gateway-in { background:repeating-radial-gradient(ellipse at 50% -20%,transparent 0 18px,#ffffff40 19px 21px,transparent 23px 34px),#cdeee2; }
.hb-gateway-zone-label { padding:2px 8px; border-radius:6px; background:#244958cc; color:#f4f6de; font:800 10px var(--mono); letter-spacing:1px; }
.hb-gateway-in .hb-gateway-zone-label { background:#3f7656cc; }
.hb-gateway-wall { display:flex; flex-wrap:wrap; justify-content:center; gap:10px; padding:10px; border-block:3px solid #7a5a2f; background-color:#c9b48a; background-image:linear-gradient(#7a5a2f44 2px,transparent 2px),linear-gradient(90deg,#7a5a2f44 2px,transparent 2px); background-size:30px 14px; }
.hb-gateway-wall.closed { min-height:46px; align-items:center; }
.hb-gateway-closed { padding:4px 10px; border-radius:8px; background:#fff6dbdd; font:700 11px var(--sans); color:#6b4d2a; }
.hb-gateway-door { position:relative; display:flex; align-items:center; gap:7px; min-width:0; padding:6px 11px 6px 7px; border:2px solid #7a5a2f; border-radius:16px 16px 6px 6px; background:#fff6db; box-shadow:0 3px 0 #7a5a2f; color:#3b3a2a; }
.hb-gateway-door b { display:block; font:800 11.5px var(--mono); }
.hb-gateway-door small { display:block; font:600 10px var(--mono); color:#6b5a3a; }
.hb-gateway-door.on { border-color:#4f8a5b; box-shadow:0 3px 0 #4f8a5b,0 0 0 4px #c5e9b4; }
.hb-gateway-door.bad { border-color:#c76750; box-shadow:0 3px 0 #b76a55,0 0 0 4px #f8e1da; }
.hb-gateway-cost { position:absolute; top:-9px; right:-8px; width:19px; height:19px; border-radius:50%; background:#efaa42; border:2px solid #7a5a2f; font:800 10px/15px var(--mono); text-align:center; color:#4d3d2a; }
.hb-gateway-buoy { display:flex; align-items:center; gap:7px; padding:6px 11px 6px 7px; border:2px solid #5aa6c6; border-radius:13px; background:#fffbea; box-shadow:0 3px 0 #5aa6c6; }
.hb-gateway-buoy>div { display:grid; justify-items:start; gap:2px; }
.hb-gateway-buoy b { font:800 12px var(--mono); color:#244958; }
.hb-gateway-buoy small { font:600 10px var(--mono); color:#5d6a64; }
.hb-gateway-buoy .hb-chip { font-size:9.5px; padding:0 5px; }
.hb-gateway-buoy.on { border-color:#4f8a5b; box-shadow:0 3px 0 #4f8a5b,0 0 0 4px #c5e9b4; }
.hb-gateway-buoy.bad { opacity:.6; }

/* Route signs at the Ingress gate. */
.hb-gateway-signs { display:grid; gap:7px; margin-bottom:12px; }
.hb-gateway-sign { position:relative; display:grid; grid-template-columns:minmax(0,1fr) auto auto auto; align-items:center; gap:8px; padding:6px 12px 6px 10px; border:2px solid #8a6d2f; border-radius:5px 16px 16px 5px; background:linear-gradient(#f6e4b8,#e9cf96); box-shadow:0 3px 0 #8a6d2f; font:700 12px var(--mono); color:#4d3d2a; transition:opacity .25s; }
.hb-gateway-sign .host { overflow-wrap:anywhere; }
.hb-gateway-sign code { font:800 12.5px var(--mono); color:#2f4f4c; }
.hb-gateway-sign small { font:700 10.5px var(--mono); color:#6b5a3a; padding:1px 6px; border-radius:6px; background:#fff6db; }
.hb-gateway-sign>b { color:#245470; }
.hb-gateway-sign.edit { border-style:dashed; background:linear-gradient(#ffeec2,#ffe1a0); }
.hb-gateway-pen { position:absolute; top:-9px; left:10px; padding:0 6px; border-radius:6px; background:#a98048; color:#fff8e5; font:800 9.5px/16px var(--sans); font-style:normal; }
.hb-gateway-sign.hit { border-color:#4f8a5b; box-shadow:0 3px 0 #4f8a5b,0 0 0 4px #c5e9b4; background:linear-gradient(#ecf8de,#d2ecc0); }
.hb-gateway-sign.dim { opacity:.42; }

/* Namespaces and Pods behind fences. */
.hb-gateway-nsmap { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,190px),1fr)); gap:12px; }
.hb-gateway-ns { min-width:0; border:2px dashed #6f9ea0; border-radius:18px; padding:8px 10px 12px; background:#e4f6f04d; }
.hb-gateway-ns>header { display:flex; justify-content:space-between; gap:6px; margin:0 4px 10px; font:800 12px var(--mono); color:#2b5a66; }
.hb-gateway-ns>header span { font:600 10px var(--sans); color:#4a675e; }
.hb-gateway-ns.sea { background:#79b4c866; border-color:#3d6f86; }
.hb-gateway-ns-body { display:flex; flex-wrap:wrap; gap:14px 8px; align-items:flex-start; }
.hb-gateway-pod { position:relative; display:flex; align-items:center; gap:6px; min-width:0; padding:6px 9px 6px 5px; border:2px solid #b59c61; border-radius:12px; background:#fff7d8; box-shadow:0 3px 0 #ab905b; }
.hb-gateway-pod>svg { width:28px; height:32px; flex-shrink:0; }
.hb-gateway-pod>div { display:grid; justify-items:start; gap:3px; min-width:0; }
.hb-gateway-pod b { font:800 12px var(--mono); color:#3f4a38; }
.hb-gateway-pod .hb-chip { font-size:9.5px; padding:0 5px; }
.hb-gateway-fences { display:flex; flex-wrap:wrap; gap:3px; }
.hb-gateway-pod.fenced-in::before,.hb-gateway-pod.fenced-out::after { content:''; position:absolute; left:8px; right:8px; height:9px; border:2px solid #7a5a2f; background:repeating-linear-gradient(90deg,#fff3d1 0 5px,#7a5a2f 5px 7px); }
.hb-gateway-pod.fenced-in::before { top:-11px; border-bottom:0; border-radius:4px 4px 0 0; }
.hb-gateway-pod.fenced-out::after { bottom:-11px; border-top:0; border-radius:0 0 4px 4px; }
.hb-gateway-pod.from { border-color:#a98048; box-shadow:0 3px 0 #9a7848,0 0 0 4px #ffe4a0; }
.hb-gateway-pod.to { border-color:#4f8a5b; box-shadow:0 3px 0 #4f8a5b,0 0 0 4px #c5e9b4; }
.hb-gateway-pod.bad { border-color:#c76750; box-shadow:0 3px 0 #b76a55,0 0 0 4px #f8e1da; animation:st-shake .45s; }
.hb-gateway-secret,.hb-gateway-ingress-card { display:flex; align-items:center; gap:7px; padding:6px 10px 6px 6px; border:2px solid #b8964f; border-radius:12px; background:#ffe9b0; box-shadow:0 3px 0 #b8964f; }
.hb-gateway-secret b,.hb-gateway-ingress-card b { display:block; font:800 12px var(--mono); color:#4d3d2a; }
.hb-gateway-secret small { display:block; font:600 10px var(--mono); color:#6b5a3a; }
.hb-gateway-ingress-card { border-color:#7a5a2f; background:#fff6db; box-shadow:0 3px 0 #7a5a2f; }
.hb-gateway-lookup { display:block; font:700 10.5px var(--mono); color:#5d6a64; }
.hb-gateway-lookup.ok { color:#2d694b; }.hb-gateway-lookup.bad { color:#9c3d2d; }
.hb-gateway .hb-stats { margin:12px 0 0; }
.hb-gateway-secret.on { border-color:#4f8a5b; box-shadow:0 3px 0 #4f8a5b,0 0 0 3px #c5e9b4; }
.hb-gateway-secret.dim { opacity:.55; border-style:dashed; box-shadow:none; }
/* YAML: one block per line, so a wrapped line hangs under its own indentation instead of restarting at column 0. */
.hb-gateway-yaml>span { display:block; padding-left:calc((var(--ind) + 2) * 1ch); text-indent:calc((var(--ind) + 2) * -1ch); }

/* Demo versions: the same pieces, shrunk to fit the porthole. */
.hb-gateway-demo { gap:8px; }
.hb-gateway-scene.mini { border-width:2px; border-radius:14px; box-shadow:0 3px 0 #567979; }
.hb-gateway-scene.mini .hb-gateway-out,.hb-gateway-scene.mini .hb-gateway-in { gap:5px; padding:6px; justify-content:center; }
.hb-gateway-scene.mini .hb-gateway-wall { gap:4px; padding:5px; }
.hb-gateway-scene.mini .hb-gateway-door,.hb-gateway-scene.mini .hb-gateway-buoy { gap:3px; padding:2px 6px 2px 3px; border-width:1.5px; border-radius:9px; box-shadow:0 2px 0 #7a5a2f; }
.hb-gateway-scene.mini .hb-gateway-buoy { box-shadow:0 2px 0 #5aa6c6; }
.hb-gateway-scene.mini .hb-gateway-door b,.hb-gateway-scene.mini .hb-gateway-buoy b { font-size:9px; }
.hb-gateway-scene.mini .hb-chip { font-size:8px; padding:0 3px; }
.hb-gateway-scene.mini .hb-gateway-icon,.hb-gateway-lane.mini .hb-gateway-icon { width:16px; height:16px; }
.hb-gateway-scene.mini .hb-gateway-stop { padding:2px 5px 2px 3px; }
.hb-gateway-scene.mini .hb-gateway-stop-text b { font-size:9px; }
.hb-gateway-scene.mini .hb-gateway-cost { width:14px; height:14px; font-size:8px; line-height:11px; top:-7px; right:-6px; border-width:1.5px; }
.hb-gateway-scene.mini .hb-gateway-closed { font-size:9px; padding:2px 6px; }
.hb-gateway-lane.mini { padding:5px 6px; gap:3px; border-width:1.5px; border-radius:11px; box-shadow:0 2px 0 #b39a62; }
.hb-gateway-lane.mini .hb-gateway-route { justify-content:center; row-gap:6px; }
.hb-gateway-lane.mini .hb-gateway-track { flex:1 1 10px; min-width:10px; max-width:44px; margin:0 2px; }
.hb-gateway-lane.mini .hb-gateway-stop,.hb-gateway-lane.mini .hb-gateway-pod { flex-shrink:0; }
.hb-gateway-lane.mini .hb-gateway-stop-text b,.hb-gateway-lane.mini .hb-gateway-pod b { white-space:nowrap; }
.hb-gateway-lane.mini .hb-gateway-stop { padding:2px 5px 2px 3px; border-width:1.5px; gap:3px; }
.hb-gateway-lane.mini .hb-gateway-stop-text b { font-size:9px; }
.hb-gateway-lane.mini .hb-gateway-stop-text small { display:none; }
.hb-gateway-lane.mini .hb-gateway-pod { padding:2px 5px 2px 2px; border-width:1.5px; gap:3px; box-shadow:0 2px 0 #ab905b; }
.hb-gateway-lane.mini .hb-gateway-stop.block::after { width:13px; height:13px; font-size:8px; line-height:13px; top:-6px; right:-5px; }
.hb-gateway-pod.mini>svg { width:18px; height:21px; }
.hb-gateway-pod.mini b { font-size:9px; }
.hb-gateway-pod.mini.fenced-in::before { top:-8px; height:6px; left:5px; right:5px; }
.hb-gateway-pod.mini.fenced-out::after { bottom:-8px; height:6px; left:5px; right:5px; }
.hb-gateway-minipods { display:flex; justify-content:center; gap:8px; padding-top:6px; }
.hb-gateway-minipods .hb-gateway-pod { padding:3px 7px 3px 3px; }
.hb-gateway-ticket { display:flex; align-items:center; justify-content:center; gap:6px; margin:0 auto; padding:3px 9px 3px 5px; border:2px solid #b59c61; border-radius:11px; background:#fff7d8; box-shadow:0 3px 0 #ab905b; max-width:100%; }
.hb-gateway-ticket code { font:800 9px var(--mono); color:#3f4a38; overflow-wrap:normal; word-break:keep-all; }
.hb-gateway-demo .hb-gateway-signs { margin:0; gap:4px; }
.hb-gateway-demo .hb-gateway-sign { gap:4px; padding:2px 6px 2px 5px; font-size:9px; border-width:1.5px; box-shadow:0 2px 0 #8a6d2f; }
.hb-gateway-demo .hb-gateway-sign code { font-size:9.5px; }
.hb-gateway-demo .hb-gateway-sign small { font-size:8px; padding:0 3px; }
.hb-gateway-demo .hb-gateway-sign.hit { box-shadow:0 2px 0 #4f8a5b,0 0 0 3px #c5e9b4; }
.hb-gateway-nsmap.mini { gap:6px; grid-template-columns:repeat(auto-fit,minmax(min(100%,90px),1fr)); }
.hb-gateway-nsmap.mini.stack { grid-template-columns:minmax(0,1fr); }
.hb-gateway-nsmap.mini.pair { grid-template-columns:minmax(0,1.6fr) minmax(0,1fr); }
.hb-gateway-nsmap.mini .hb-gateway-ns { padding:3px 5px 6px; border-width:1.5px; border-radius:11px; }
.hb-gateway-nsmap.mini .hb-gateway-ns>header { margin:0 2px 5px; font-size:9px; }
.hb-gateway-nsmap.mini .hb-gateway-ns-body { gap:9px 5px; align-items:center; justify-content:center; }
.hb-gateway-demo .hb-gateway-secret,.hb-gateway-demo .hb-gateway-ingress-card { gap:4px; padding:2px 6px 2px 3px; border-width:1.5px; border-radius:9px; box-shadow:0 2px 0 #b8964f; }
.hb-gateway-demo .hb-gateway-ingress-card { box-shadow:0 2px 0 #7a5a2f; }
.hb-gateway-demo .hb-gateway-secret.on { box-shadow:0 2px 0 #4f8a5b,0 0 0 3px #c5e9b4; }
.hb-gateway-demo .hb-gateway-secret.dim { box-shadow:none; }
.hb-gateway-demo .hb-gateway-secret b,.hb-gateway-demo .hb-gateway-ingress-card b { font-size:9px; }
.hb-gateway-demo .hb-gateway-secret small,.hb-gateway-demo .hb-gateway-lookup { font-size:8px; }
.hb-gateway-demo .hb-gateway-icon { width:16px; height:16px; }

@keyframes hb-gateway-draw { from { transform:scaleX(0); } to { transform:scaleX(1); } }
@keyframes hb-gateway-draw-v { from { transform:scaleY(0); } to { transform:scaleY(1); } }
@keyframes hb-gateway-run { 0% { left:-6px; opacity:0; } 12% { opacity:1; } 88% { opacity:1; } 100% { left:calc(100% - 6px); opacity:0; } }
@keyframes hb-gateway-bounce { 0% { left:-6px; opacity:0; } 10% { opacity:1; } 55% { left:calc(100% - 8px); } 100% { left:15%; opacity:0; } }

@media(max-width:440px) {
  /* The demo porthole is narrow: mini lanes run top to bottom so they still read as one path. */
  .hb-gateway-lane.mini .hb-gateway-route { flex-direction:column; flex-wrap:nowrap; row-gap:0; }
  .hb-gateway-lane.mini .hb-gateway-track { flex:0 0 10px; width:4px; height:10px; min-width:0; max-width:none; margin:2px 0; background:repeating-linear-gradient(180deg,#8eaaa4 0 4px,transparent 4px 7px); }
  .hb-gateway-lane.mini .hb-gateway-track::before { transform-origin:top; }
  .hb-gateway-lane.mini.go .hb-gateway-track.pass::before,.hb-gateway-lane.mini.go .hb-gateway-track.fail::before { animation-name:hb-gateway-draw-v; }
  .hb-gateway-lane.mini .hb-gateway-dot { display:none; }
  .hb-gateway-nsmap.mini.pair { grid-template-columns:minmax(0,1fr); }
  .hb-gateway-lane { padding:8px 9px; }
  .hb-gateway-ask>b { font-size:11.5px; flex-basis:100%; }
  .hb-gateway-stop-text b { font-size:10.5px; }
  .hb-gateway-sign { grid-template-columns:minmax(0,1fr) auto; row-gap:2px; }
  .hb-gateway-out,.hb-gateway-in { padding:10px; }
}
