From a010660849255c68babee8e4b5afedbcd71d57a2 Mon Sep 17 00:00:00 2001 From: v0 Date: Thu, 9 Jul 2026 13:00:23 +0000 Subject: [PATCH 1/2] feat: enhance changelog and docs page styling and structure Co-authored-by: Harshil Gupta <144909381+hars-21@users.noreply.github.com> --- src/app/changelog/page.tsx | 63 ++-- src/app/docs/page.tsx | 207 ++++++-------- src/app/globals.css | 183 ++++-------- src/app/install/page.tsx | 94 +++--- src/app/layout.tsx | 31 +- src/app/not-found.tsx | 23 +- src/app/page.tsx | 475 ++++++++++++++++--------------- src/components/code-block.tsx | 16 +- src/components/footer.tsx | 74 +++-- src/components/nav.tsx | 35 ++- src/components/terminal-demo.tsx | 72 +++-- 11 files changed, 612 insertions(+), 661 deletions(-) diff --git a/src/app/changelog/page.tsx b/src/app/changelog/page.tsx index 6268aea..bbf5ffe 100644 --- a/src/app/changelog/page.tsx +++ b/src/app/changelog/page.tsx @@ -1,4 +1,5 @@ import type { Metadata } from 'next'; +import { ArrowUpRight } from 'lucide-react'; export const metadata: Metadata = { title: "What's New", @@ -56,7 +57,10 @@ function renderInline(text: string): React.ReactNode { return parts.map((part, i) => { if (part.startsWith('`') && part.endsWith('`')) { return ( - + {part.slice(1, -1)} ); @@ -74,37 +78,45 @@ export default async function ChangelogPage() { return (
-
-
-

- What's New +
+
+

Changelog

+

+ What's new

-

+

Every release of reqsh, from the latest features to the smallest fixes.

-
+
{releases.map((release, i) => ( -
-
-

+
+
+

v{release.version}

{i === 0 && ( - + Latest )} +
- -
    +
      {release.items.map((item, j) => ( -
    • - {renderInline(item)} +
    • +
    • ))}
    @@ -112,26 +124,15 @@ export default async function ChangelogPage() { ))}

- diff --git a/src/app/docs/page.tsx b/src/app/docs/page.tsx index c1d7273..85b9edb 100644 --- a/src/app/docs/page.tsx +++ b/src/app/docs/page.tsx @@ -8,28 +8,41 @@ export const metadata: Metadata = { 'Getting started with reqsh - learn how to install, configure and send HTTP requests from your terminal.', }; +function InlineCode({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} + export default function DocsPage() { return (
-
-
-

Documentation

-

- Master the interactive HTTP shell. Learn how to install, configure your environment, and - execute requests efficiently. +

+
+

Guide

+

+ Documentation +

+

+ Learn how to install reqsh, configure your session, and send requests efficiently — + all from the comfort of your terminal.

-
-

Getting Started

-
+
+

+ Getting started +

+
-

1. Install reqsh

-

+

1. Install reqsh

+

Head over to the{' '} installation guide {' '} @@ -37,64 +50,43 @@ export default function DocsPage() {

-

2. Start the shell

-

- Simply type{' '} - - reqsh - {' '} - in your terminal. This drops you into the interactive REPL. +

2. Start the shell

+

+ Simply type reqsh in your terminal. This drops you into + the interactive REPL.

-

3. Set a base URL

-

- Define your target host. All subsequent requests in this session will be appended to - this base URL automatically. +

3. Set a base URL

+

+ Define your target host. All subsequent requests in this session will be appended + to this base URL automatically.

base https://api.example.com']} />
-

4. Send a request

-

+

4. Send a request

+

Type the HTTP method and the relative path. Then execute it using the special{' '} - - ::send - {' '} - command. + ::send command.

GET /users', '.....> ::send']} />
-
-

Sending Requests

-

+

+

+ Sending requests +

+

The shell supports building complex requests step-by-step. Start with the method and - path. HTTP methods are case-insensitive -{' '} - - GET - - ,{' '} - - POST - - ,{' '} - - PUT - - ,{' '} - - PATCH - - ,{' '} - - DELETE - {' '} - are all supported. You can also use absolute URLs — no base URL required. Add headers on - the following lines. Leave a blank line to start writing the body. + path. HTTP methods are case-insensitive — GET,{' '} + POST, PUT,{' '} + PATCH, DELETE are all supported. You + can also use absolute URLs — no base URL required. Add headers on the following lines. + Leave a blank line to start writing the body.

::send', ]} /> -
- Response time is displayed after every request:{' '} - - 200 OK - 142ms - +

+ Response time is displayed after every request: 200 OK - 142ms . JSON responses are automatically pretty-printed with colored syntax. -

+

-
-

Variables

-

- Store values with{' '} - - set - {' '} - and reference them anywhere in your request using{' '} - - {'{{name}}'} - - . Variables are interpolated at request time. +

+

+ Variables +

+

+ Store values with set and reference them anywhere in your + request using {'{{name}}'}. Variables are interpolated at + request time.

-
-

Query Parameters

-

- Add query parameters with{' '} - - param: - {' '} - lines. Values are URL-encoded automatically. +

+

+ Query parameters +

+

+ Add query parameters with param: lines. Values are URL-encoded + automatically.

-
-

Save & Run

-

- Save a request to session memory after executing it, then run it again instantly without - retyping. +

+

+ Save & run +

+

+ Save a request to session memory after executing it, then run it again instantly + without retyping.

-

Built-in Commands

-

- Beyond standard HTTP methods ( - - GET - - ,{' '} - - POST - - ,{' '} - - PUT - - ,{' '} - - PATCH - - ,{' '} - - DELETE - - ), reqsh provides specific REPL commands to manage your session. +

+ Built-in commands +

+

+ Beyond standard HTTP methods (GET,{' '} + POST, PUT,{' '} + PATCH, DELETE), reqsh provides + specific REPL commands to manage your session.

-
+
- - - - + + + + - + - - - + + + + ); } diff --git a/src/app/globals.css b/src/app/globals.css index 7bcdd60..6594b8e 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,34 +1,46 @@ @import 'tailwindcss'; @theme { - --color-accent: #ff3333; - --color-accent-dark: #cc2222; - --color-accent-light: #ff5555; - --color-surface: #0a0a0a; - --color-surface-light: #1a1a1a; - --color-surface-lighter: #2a2a2a; - --color-text-primary: #ffffff; - --color-text-secondary: #888888; - --color-border: rgba(255, 255, 255, 0.08); + /* Palette: warm paper, warm charcoal, muted brick red */ + --color-background: #f6f3ec; + --color-foreground: #26211d; + --color-muted: #6f6760; + --color-card: #fdfbf7; + --color-border: #e5dfd3; + + --color-accent: #b8402e; + --color-accent-strong: #99321f; + --color-accent-soft: #f2e4de; + + /* Dark surfaces (nav, footer, terminal) */ + --color-ink: #211d1a; + --color-ink-soft: #2e2a26; + --color-ink-border: #3b3630; + --color-ink-muted: #a39b91; + --color-ink-foreground: #f6f3ec; + + --font-sans: var(--font-geist-sans), system-ui, sans-serif; + --font-serif: var(--font-instrument-serif), Georgia, serif; + --font-mono: var(--font-geist-mono), ui-monospace, monospace; +} + +html { + background: var(--color-background); + scroll-behavior: smooth; } body { - background: linear-gradient(135deg, #000000 0%, #0a0505 50%, #050000 100%); - color: #ffffff; - font-family: var(--font-geist-sans), system-ui, sans-serif; + background: var(--color-background); + color: var(--color-foreground); + font-family: var(--font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - position: relative; overflow-x: hidden; } -html { - background: #000000; -} - ::selection { - background: rgba(255, 51, 51, 0.4); - color: #ffffff; + background: var(--color-accent-soft); + color: var(--color-accent-strong); } *::-webkit-scrollbar { @@ -40,24 +52,25 @@ html { } *::-webkit-scrollbar-thumb { - background: rgba(255, 51, 51, 0.4); + background: var(--color-border); border-radius: 999px; } *::-webkit-scrollbar-thumb:hover { - background: rgba(255, 51, 51, 0.6); + background: var(--color-muted); } -.transition-snappy { - transition-property: all; - transition-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); - transition-duration: 300ms; +/* Accessible focus states — red outline per brand */ +:focus-visible { + outline: 2px solid var(--color-accent); + outline-offset: 2px; + border-radius: 2px; } -.transition-smooth { +.transition-snappy { transition-property: all; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 500ms; + transition-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); + transition-duration: 250ms; } @keyframes blink { @@ -67,111 +80,37 @@ html { } .animate-blink { - animation: blink 1s step-end infinite; -} - -@keyframes float { - 0%, 100% { - transform: translateY(0px) rotate(0deg); - } - 50% { - transform: translateY(-20px) rotate(5deg); - } + animation: blink 1.1s step-end infinite; } -.animate-float { - animation: float 6s ease-in-out infinite; -} - -@keyframes float-delayed { - 0%, 100% { - transform: translateY(0px) rotate(0deg); +@keyframes fade-up { + from { + opacity: 0; + transform: translateY(16px); } - 50% { - transform: translateY(-15px) rotate(-3deg); + to { + opacity: 1; + transform: translateY(0); } } -.animate-float-delayed { - animation: float-delayed 8s ease-in-out infinite 1s; +.animate-fade-up { + animation: fade-up 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both; } -@keyframes pulse-glow { - 0%, 100% { - opacity: 0.5; - filter: blur(8px); - } - 50% { - opacity: 0.8; - filter: blur(12px); - } +.animate-fade-up-delay-1 { + animation: fade-up 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) 0.12s both; } -.animate-pulse-glow { - animation: pulse-glow 4s ease-in-out infinite; +.animate-fade-up-delay-2 { + animation: fade-up 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) 0.24s both; } -@keyframes slide-in { - from { - opacity: 0; - transform: translateY(20px); +@media (prefers-reduced-motion: reduce) { + .animate-fade-up, + .animate-fade-up-delay-1, + .animate-fade-up-delay-2, + .animate-blink { + animation: none; } - to { - opacity: 1; - transform: translateY(0); - } -} - -.animate-slide-in { - animation: slide-in 0.6s ease-out; -} - -/* Abstract gradient background elements */ -.gradient-blob-1 { - position: fixed; - top: -10%; - right: -5%; - width: 500px; - height: 500px; - background: radial-gradient(circle, rgba(255, 51, 51, 0.15) 0%, transparent 70%); - border-radius: 50%; - filter: blur(40px); - pointer-events: none; - z-index: 0; - animation: float 20s ease-in-out infinite; -} - -.gradient-blob-2 { - position: fixed; - bottom: -20%; - left: -10%; - width: 600px; - height: 600px; - background: radial-gradient(circle, rgba(255, 51, 51, 0.1) 0%, transparent 70%); - border-radius: 50%; - filter: blur(50px); - pointer-events: none; - z-index: 0; - animation: float-delayed 25s ease-in-out infinite; -} - -.gradient-blob-3 { - position: fixed; - top: 50%; - left: 50%; - width: 400px; - height: 400px; - background: radial-gradient(circle, rgba(255, 51, 51, 0.08) 0%, transparent 70%); - border-radius: 50%; - filter: blur(60px); - pointer-events: none; - z-index: 0; - transform: translate(-50%, -50%); - animation: pulse-glow 6s ease-in-out infinite 2s; -} - -/* Content wrapper to sit above blobs */ -.relative-content { - position: relative; - z-index: 1; } diff --git a/src/app/install/page.tsx b/src/app/install/page.tsx index ddeec84..d537ca7 100644 --- a/src/app/install/page.tsx +++ b/src/app/install/page.tsx @@ -7,21 +7,36 @@ export const metadata: Metadata = { 'Install reqsh - use the install script, download a prebuilt binary or build from source.', }; +function InlineCode({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} + export default function InstallPage() { return (
-
-
-

Installation

-

+

+
+

+ Get started +

+

+ Installation +

+

Get reqsh running on your system in seconds. Choose the method that best fits your workflow.

-
-

Install Script

-

+

+

+ Install script +

+

The fastest and recommended way to install. This script detects your OS and architecture, downloads the latest binary, and places it in your PATH.

@@ -32,33 +47,27 @@ export default function InstallPage() { />
-
-

Prebuilt Binary

-

+

+

+ Prebuilt binary +

+

Download the latest binary for your platform from the{' '} GitHub Releases {' '} page. Available for macOS (Intel & Silicon), Linux (x86_64), and Windows (x86_64).

-
-

- 1.Download the binary for your - platform. -

-

- 2.Move it to a directory included - in your system PATH. -

-

- 3.Grant execution permissions. -

-
+
    +
  1. Download the binary for your platform.
  2. +
  3. Move it to a directory included in your system PATH.
  4. +
  5. Grant execution permissions.
  6. +
-

- Windows users: place{' '} - - reqsh.exe - {' '} - in a directory listed in your{' '} - - %PATH% - - . +

+ Windows users: place reqsh.exe in a directory listed in your{' '} + %PATH%.

-
-

Build from Source

-

+

+

+ Build from source +

+

If you want to compile reqsh yourself, you'll need the{' '} Rust toolchain {' '} @@ -101,18 +105,16 @@ export default function InstallPage() { 'cargo build --release', ]} /> -

- The binary will be at{' '} - - target/release/reqsh - - . +

+ The binary will be at target/release/reqsh.

-

Verify Installation

-

+

+ Verify installation +

+

Confirm reqsh is installed and working correctly.

diff --git a/src/app/layout.tsx b/src/app/layout.tsx index acc7c21..e84f896 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,5 @@ import type { Metadata } from 'next'; -import { Geist, Geist_Mono } from 'next/font/google'; +import { Geist, Geist_Mono, Instrument_Serif } from 'next/font/google'; import { SpeedInsights } from '@vercel/speed-insights/next'; import Nav from '@/components/nav'; import Footer from '@/components/footer'; @@ -15,6 +15,13 @@ const geistMono = Geist_Mono({ subsets: ['latin'], }); +const instrumentSerif = Instrument_Serif({ + variable: '--font-instrument-serif', + subsets: ['latin'], + weight: '400', + style: ['normal', 'italic'], +}); + const siteUrl = 'https://reqsh.dev'; export const metadata: Metadata = { @@ -130,24 +137,18 @@ export default function RootLayout({ }; return ( - - + +
CommandUsageDescription
CommandUsageDescription
{cmd}{usage}{desc}
{cmd}{usage}{desc}