# UI design system

## Reading-first visual direction

The handbook uses a restrained security reference aesthetic: warm light surfaces, dark blue-green surfaces, teal links/accent, system fonts, and readable mono text for artifact and source identifiers. The main content width is 49rem, sidebar 18rem, body size 1.0625rem, and prose line height 1.72. Paragraphs target no more than 76 characters per line. System fonts avoid remote font requests and reduce layout uncertainty.

## Tokens

All custom variables are defined in `src/styles/theme.css` and bridge to Starlight color/font tokens. Values below document the implementation, not measured WCAG contrast claims.

| Token | Dark | Light | Use |
| --- | --- | --- | --- |
| Background | `#10191d` | `#fbfcfa` | Page/navigation/sidebar |
| Surface | `#172429` | `#f0f5f2` | Cards, contracts, evidence |
| Border | `#385158` | `#c6d5cf` | Containers and controls |
| Text | `#edf4f3` | `#182d30` | Primary content |
| Muted | `#adc2c3` | `#4c6265` | Context and captions |
| Accent | `#77ddd1` | `#0b6b65` | Links and handoffs |
| Focus | `#a0ece2` | `#066b63` | Three-pixel visible outline |
| Success | `#83dfac` | `#176543` | Reserved state signal |
| Warning | `#ffce88` | `#80530d` | Reserved state signal |
| Danger | `#ffaaa0` | `#a3362b` | Reserved state signal |

Color never carries the evidence classification alone. Status appears in words, with result, scope, and limitations. Heading tracking is slightly tightened; command/code text uses local monospace fonts and breaks long identifiers where needed. The home hero uses fluid type from 2.5rem to 4.5rem and a constrained headline measure.

## Spacing and components

Panels use 1.3rem padding, a one-pixel border, and modest rounded corners; cards use 1.35rem padding and one-rem grid gaps. Secondary metadata uses smaller text but retains line spacing. The baseline notice appears directly after the page title so historical context cannot be mistaken for a footer disclaimer. Source links label their pinned implementation role separately from edit links.

Native details elements in the architecture map expose a labelled summary and keyboard interaction without a custom accordion framework. Release-journey buttons have disabled states and a live stage position; full static content is visible before enhancement. Evidence filters use labelled native selects, a polite live result count, and a clear empty state. Filters remain hidden until their JavaScript initializes, avoiding inert controls when scripting is absent.

## Responsive behavior

Three-column reading cards collapse at 50rem. The two-column home note also collapses. Panels reduce padding. At 25rem, body text becomes 1rem, filters stack, and card padding reduces. Starlight manages its standard sidebar/mobile-menu and right-side table-of-contents behavior; custom code must be tested alongside it.

Diagrams retain a 620px minimum width inside an independently scrollable region so labels remain readable on phones. This region is focusable and named. It must not produce page-wide overflow. Evidence images scale to content width and link to the full asset. Wide tables/code blocks should scroll within their own layout; long digests and URL text should not widen the viewport.

## Accessibility and diagram conventions

Each diagram has a visible title, SVG title/description, caption, semantics text, and ordered text equivalent. Theme variables color shapes and arrows. Diagrams explain a causal sequence, while page prose preserves scope and failure paths that four visual nodes cannot fully express. Optional/deferred behavior is stated in text, not represented as active solely by an arrow.

Focus-visible uses a three-pixel outline with four-pixel offset. Link underlines have additional offset. Native buttons/selects/details preserve browser keyboard semantics. Headings maintain Starlight's article structure, and evidence image descriptions explain useful content rather than naming the screenshot file. Automated axe checks and manual keyboard/visual review target WCAG 2.2 AA practices; they are not certification.

## Motion, print, and states

Custom components use no decorative animation. Reduced-motion media rules shorten transitions/animations and disable smooth scrolling. Print rules hide navigation, filters, search, pagination, and journey controls; remove frame padding; show details content; reduce diagram minimum width; and underline links in black. Print/no-JavaScript readability must be inspected in production output because CSS alone does not prove the final browser presentation.

The current custom CSS has no separate loading spinner or network error state because catalogue records are static. Search loading/no-result states belong to Starlight/Pagefind and require production browser tests. The final audit must record actual viewport/theme/focus/overflow findings and any token changes after remediation.


## Verified UI refinements

Native Starlight owns modal/menu/theme states. A small Search override adds the explicit Pagefind input label required by the accessibility audit. Named complementary landmarks distinguish implementation sources, related controls and local contents. Authored flex/grid components explicitly preserve HTML hidden state so filters/journey controls stay unavailable without JavaScript while prose/records/stages remain readable. Print reveals every journey stage. The homepage includes an explicit baseline notice because splash rendering does not use the article PageTitle slot.

The UI is owned by the separate private `devSatym/gcp-security-handbook` repository. Implementation-source links continue to name the historical project; edit links name the handbook. Earlier screenshot sidecars preserve their original base and capture dates, while each subsequent profile capture records its real coordinates. The custom-domain profile renders at `/`; the standalone GitHub profile renders at `/gcp-security-handbook/`; the legacy compatibility profile renders at `/gcp-supply-chain-security/`.

