/* ==========================================================================
   OSI Fiber – shared animated fiber-optic background component
   Include on every page:  <link rel="stylesheet" href="/assets/fiber.css">
                           <script src="/assets/fiber.js" defer></script>
   Mark up sections with data-fiber-section (optional data-fiber-lane="left|right")
   and any card the fiber should "plug into" with data-fiber-node.
   ========================================================================== */
:root{
  --fiber-a:#29b6e8;          /* aqua strand (multimode jacket colour) */
  --fiber-b:#ffd200;          /* yellow strand (single-mode jacket colour) */
  --fiber-jacket:rgba(10,51,80,.16);
  --fiber-strand-opacity:.55;
  --fiber-glow-opacity:.10;
}
body.has-fiber{position:relative}
.fiber-layer{position:absolute;left:0;top:0;width:100%;z-index:1;pointer-events:none;overflow:visible}
/* content that must sit above the fiber */
.fiber-above,[data-fiber-section] > .wrap{position:relative;z-index:2}
.fiber-layer .jacket{fill:none;stroke:var(--fiber-jacket);stroke-width:6;stroke-linecap:round}
.fiber-layer .glow{fill:none;stroke-width:12;stroke-linecap:round;opacity:var(--fiber-glow-opacity)}
.fiber-layer .strand{fill:none;stroke-width:2;stroke-linecap:round;opacity:var(--fiber-strand-opacity)}
.fiber-layer .a{stroke:var(--fiber-a)} .fiber-layer .b{stroke:var(--fiber-b)}
.fiber-layer .branch.strand{stroke-width:1.6;opacity:.5}
.fiber-layer .branch.glow{stroke-width:8}
.fiber-layer .port{fill:#04192a;stroke:var(--fiber-a);stroke-width:1.6}
.fiber-layer .port-glow{fill:var(--fiber-a);opacity:.35;transform-box:fill-box;transform-origin:center;animation:fiber-breathe 2.8s ease-in-out infinite}
.fiber-layer .end-cap{fill:var(--fiber-a);opacity:.9}
@keyframes fiber-breathe{0%,100%{opacity:.15;transform:scale(.8)}50%{opacity:.55;transform:scale(1.25)}}
/* feeder strands sit behind text, so keep them quiet */
.fiber-layer .feeder.strand{stroke-width:1.4;opacity:.32}
.fiber-layer .feeder.glow{stroke-width:8;opacity:.06}
.fiber-layer .feeder-pulse{opacity:.75}
/* element the fiber starts from (e.g. the logo): flashes as each pulse leaves it */
.fiber-beat{animation:fiber-logo-beat var(--fiber-beat,2.8s) linear infinite}
@keyframes fiber-logo-beat{
  0%{box-shadow:0 0 0 2px rgba(255,255,255,.9),0 0 34px 6px rgba(41,182,232,.95)}
  18%{box-shadow:0 0 0 1px rgba(41,182,232,.7),0 0 22px 2px rgba(41,182,232,.55)}
  100%{box-shadow:0 0 0 1px rgba(41,182,232,.55),0 0 16px rgba(41,182,232,.3)}}
/* reduced motion: no travelling light, a steady lit fibre instead */
@media (prefers-reduced-motion:reduce){
  .fiber-layer .pulse{display:none}
  .fiber-layer .port-glow{animation:none;opacity:.4}
  .fiber-beat{animation:none}
  .fiber-layer .strand{opacity:.8}
  .fiber-layer .glow{opacity:.2}
}
.fiber-static .strand{opacity:.8}.fiber-static .glow{opacity:.2}
/* small screens: thinner, quieter */
@media (max-width:700px){
  .fiber-layer .jacket{stroke-width:4}
  .fiber-layer .glow{stroke-width:8}
  .fiber-layer .strand{stroke-width:1.6}
}
@media print{.fiber-layer{display:none}}
