proxilion 0.0.2__tar.gz → 0.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. {proxilion-0.0.2 → proxilion-0.0.3}/PKG-INFO +6 -6
  2. {proxilion-0.0.2 → proxilion-0.0.3}/README.md +5 -5
  3. {proxilion-0.0.2 → proxilion-0.0.3}/marketing-site/grc.html +163 -0
  4. {proxilion-0.0.2 → proxilion-0.0.3}/marketing-site/index.html +462 -125
  5. {proxilion-0.0.2 → proxilion-0.0.3}/marketing-site/mcp.html +159 -0
  6. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/compliance/base.py +4 -4
  7. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/compliance/eu_ai_act.py +14 -4
  8. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/compliance/iso27001.py +2 -2
  9. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/compliance/soc2.py +16 -3
  10. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/events.py +9 -5
  11. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/explainability.py +30 -19
  12. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/hash_chain.py +14 -0
  13. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/caching/tool_cache.py +14 -8
  14. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/context/context_window.py +27 -2
  15. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/contrib/mcp.py +2 -1
  16. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/core.py +26 -21
  17. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/exceptions.py +84 -0
  18. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/guards/output_guard.py +1 -1
  19. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/observability/__init__.py +3 -1
  20. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/observability/metrics.py +14 -6
  21. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/observability/session_cost_tracker.py +6 -7
  22. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/policies/builtin.py +2 -1
  23. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/policies/registry.py +12 -6
  24. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/__init__.py +51 -37
  25. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/agent_trust.py +23 -8
  26. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/behavioral_drift.py +14 -6
  27. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/idor_protection.py +12 -4
  28. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/intent_capsule.py +3 -2
  29. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/intent_validator.py +89 -2
  30. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/memory_integrity.py +14 -13
  31. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/rate_limiter.py +112 -22
  32. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/timeouts/manager.py +2 -0
  33. {proxilion-0.0.2 → proxilion-0.0.3}/pyproject.toml +1 -1
  34. {proxilion-0.0.2 → proxilion-0.0.3}/tests/conftest.py +17 -16
  35. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_audit.py +27 -10
  36. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_caching.py +6 -6
  37. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_cascade_protection.py +3 -6
  38. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_cloud_exporters.py +28 -14
  39. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_compliance_exporters.py +15 -16
  40. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_context_window.py +10 -4
  41. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_core.py +3 -4
  42. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_cost_limiter.py +11 -6
  43. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_cost_tracker.py +6 -8
  44. proxilion-0.0.3/tests/test_engines/__init__.py +0 -0
  45. proxilion-0.0.3/tests/test_engines/test_factory.py +163 -0
  46. proxilion-0.0.3/tests/test_engines/test_opa_engine.py +201 -0
  47. proxilion-0.0.3/tests/test_engines/test_simple_engine.py +210 -0
  48. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_google_integration.py +9 -9
  49. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_guards.py +15 -13
  50. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_integrations/test_anthropic.py +15 -11
  51. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_integrations/test_langchain.py +8 -11
  52. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_integrations/test_mcp.py +6 -7
  53. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_integrations/test_openai.py +2 -6
  54. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_message_history.py +1 -4
  55. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_observability_hooks.py +32 -23
  56. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_policies.py +3 -3
  57. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_providers.py +14 -18
  58. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_resilience.py +15 -22
  59. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_scheduling.py +8 -10
  60. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_scope_enforcer.py +19 -11
  61. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_security/test_circuit_breaker.py +10 -14
  62. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_security/test_idor.py +0 -3
  63. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_security/test_rate_limiter.py +3 -6
  64. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_sequence_validator.py +4 -8
  65. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_session.py +7 -9
  66. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_streaming.py +11 -13
  67. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_timeouts.py +17 -17
  68. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_tool_registry.py +19 -18
  69. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_trust_boundaries.py +1 -2
  70. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_validation.py +26 -12
  71. {proxilion-0.0.2 → proxilion-0.0.3}/.gitignore +0 -0
  72. {proxilion-0.0.2 → proxilion-0.0.3}/LICENSE +0 -0
  73. {proxilion-0.0.2 → proxilion-0.0.3}/docs/concepts.md +0 -0
  74. {proxilion-0.0.2 → proxilion-0.0.3}/docs/features/README.md +0 -0
  75. {proxilion-0.0.2 → proxilion-0.0.3}/docs/features/authorization.md +0 -0
  76. {proxilion-0.0.2 → proxilion-0.0.3}/docs/quickstart.md +0 -0
  77. {proxilion-0.0.2 → proxilion-0.0.3}/docs/security.md +0 -0
  78. {proxilion-0.0.2 → proxilion-0.0.3}/marketing-site/apple-touch-icon.png +0 -0
  79. {proxilion-0.0.2 → proxilion-0.0.3}/marketing-site/favicon-16x16.png +0 -0
  80. {proxilion-0.0.2 → proxilion-0.0.3}/marketing-site/favicon-32x32.png +0 -0
  81. {proxilion-0.0.2 → proxilion-0.0.3}/marketing-site/favicon.ico +0 -0
  82. {proxilion-0.0.2 → proxilion-0.0.3}/marketing-site/og-image.png +0 -0
  83. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/__init__.py +0 -0
  84. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/__init__.py +15 -15
  85. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/base_exporters.py +0 -0
  86. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/compliance/__init__.py +0 -0
  87. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/exporters/__init__.py +0 -0
  88. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/exporters/aws_s3.py +0 -0
  89. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/exporters/azure_storage.py +0 -0
  90. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/exporters/cloud_base.py +0 -0
  91. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/exporters/gcp_storage.py +0 -0
  92. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/exporters/multi_exporter.py +0 -0
  93. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/audit/logger.py +0 -0
  94. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/caching/__init__.py +0 -0
  95. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/context/__init__.py +0 -0
  96. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/context/message_history.py +0 -0
  97. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/context/session.py +0 -0
  98. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/contrib/__init__.py +0 -0
  99. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/contrib/anthropic.py +2 -2
  100. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/contrib/google.py +0 -0
  101. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/contrib/langchain.py +0 -0
  102. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/contrib/openai.py +2 -2
  103. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/decorators.py +0 -0
  104. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/engines/__init__.py +0 -0
  105. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/engines/base.py +0 -0
  106. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/engines/casbin_engine.py +0 -0
  107. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/engines/opa_engine.py +0 -0
  108. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/engines/simple.py +0 -0
  109. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/guards/__init__.py +0 -0
  110. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/guards/input_guard.py +0 -0
  111. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/observability/cost_tracker.py +0 -0
  112. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/observability/hooks.py +0 -0
  113. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/policies/__init__.py +0 -0
  114. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/policies/base.py +0 -0
  115. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/providers/__init__.py +0 -0
  116. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/providers/adapter.py +0 -0
  117. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/providers/anthropic_adapter.py +0 -0
  118. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/providers/gemini_adapter.py +0 -0
  119. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/providers/openai_adapter.py +0 -0
  120. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/py.typed +0 -0
  121. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/resilience/__init__.py +0 -0
  122. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/resilience/degradation.py +0 -0
  123. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/resilience/fallback.py +0 -0
  124. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/resilience/retry.py +0 -0
  125. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/scheduling/__init__.py +0 -0
  126. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/scheduling/priority_queue.py +0 -0
  127. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/scheduling/scheduler.py +0 -0
  128. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/cascade_protection.py +0 -0
  129. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/circuit_breaker.py +0 -0
  130. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/cost_limiter.py +0 -0
  131. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/scope_enforcer.py +0 -0
  132. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/sequence_validator.py +0 -0
  133. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/security/trust_boundaries.py +0 -0
  134. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/streaming/__init__.py +0 -0
  135. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/streaming/detector.py +0 -0
  136. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/streaming/transformer.py +0 -0
  137. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/timeouts/__init__.py +0 -0
  138. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/timeouts/decorators.py +0 -0
  139. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/tools/__init__.py +0 -0
  140. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/tools/decorators.py +0 -0
  141. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/tools/registry.py +0 -0
  142. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/types.py +0 -0
  143. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/validation/__init__.py +0 -0
  144. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/validation/pydantic_schema.py +0 -0
  145. {proxilion-0.0.2 → proxilion-0.0.3}/proxilion/validation/schema.py +0 -0
  146. {proxilion-0.0.2 → proxilion-0.0.3}/tests/__init__.py +0 -0
  147. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_integrations/__init__.py +0 -0
  148. {proxilion-0.0.2 → proxilion-0.0.3}/tests/test_security/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proxilion
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: Application-layer security SDK for LLM tool call authorization
5
5
  Project-URL: Homepage, https://proxilion.com
