/* ===== v2027 · OSI stage — DOM glass bands (canvas draws only the packets) =====
   The 7 layers are real DOM so we get: backdrop-filter glass, CSS spring hover,
   native click/hover targets, and free responsive reflow. The <canvas id="osi">
   sits ABOVE these (z-index 2, pointer-events:none) and paints only the flowing
   packet stream + trails + the periodic encapsulation "hero" packet.
   Per-band accent colour comes in via inline `--lc`. */

.osi-stage {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 50%;   /* right half — office occupies left */
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 96px 14px 78px 0;     /* clear top bar + header nav row + bottom hud */
    pointer-events: none;          /* only chips/bands re-enable below */
}

/* ===== Virtual office (left half) — Gather-style 2D room, desktop only ===== */
.office-stage {
    position: fixed;
    top: 0; left: 0; bottom: 0; right: 50%;
    z-index: 1;
    padding: 96px 14px 78px 22px;
    pointer-events: none;
    display: flex;
    align-items: center;
    justify-content: center;
}
.office-stage #office {
    width: 100%;
    height: 100%;
    max-width: 1120px;
    pointer-events: auto;
    touch-action: manipulation;   /* kill 300ms tap delay / double-tap zoom */
    border-radius: 16px;
    border: 1px solid rgba(120, 150, 230, 0.14);
    box-shadow: 0 20px 60px -24px rgba(0, 0, 0, 0.6),
                inset 0 0 0 1px rgba(255, 255, 255, 0.02);
}

/* ===== Footer dashed rule (spans full width above bottom hud) ===== */
.app-foot-rule {
    position: fixed;
    left: var(--pad); right: var(--pad);
    bottom: 46px;
    z-index: 3;
    border-top: 1px dashed rgba(111, 214, 255, 0.18);
    pointer-events: none;
}

.osi-rack {
    pointer-events: none;
    width: 100%;
    max-width: 1120px;                         /* fills the right half */
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: clamp(6px, 1.1vh, 14px);
    padding: 0 40px;               /* data lanes (slimmer = wider faceplates) */
}

/* ---- endpoints (client top / server bottom) ---- */
.osi-end {
    pointer-events: none;
    flex: 0 0 auto;
    display: flex; align-items: center; gap: 9px;
    font: 700 11px var(--font-mono);
    letter-spacing: 0.08em;
    color: var(--fg-dim);
    padding: 2px 4px;
}
.osi-end b { color: var(--fg); }
.osi-end span:last-child { font-weight: 400; opacity: 0.7; text-transform: none; letter-spacing: 0; }
.osi-end-top { justify-content: flex-start; }
.osi-end-bot { justify-content: flex-end; }
.oe-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 10px var(--accent);
    animation: oeBlink 2.4s ease-in-out infinite;
}
@keyframes oeBlink { 0%,100%{opacity:1} 50%{opacity:0.35} }

/* ---- a band ---- */
/* ---- server-rack 1U faceplate (still an OSI layer band) ---- */
.osi-band {
    position: relative;
    flex: 1 1 0; min-height: 0;
    display: flex; align-items: center;
    gap: 14px;
    padding: 8px 16px 8px 28px;          /* extra left for rail + screws */
    border-radius: 5px;                  /* squared rack faceplate */
    background:
        repeating-linear-gradient(0deg, rgba(255,255,255,0.016) 0 1px, transparent 1px 3px), /* brushed metal */
        linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.006) 14%, rgba(0,0,0,0.16)),
        linear-gradient(135deg, rgba(34,44,70,0.5), rgba(12,18,34,0.6));
    border: 1px solid rgba(120,150,230,0.16);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.07),   /* top bevel */
                inset 0 -1px 0 rgba(0,0,0,0.35),         /* bottom shade */
                inset 0 0 0 1px rgba(0,0,0,0.12);
    backdrop-filter: blur(11px) saturate(135%);
    -webkit-backdrop-filter: blur(11px) saturate(135%);
    overflow: hidden;
    cursor: pointer;
    pointer-events: auto;
    transition: transform 0.5s cubic-bezier(0.22,1,0.36,1),
                border-color 0.35s ease, box-shadow 0.45s ease,
                opacity 0.4s ease, filter 0.4s ease, background 0.35s ease;
}

