diff --git a/README.md b/README.md
index 69499896270150ef8293127b56b7b81624fdb2a6..520007af0af9e59d04dcc18cd2d6c802c1f7872a 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,7 @@ final readonly class EchoResponder extends WebSocketRPCResponder
         RPCRequest $rpcRequest,
     ): void {
         $webSocketConnection->push(new RPCResponse(
-            $rpcRequest->requestId,
+            $rpcRequest,
             $rpcRequest->payload,
         ));
     }
diff --git a/app/Template/StaticPageLayout/Turbo.php b/app/Template/StaticPageLayout/Turbo.php
index b15cf2478decfbea861e18bca9be432b62691d83..0ed9d79e04ba9634e4dbf0c6acf2906c77a1835f 100644
--- a/app/Template/StaticPageLayout/Turbo.php
+++ b/app/Template/StaticPageLayout/Turbo.php
@@ -73,6 +73,9 @@ abstract readonly class Turbo extends StaticPageLayout
             <meta name="turbo-refresh-method" content="morph">
             <meta name="turbo-refresh-scroll" content="preserve">
             <title>{$staticPage->frontMatter->title}</title>
+            <link rel="preconnect" href="https://fonts.googleapis.com">
+            <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+            <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:wght@100..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&family=Noto+Serif:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
         HTML;
         yield from $this->renderMeta($staticPage);
         yield $renderedPreloads;
diff --git a/docs/pages/docs/features/websockets/protocols.md b/docs/pages/docs/features/websockets/protocols.md
index a702672689862970e8fade0cc6fe52925b4d2f1f..79763e448bee1f966d76ccd69776ea80536ba715 100644
--- a/docs/pages/docs/features/websockets/protocols.md
+++ b/docs/pages/docs/features/websockets/protocols.md
@@ -90,7 +90,7 @@ final readonly class EchoResponder extends WebSocketRPCResponder
         RPCRequest $rpcRequest,
     ): void {
         $webSocketConnection->push(new RPCResponse(
-            $rpcRequest->requestId,
+            $rpcRequest,
             $rpcRequest->payload,
         ));
     }
diff --git a/docs/pages/index.md b/docs/pages/index.md
index f532ee2da56514a1da75f65d86a4ff3094174cbe..ea8919bf3bf334d7fd3d521d943e021b36f9e647 100644
--- a/docs/pages/index.md
+++ b/docs/pages/index.md
@@ -164,7 +164,7 @@ final readonly class EchoResponder extends WebSocketRPCResponder
         RPCRequest $rpcRequest,
     ): void {
         $webSocketConnection->push(new RPCResponse(
-            $rpcRequest->requestId,
+            $rpcRequest,
             $rpcRequest->payload,
         ));
     }
diff --git a/resources/css/docs-common.css b/resources/css/docs-common.css
index d5072db912959f896c94d560b5003fd86446fa17..dbc84f30306bc1f85f850e6addada7e3d3798d08 100644
--- a/resources/css/docs-common.css
+++ b/resources/css/docs-common.css
@@ -18,8 +18,8 @@
   --color-tag-background: transparent;
   --color-tag-border: var(--color-body-font);
   --color-tag-font: var(--color-body-font);
-  --font-family-body: sans-serif;
-  --font-family-serif: Garamond, Georgia, serif;
+  --font-family-body: "Noto Sans", sans-serif;
+  --font-family-serif: "Noto Serif", Garamond, Georgia, serif;
   --font-family-monospace: monospace;
   --height-primary-navigation: 70px;
   --height-aside-filter: 70px;
@@ -29,32 +29,19 @@
   --z-index-documentation-aside-filter: 2;
   --z-index-primary-navigation: 3;
   --z-index-edit-on-github: 4;
-}
 