6
6
  Project-URL: Documentation, https://proxilion.com
@@ -290,11 +290,11 @@ if limiter.allow_request("user_123"):
290
290
  limiter = SlidingWindowRateLimiter(max_requests=100, window_seconds=60)
291
291
 
292
292
  # Multi-dimensional (user + IP + tool)
293
- limiter = MultiDimensionalRateLimiter(configs=[
294
- RateLimitConfig(dimension="user", capacity=100, refill_rate=10),
295
- RateLimitConfig(dimension="ip", capacity=1000, refill_rate=100),
296
- RateLimitConfig(dimension="tool", capacity=50, refill_rate=5),
297
- ])
293
+ limiter = MultiDimensionalRateLimiter(limits={
294
+ "user": RateLimitConfig(capacity=100, refill_rate=10),
295
+ "ip": RateLimitConfig(capacity=1000, refill_rate=100),
296
+ "tool": RateLimitConfig(capacity=50, refill_rate=5),
297
+ })
298
298
  ```
299
299
 
300
300
  **Deterministic**: Counter-based algorithms with configurable thresholds.
@@ -248,11 +248,11 @@ if limiter.allow_request("user_123"):
248
248
  limiter = SlidingWindowRateLimiter(max_requests=100, window_seconds=60)
249
249
 
250
250
  # Multi-dimensional (user + IP + tool)
251
- limiter = MultiDimensionalRateLimiter(configs=[
252
- RateLimitConfig(dimension="user", capacity=100, refill_rate=10),
253
- RateLimitConfig(dimension="ip", capacity=1000, refill_rate=100),
254
- RateLimitConfig(dimension="tool", capacity=50, refill_rate=5),
255
- ])
251
+ limiter = MultiDimensionalRateLimiter(limits={
252
+ "user": RateLimitConfig(capacity=100, refill_rate=10),
253
+ "ip": RateLimitConfig(capacity=1000, refill_rate=100),
254
+ "tool": RateLimitConfig(capacity=50, refill_rate=5),
255
+ })
256
256
  ```