/* mounting screws at the 4 corners */
.osi-band::after {
    content: "";
    position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    background:
        radial-gradient(circle 2.4px at 10px 9px,  rgba(0,0,0,0.6) 38%, rgba(255,255,255,0.12) 66%, transparent 70%),
        radial-gradient(circle 2.4px at calc(100% - 10px) 9px,  rgba(0,0,0,0.6) 38%, rgba(255,255,255,0.12) 66%, transparent 70%),
        radial-gradient(circle 2.4px at 10px calc(100% - 9px),  rgba(0,0,0,0.6) 38%, rgba(255,255,255,0.12) 66%, transparent 70%),
        radial-gradient(circle 2.4px at calc(100% - 10px) calc(100% - 9px), rgba(0,0,0,0.6) 38%, rgba(255,255,255,0.12) 66%, transparent 70%);
}

/* ambient breathing glow — always pulsing (cheap: opacity on a pseudo) */
.osi-band::before {
    content: "";
    position: absolute; inset: 0;
    border-radius: inherit;
    background: radial-gradient(130% 120% at 0% 50%,
        color-mix(in srgb, var(--lc) 26%, transparent), transparent 62%);
    opacity: 0.06;
    animation: bandBreath 5.5s ease-in-out infinite;
    animation-delay: var(--bd, 0s);
    pointer-events: none;
}
@keyframes bandBreath { 0%,100%{opacity:0.05} 50%{opacity:0.20} }

/* a packet sweeping past lights the band (toggled from JS) */
.osi-band.is-pulse {
    border-color: color-mix(in srgb, var(--lc) 65%, transparent);
    box-shadow: 0 0 30px -4px color-mix(in srgb, var(--lc) 55%, transparent);
}
.osi-band.is-pulse::before { opacity: 0.42; transition: opacity 0.1s ease; }

/* left edge = power rail; a status LED rides on top */
.ob-rail {
    position: absolute; left: 0; top: 0; bottom: 0;
    width: 5px; border-radius: 0;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--lc) 38%, transparent),
        color-mix(in srgb, var(--lc) 10%, transparent));
    box-shadow: inset -1px 0 0 rgba(0,0,0,0.4);
}
.ob-rail::after {                         /* status LED */
    content: ""; position: absolute;
    left: 9px; top: 11px; width: 5px; height: 5px; border-radius: 50%;
    background: var(--lc);
    box-shadow: 0 0 7px color-mix(in srgb, var(--lc) 95%, transparent),
                inset 0 0 0 1px rgba(255,255,255,0.25);
    animation: ledBlink 3.2s steps(1) infinite;
    animation-delay: var(--bd, 0s);
}
@keyframes ledBlink { 0%,92%{opacity:1} 96%{opacity:0.35} }
/* engraved rack-unit number plate */
.ob-num {
    flex: 0 0 auto;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border-radius: 3px;
    font: 700 15px var(--font-mono);
    color: color-mix(in srgb, var(--lc) 92%, white 8%);
    background: linear-gradient(180deg, rgba(0,0,0,0.42), rgba(0,0,0,0.16));
    border: 1px solid rgba(255,255,255,0.07);
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.6), inset 0 -1px 0 rgba(255,255,255,0.05),
                0 0 6px color-mix(in srgb, var(--lc) 22%, transparent);
    text-shadow: 0 0 6px color-mix(in srgb, var(--lc) 55%, transparent);
}
.ob-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; justify-content: center; }
.ob-head { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.ob-name { font: 600 15px var(--font-sans); color: var(--fg); white-space: nowrap; }
.ob-pt   { font: 400 12px var(--font-sans); color: var(--fg-dim); white-space: nowrap; }
.ob-proto {
    font: 400 11px var(--font-mono); color: var(--fg-dim); opacity: 0.7;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* PDU = a port/label tag riveted on the faceplate */
.ob-pdu {
    flex: 0 0 auto;
    align-self: center;
    font: 700 10px var(--font-mono); letter-spacing: 0.08em;
    color: color-mix(in srgb, var(--lc) 95%, white 5%);
    padding: 4px 9px; border-radius: 3px;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--lc) 16%, transparent),
        color-mix(in srgb, var(--lc) 7%, rgba(0,0,0,0.2)));
    border: 1px solid color-mix(in srgb, var(--lc) 42%, transparent);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), inset 0 -1px 2px rgba(0,0,0,0.3);
}