-@media screen and (max-width: 1023px) {
-  :root {
+  @media screen and (max-height: 1199px) {
     --font-size-base: 18px;
     --font-size-code: 16px;
-    --font-size-code-smaller: 14px;
     --font-size-smaller: 16px;
   }
-}
-@media screen and (min-width: 1024px) {
-  :root {
+  @media screen and (min-height: 1200px) {
     --font-size-base: 20px;
     --font-size-code: 18px;
-    --font-size-code-smaller: 18px;
     --font-size-smaller: 18px;
   }
 }
-@media screen and (min-width: 2000px) {
-  :root {
-    --font-size-base: 22px;
-    --font-size-code: 18px;
-    --font-size-code-smaller: 18px;
-    --font-size-smaller: 20px;
-  }
-}
+
 
 ::-webkit-scrollbar {
   background-color: transparent;
diff --git a/resources/css/docs-page-homepage.css b/resources/css/docs-page-homepage.css
index 0d5e0735e1c83b43a80a9045572db6953d90f86e..80e4cec9d7336c235c84434f12605e09b7d0aad5 100644
--- a/resources/css/docs-page-homepage.css
+++ b/resources/css/docs-page-homepage.css
@@ -27,7 +27,7 @@
     row-gap: 20px;
   }
   @media screen and (min-width: 1024px) {
-    row-gap: 120px;
+    row-gap: 60px;
   }
 }
 
diff --git a/src/Constraint/StringConstraint.php b/src/Constraint/StringConstraint.php
index 85936e32e4897bdef5bc7c019cb1b46339997e8d..1b69eea462aad77823d4be5ab4e76e76d351585b 100644
--- a/src/Constraint/StringConstraint.php
+++ b/src/Constraint/StringConstraint.php
@@ -83,9 +83,10 @@ final readonly class StringConstraint extends Constraint
 
     protected function doValidate(mixed $notValidatedData, ConstraintPath $path): ConstraintResult
     {
-        if (!is_string($notValidatedData) || (!$this->isEmptyAllowed && empty($notValidatedData))) {
+        if (!is_string($notValidatedData) || (!$this->isEmptyAllowed && 0 === strlen($notValidatedData))) {
             return new ConstraintResult(
                 castedData: $notValidatedData,
+                comment: 'Expected string, got '.gettype($notValidatedData),
                 path: $path,
                 reason: ConstraintReason::InvalidDataType,
                 status: ConstraintResultStatus::Invalid,
diff --git a/src/Constraint/TupleConstraintTest.php b/src/Constraint/TupleConstraintTest.php
index 07a87ac0271001e4e03766c06f3252fba87d723e..11ad9521675f335aa97bd64e92ab44cd49c6cd46 100644
--- a/src/Constraint/TupleConstraintTest.php
+++ b/src/Constraint/TupleConstraintTest.php
@@ -13,6 +13,21 @@ use PHPUnit\Framework\TestCase;
 #[CoversClass(TupleConstraint::class)]
 final class TupleConstraintTest extends TestCase
 {
+    public function test_data_is_mapped(): void
+    {
+        $constraint = new TupleConstraint(
+            items: [
+                new StringConstraint(),
+                new NumberConstraint(),
+            ]
+        );
+
+        $validatedResult = $constraint->validate(['hi', 5]);
+
+        self::assertTrue($validatedResult->status->isValid());
+        self::assertEquals(['hi', 5], $validatedResult->castedData);
+    }
+
     public function test_is_converted_optionally_to_json_schema(): void
     {
         $constraint = new TupleConstraint(
diff --git a/src/ConstraintResult.php b/src/ConstraintResult.php
index 88a3c3d29fc4e6bcbf94cd0913a6e4333019bf68..1853c0a791b73da42593b008f69cba6e3d46552b 100644
--- a/src/ConstraintResult.php
+++ b/src/ConstraintResult.php
@@ -17,6 +17,7 @@ readonly class ConstraintResult
         public ConstraintResultStatus $status,
         public ConstraintReason $reason,
         public array $nested = [],
+        public ?string $comment = null,
     ) {}
 
     /**
diff --git a/src/ConstraintResultErrorMessage.php b/src/ConstraintResultErrorMessage.php
index c5a60c193f31b2bec7f1a40ce2918350ecdfc6e7..4dcfce2f68fba61b5bbdb7c47926d14cabcefedf 100644
--- a/src/ConstraintResultErrorMessage.php
+++ b/src/ConstraintResultErrorMessage.php
@@ -19,10 +19,11 @@ readonly class ConstraintResultErrorMessage implements Stringable
             $message[] = sprintf('"%s" -> %s', $name, $errorCode);
         }
 
-        // var_dump($constraintResult->castedData);
-
         $this->message = sprintf(
-            '%s',
+            '%s%s',
+            is_string($constraintResult->comment)
+                ? $constraintResult->comment.":\n"
+                : '',
             implode("\n", $message),
         );
     }
diff --git a/src/InputValidator/RPCMessageValidator.php b/src/InputValidator/RPCMessageValidator.php
index 68cfd78c3dc510beb1df2d174e8f0cee45023fa3..49a731c4bf9342d7cd0521e40d0f6cbdde8f9c77 100644
--- a/src/InputValidator/RPCMessageValidator.php
+++ b/src/InputValidator/RPCMessageValidator.php
@@ -11,7 +11,6 @@ use Distantmagic\Resonance\Constraint\AnyConstraint;
 use Distantmagic\Resonance\Constraint\EnumConstraint;
 use Distantmagic\Resonance\Constraint\StringConstraint;
 use Distantmagic\Resonance\Constraint\TupleConstraint;
-use Distantmagic\Resonance\ConstraintStringFormat;
 use Distantmagic\Resonance\Feature;
 use Distantmagic\Resonance\InputValidatedData\RPCMessage;
 use Distantmagic\Resonance\InputValidator;
@@ -46,7 +45,7 @@ readonly class RPCMessageValidator extends InputValidator
             items: [
                 new EnumConstraint($this->rpcMethodValidator->values()),
                 new AnyConstraint(),
-                (new StringConstraint(format: ConstraintStringFormat::Uuid))->nullable(),
+                (new StringConstraint())->nullable(),
             ],
         );
     }
diff --git a/src/RPCResponse.php b/src/RPCResponse.php
index a25f63fb2be3ae606623c2575c1ef731bced407c..15d1a8e9a03f86cd6f29bb8510198f0044fe154e 100644
--- a/src/RPCResponse.php
+++ b/src/RPCResponse.php
@@ -9,15 +9,16 @@ use Stringable;
 readonly class RPCResponse implements Stringable
 {
     public function __construct(
-        private string $requestId,
+        private RPCRequest $rpcRequest,
         private mixed $content,
     ) {}
 
     public function __toString(): string
     {
         return json_encode([
-            $this->requestId,
+            $this->rpcRequest->method,
             $this->content,
+            $this->rpcRequest->requestId,
         ]);
     }
 }