257
257
 
258
258
  **Deterministic**: Counter-based algorithms with configurable thresholds.
@@ -509,12 +509,135 @@
509
509
  flex-wrap: wrap;
510
510
  }
511
511
 
512
+ /* Mobile Menu Toggle */
513
+ .mobile-menu-toggle {
514
+ display: none;
515
+ flex-direction: column;
516
+ justify-content: center;
517
+ align-items: center;
518
+ width: 44px;
519
+ height: 44px;
520
+ background: transparent;
521
+ border: none;
522
+ cursor: pointer;
523
+ padding: 8px;
524
+ margin-right: -8px;
525
+ border-radius: 8px;
526
+ transition: background var(--transition-fast);
527
+ }
528
+
529
+ .mobile-menu-toggle:hover {
530
+ background: rgba(255, 255, 255, 0.05);
531
+ }
532
+
533
+ .mobile-menu-toggle span {
534
+ display: block;
535
+ width: 22px;
536
+ height: 2px;
537
+ background: var(--text);
538
+ border-radius: 2px;
539
+ transition: all var(--transition-fast);
540
+ }
541
+
542
+ .mobile-menu-toggle span:nth-child(1) {
543
+ margin-bottom: 5px;
544
+ }
545
+
546
+ .mobile-menu-toggle span:nth-child(3) {
547
+ margin-top: 5px;
548
+ }
549
+
550
+ .mobile-menu-toggle.active span:nth-child(1) {
551
+ transform: rotate(45deg) translate(5px, 5px);
552
+ }
553
+
554
+ .mobile-menu-toggle.active span:nth-child(2) {
555
+ opacity: 0;
556
+ }
557
+
558
+ .mobile-menu-toggle.active span:nth-child(3) {
559
+ transform: rotate(-45deg) translate(5px, -5px);
560
+ }
561
+
562
+ /* Mobile Menu */
563
+ .mobile-menu {
564
+ display: none;
565
+ position: fixed;
566
+ top: 73px;
567
+ left: 0;
568
+ right: 0;
569
+ background: rgba(0, 0, 0, 0.98);
570
+ backdrop-filter: blur(20px);
571
+ -webkit-backdrop-filter: blur(20px);
572
+ border-bottom: 1px solid var(--border);
573
+ padding: 20px 24px 28px;
574
+ z-index: 999;
575
+ animation: slideDown 0.3s ease-out;
576
+ }
577
+
578
+ @keyframes slideDown {
579
+ from { opacity: 0; transform: translateY(-10px); }
580
+ to { opacity: 1; transform: translateY(0); }
581
+ }
582
+
583
+ .mobile-menu.active {
584
+ display: block;
585
+ }
586
+
587
+ .mobile-menu-links {
588
+ list-style: none;
589
+ display: flex;
590
+ flex-direction: column;
591
+ gap: 8px;
592
+ margin-bottom: 20px;
593
+ }
594
+
595
+ .mobile-menu-links a {
596
+ display: block;
597
+ padding: 14px 16px;
598
+ color: var(--text-muted);
599
+ text-decoration: none;
600
+ font-weight: 500;
601
+ font-size: 1rem;
602
+ border-radius: 10px;
603
+ transition: all var(--transition-fast);
604
+ }
605
+
606
+ .mobile-menu-links a:hover,
607
+ .mobile-menu-links a.active {
608
+ color: var(--text);
609
+ background: rgba(255, 255, 255, 0.05);
610
+ }
611
+
612
+ .mobile-menu-cta {
613
+ display: flex;
614
+ align-items: center;
615
+ justify-content: center;
616
+ gap: 8px;
617
+ width: 100%;
618
+ padding: 14px 20px;
619
+ background: var(--accent);
620
+ border-radius: 10px;
621
+ color: #000;
622
+ text-decoration: none;
623
+ font-weight: 600;
624
+ font-size: 0.95rem;
625
+ }
626
+
512
627
  /* Responsive */