/* ---- node chips ---- */
.ob-chips { display: flex; flex-wrap: wrap; gap: 6px; overflow: hidden; max-height: 26px; }
.ob-chip {
    pointer-events: auto;
    display: inline-flex; align-items: center; gap: 7px;
    padding: 3px 10px 3px 8px;
    border-radius: 8px;
    font: 500 11.5px var(--font-sans);
    color: var(--fg-dim);
    background: rgba(255,255,255,0.03);
    border: 1px solid transparent;
    cursor: pointer; white-space: nowrap;
    transition: transform 0.4s cubic-bezier(0.34,1.56,0.64,1),
                color 0.25s, background 0.25s, border-color 0.25s, box-shadow 0.3s;
}
.ob-chip .dot {
    width: 7px; height: 7px; border-radius: 50%;
    border: 1.5px solid color-mix(in srgb, var(--lc) 85%, transparent);
    flex: 0 0 auto;
}
.ob-chip.is-primary {
    color: var(--fg); font-weight: 700;
    background: color-mix(in srgb, var(--lc) 11%, transparent);
}
.ob-chip.is-primary .dot {
    background: var(--lc); border-color: var(--lc);
    box-shadow: 0 0 8px color-mix(in srgb, var(--lc) 90%, transparent);
}
.ob-chip:hover {
    transform: translateY(-2px) scale(1.05);
    color: var(--fg);
    background: color-mix(in srgb, var(--lc) 17%, transparent);
    border-color: color-mix(in srgb, var(--lc) 55%, transparent);
    box-shadow: 0 6px 18px -6px color-mix(in srgb, var(--lc) 60%, transparent);
}

/* ---- hover / focus on a band ---- */
.osi-band:hover {
    transform: translateX(4px) scale(1.012);
    border-color: color-mix(in srgb, var(--lc) 50%, transparent);
    box-shadow: 0 10px 34px -10px color-mix(in srgb, var(--lc) 45%, transparent);
}
.osi-rack.has-focus .osi-band { opacity: 0.38; filter: saturate(0.7); }
.osi-rack.has-focus .osi-band.is-focused {
    opacity: 1; filter: none;
    transform: translateX(6px) scale(1.02);
    border-color: color-mix(in srgb, var(--lc) 70%, transparent);
    box-shadow: 0 12px 44px -10px color-mix(in srgb, var(--lc) 55%, transparent);
}

/* ---- responsive ----
   tablets (641–900): the virtual office takes the whole viewport — the OSI
   rack ("camadas") hides. Phones (≤640) flip it: rack only, office hidden. */
@media (max-width: 900px) {
    .app-foot-rule { display: none; }
    .office-stage { left: 0; right: 0; padding: 88px 12px 64px; }
    /* rack hidden here; ≤640 flips it back on full width */
    .osi-stage { display: none; left: 0; padding: 96px 0 64px; }
    .osi-rack  { width: min(560px, calc(100vw - 20px)); padding: 0 22px; gap: 5px; }
    .osi-band  { gap: 10px; padding: 7px 12px 7px 16px; border-radius: 12px; }
    .ob-num    { width: 26px; height: 26px; font-size: 13px; }
    .ob-name   { font-size: 13.5px; }
    .ob-pt     { display: none; }
    .ob-proto  { font-size: 10px; }
    .ob-chips  { max-height: 24px; gap: 5px; }
    .ob-chip   { font-size: 11px; padding: 3px 8px; }
}
@media (max-width: 640px) {
    .office-stage { display: none; }       /* phones = rack only */
    .osi-stage { display: flex; padding: 92px 0 16px; }   /* bottom hud hidden on touch */
    .ob-proto  { display: none; }          /* keep header to name + pdu */
    .ob-chips  { max-height: 23px; }
    .ob-chip:not(.is-primary) { display: none; }   /* primary chip only; rest live in panel */
    .ob-pdu    { font-size: 9px; padding: 3px 7px; }
}
@media (min-width: 2200px) {
    .osi-rack { max-width: 1320px; padding: 0 56px; }
    .ob-name  { font-size: 18px; }
    .ob-num   { width: 38px; height: 38px; font-size: 18px; }
    .ob-chip  { font-size: 14px; }
}

@media (prefers-reduced-motion: reduce) {
    .osi-band::before, .oe-dot { animation: none; }
}