## Identity and project navigation addendum

Project understanding remains the first reading task. The header keeps compact project identity and source/about navigation; home uses the restrained “Maintained and documented by Satyam Agnihotri” attribution. About and contribution content explain the supplied focus and supported adaptations without claiming sole original authorship, employment experience or production impact. The footer keeps concise author/source/about links. Longform metadata remains small rather than repeating a resume panel.

The shared author record contains the proposed name `Satyam Agnihotri`, handle `devSatym`, headline `DevOps & Cloud Engineer`, short supplied biography and public profile destinations. No approved headshot exists, so initials are a text fallback. Null email/avatar/resume fields and an empty certification list produce no empty control, invented mailbox or verification badge. A profile URL is supplied copy; observed availability is a separate state. The GitHub profile was reachable in the recorded read-only check; LinkedIn returned 999 and portfolio verification timed out, so those outcomes cannot support a live destination claim.

The More engineering projects area is driven by a typed catalogue with title, repository URL, proposed/live docs URL, availability, summary and optional approved preview. The GCP handbook links to its verified live site at `security.devsatym.xyz`. It presents `devsatym.xyz` as the planned central portfolio and `resilience.devsatym.xyz`, `aks.devsatym.xyz` as independent future site targets. Unverified future documentation destinations are explicitly planned text or omitted rather than advertised with working-link styling. Do not embed unrelated project content or make portfolio publication a prerequisite of the current handbook.

Identity links must preserve visible keyboard focus, adequate label meaning and readable wrapping at 320px. Status appears as text, including when a planned item has no anchor. Repeated components consume the central records so spelling, availability and optional-field behavior cannot diverge across header[local workspace]

## Images and sharing metadata addendum

Public evidence uses the profile-aware asset helper for preview and full-resolution URLs. Each image has explicit intrinsic dimensions, useful alt text, a responsive maximum width, context-rich caption and a full-resolution link. Labels distinguish the claim, context, expected/recorded result, date/revision uncertainty and limitations. The three-image set is historical; the owner's later explicit all-fourteen instruction is implemented with reviewed original bytes/dimensions and subsequent authorization to publish them on Cloudflare. No additional redaction was selected or performed. Terminal/account metadata remains visible and disclosed. Optional mask proposals remain private; a future derivative needs separate direction and explicit display provenance.

The native `ScreenshotGallery` supplies an index, labelled image cards, full-resolution links and expandable source/hash/privacy details. It distinguishes direct evidence from related context and states collection date provenance rather than inventing execution timestamps. Five previous transcript-only terminal records now also display their original PNG while retaining transcripts; eight evidence records have images and the gallery adds six remaining/contextual captures for fourteen unique originals. Gallery content is static and readable without JavaScript; image links remain useful with keyboard input and at narrow widths. No new image is manufactured to alter a command or result.

Editorial images imported from `src/assets` can use Astro's generated image URLs and image components. Files in `public/evidence` and `public/og` use paths relative to `public` and are copied as-is; a base-aware helper adds the configured prefix. Neither a GitHub blob page nor a local filesystem or temporary attachment URL is a deployed image source. [Astro image behavior](https://docs.astro.build/en/guides/images/)

The social preview is an original 1200×630 PNG with restrained project title, focus, author attribution and intended hostname. It is labelled editorial artwork rather than a cloud/evidence capture; 1200×630 is a design target, not a guarantee for every sharing service. Head metadata uses an absolute HTTPS PNG URL derived from the active profile and preserves the Starlight Head integration. SVG remains suitable for accessible in-page diagrams and favicon but is not the only sharing-image format. [Starlight Head integration](https://starlight.astro.build/reference/configuration/#head)

The pre-gallery 29-case and first expanded-gallery thirty-case/profile suites remain historical. The recorded repaired matrix passes thirty-one browser cases per profile (25 Chromium, six Firefox), including native image dimensions/full-resolution links, mobile/keyboard/no-JavaScript gallery behavior, deferred-image loading/TOC stability, social metadata, author navigation and planned destinations. Every profile's output audit has zero errors. The first catalogue Lighthouse score 80/CLS 0.465829 remains a failed checkpoint; the subsequent repaired Lighthouse checkpoint gives all categories 100 on three routes, with catalogue CLS 0.008051353. These measurements retain their original scope. Custom-domain HTTPS and public PNG responses are now verified separately in private Cloudflare receipts; neither local requests nor public HTTP checks establish a sharing service's crawler behavior.

At desktop widths, `TwoColumnContent.astro` bounds the sticky TOC inside its relative sidebar container, preserves its width with `flex-shrink: 0`, and gives the main pane `min-width: 0`. `EvidencePanel.astro` gives the image link block layout and the image an explicit width/height-derived aspect ratio; the theme makes images block elements with responsive width. This reserves image space before lazy PNG decoding and prevents the TOC/content columns from distorting when image intrinsic dimensions become available. The regression case defers PNG responses, verifies reserved image height and panel-height stability after decoding, and checks the TOC is within the viewport and remains sticky after scrolling.