513
628
  @media (max-width: 768px) {
514
629
  .nav-links {
515
630
  display: none;
516
631
  }
517
632
 
633
+ .nav-cta {
634
+ display: none;
635
+ }
636
+
637
+ .mobile-menu-toggle {
638
+ display: flex;
639
+ }
640
+
518
641
  .stats-banner {
519
642
  grid-template-columns: repeat(2, 1fr);
520
643
  }
@@ -556,9 +679,26 @@
556
679
  <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
557
680
  GitHub
558
681
  </a>
682
+ <button class="mobile-menu-toggle" aria-label="Toggle menu" aria-expanded="false">
683
+ <span></span>
684
+ <span></span>
685
+ <span></span>
686
+ </button>
559
687
  </div>
560
688
  </nav>
561
689
 
690
+ <div class="mobile-menu">
691
+ <ul class="mobile-menu-links">
692
+ <li><a href="/">SDK</a></li>
693
+ <li><a href="mcp.html">MCP Gateway</a></li>
694
+ <li><a href="grc.html" class="active">GRC</a></li>
695
+ </ul>
696
+ <a href="https://github.com/clay-good/proxilion-grc" class="mobile-menu-cta" target="_blank" rel="noopener">
697
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
698
+ GitHub
699
+ </a>
700
+ </div>
701
+
562
702
  <div class="container">
563
703
  <header>
564
704
  <div class="badge">
@@ -754,5 +894,28 @@
754
894
  </p>
755
895
  </footer>
756
896
  </div>
897
+
898
+ <script>
899
+ // Mobile menu toggle
900
+ const menuToggle = document.querySelector('.mobile-menu-toggle');
901
+ const mobileMenu = document.querySelector('.mobile-menu');
902
+
903
+ menuToggle.addEventListener('click', () => {
904
+ const isActive = menuToggle.classList.toggle('active');
905
+ mobileMenu.classList.toggle('active');
906
+ menuToggle.setAttribute('aria-expanded', isActive);
907
+ document.body.style.overflow = isActive ? 'hidden' : '';
908
+ });
909
+
910
+ // Close menu when clicking a link
911
+ mobileMenu.querySelectorAll('a').forEach(link => {
912
+ link.addEventListener('click', () => {
913
+ menuToggle.classList.remove('active');
914
+ mobileMenu.classList.remove('active');
915
+ menuToggle.setAttribute('aria-expanded', 'false');
916
+ document.body.style.overflow = '';
917
+ });
918
+ });
919
+ </script>
757
920
  </body>
758
921
  </html>