The studio's own site is the argument, so its DNA is documented to the same standard as any client's. Every value below is transcribed byte-exact from index.html, beta_v7, "THE DRAFTING TABLE."
Straight from index.html's :root (lines 30-42). One paper-light ground, one ink for structure, one burnt-orange accent, four soft washes for atmosphere. Worth saying plainly: --blue and --blue-2 are historical misnomers, holding the studio's real accent, burnt orange, not blue. The name survived a rebrand; the hex didn't. Left as-is on purpose, renaming a live token is a bigger risk than the confusion it causes a reader of this file.
Found while building this guide, worth a fix, not fixed here: .btn's box-shadow is literally rgba(203,77,20,.7), the old accent, not var(--blue). It reads fine (both are burnt-orange family) but it's a real drift between the token and the pixel. See Tokens for the full list of legacy-orange sightings.
Fraunces (500-700, plus italic 400-500) is the display face: warm, editorial, a little hand-set. It is rendered at weight 600 with tight tracking (-.015em to -.02em) so headings feel considered rather than heavy. Inter (400-700) carries body copy and UI chrome at 18px/1.65, unusually generous for a marketing site, chosen because the whole pitch is "clear." JetBrains Mono (400-700) is reserved for anything that reads as system information: eyebrows, nav links, tags, stat labels, meta lines, never for a sentence a visitor is meant to read as prose.
index.html :root, h1/h2/.hero-subHeadings, body and eyebrow, set exactly as the hero renders them.
Body copy, Inter 400, 18px, line-height 1.65, --muted on light surfaces. Plain, confident, no jargon, first person.
.brand .k / .foot .fb · CLAUDE.md 2026-08-18The only official K13 mark. Fraunces "K" set bold in ink, "13" set bold in the accent (rendered upright here, italic where it doubles as emphasis elsewhere), a two-line JetBrains Mono tag underneath. A rounded-square glyph mark existed once; Kazim ordered it destroyed on 2026-08-18 after it surfaced in a client deliverable he didn't recognize as his own. It is not canon and must never be regenerated.
One easing curve does almost everything here: --ease: cubic-bezier(.22,1,.36,1), the house "premium" reveal curve, fast to start and soft to land. Interactions run .3-.5s on it; scroll reveals run .8s; the two ambient loops (the status-dot pulse and, before it, nothing else) run 2s. There is no shine sweep and no idle "breathing" card anywhere on this site, restraint is the point. Every effect below is real, pulled from the live inline script and CSS, not the house's general motion vocabulary.
.rv / .rv.in · IntersectionObserverEvery above-the-fold block starts at opacity 0, translateY(26px). An IntersectionObserver (threshold 0.16, rootMargin "0px 0px -8% 0px") adds .in once, then unobserves, so it never re-fires on scroll-back. Hero elements are force-revealed after a 160ms timeout instead of waiting on the observer, so the first paint isn't empty.
@keyframes beatThe only truly looping animation on the page. A ring of success-green box-shadow expands and fades around the "Open for projects" dot, forever, on a 2s cycle. It is the one place the site allows itself to feel "alive" while sitting still.
@keyframes pop · .sent .ringThe moment the contact stepper hands off to mailto:, a checkmark ring scales in from 40% with a fade. Runs once in production; looped here alternate for the demo.
#hdr.scrolled · onScrollPast 30px of scroll, the header tightens its padding and its translucent, blurred background fades in. Both are plain CSS transitions triggered by a class toggle, no scroll-linked animation.
#feed · inline scriptThe hero's "Currently…" line cross-fades through a shuffled list of ~40 one-liners every 3.8s (420ms fade). A visible, focusable Pause toggle sits as a DOM sibling of the card, not inside it, because the card itself is aria-hidden="true" (a decorative ticker) and aria-hidden on a descendant can't undo an ancestor's. Under reduced motion the whole feed script bails early, and the CSS hides the Pause button, a control with no listener attached is worse than no control.
.feed-toggle{display:none} so no dead control ships#portrait [data-depth] · IntersectionObserver + rAFThree layers (a paper back-panel, the photo frame, the caption chip) sit at different data-depth multipliers (-.45, .08/.16, .16) and translate on the scroll position relative to viewport center, transform-only, GPU-friendly. An IntersectionObserver gates the scroll listener so it only runs while the portrait is actually visible.
.rv.in.screen-s / .screen-s.on/.pastEach question screen slides in from translateX(34px) with a fade, and slides the opposite way (-34px) when stepping backward past it, so going forward and going back read as different directions, not a mirrored animation.
[data-count] · countUp()The hero stat numbers (16 shipped, 10 live) count up from 0 once they scroll within 95% of the viewport, cubic ease-out over 1300ms via requestAnimationFrame. Reduced motion skips straight to the final number.
index.html :root · @media(prefers-reduced-motion)--ease cubic-bezier(.22,1,.36,1), the only named easing token, used for reveals, hovers, the header, the stepper and the portrait clip-path
.rv{opacity:1;transform:none}; the feed-toggle button is also force-hidden since its script never runsTwo CTA weights (solid, ghost), one underline-link device reused for both nav and the mailto link, and a small pill control for the feed's Pause toggle. No third accent, no icon-only buttons.
.btnThe primary action everywhere: "Start a project," "Send it." Accent fill, white text, lifts 2px and swaps to ink on hover.
.btn.ghostThe quieter second action, "See the work." Transparent, hairline border, no shadow, no lift, only a color swap on hover.
.nl · .contact .mailEvery plain in-line link, nav items and the mailto line, shares one device: an accent underline that scales in from the left on hover, never a color change alone.
.feed-toggleThe one toggle control on the page, Pause/Play for the rotating status feed. Small, quiet, sits visually on the glass card without being trapped inside its aria-hidden scope.
The only data-collecting surface is the four-step contact stepper. It has no backend and needs none, the final step composes a pre-filled mailto: and hands it to the visitor's own mail app, so there's no honeypot, no server validation, and no email address shipped as a plain link until the very last step.
.s-fieldName and email steps, minimal underline input, no box, no visible native outline, the underline itself becomes the focus indicator.
:focus-within on the wrapper swaps the border to blue instead, the substitute indicator.optStep 1's "what are we building" choice, four stacked buttons instead of a select, each with a trailing arrow that nudges right and brightens on hover.
.step-prog · .step-back · .step-sum .scProgress dots along the top fill in as you advance; a Back link appears only past step 1; answered steps collapse into clickable summary chips ("Building: A brand site") so you can jump back without losing later answers.
idx straight back to that step.sent · sendIt handlerThe whole step body becomes genuinely inert, not just visually hidden, before the success panel takes over, and the panel's copy is honest about uncertainty: the code cannot know a mail client actually opened, so it offers a plain-text fallback address if nothing takes focus within 1.2s.
stepBody.inert = true before reveal, so nothing underneath stays tabbable.skip-link · CLAUDE.mdA hidden skip-to-content link reveals on focus. The house rule behind it is written into this repo's own CLAUDE.md: opacity:0; pointer-events:none does not remove an element from the tab order, and that exact mistake once shipped a stepper that told a visitor their message was sent when nothing had happened. Every inactive step now carries the real HTML inert attribute instead.
:focus brings it to top:12pxEvery page-level building block, pulled straight from the live sections of index.html.
.status · .status-wrapA glass panel presenting the studio as a live, working thing: an "Open for projects" pulse, a rotating "Currently…" line, then count-up stats. The card itself is decorative (aria-hidden); the Pause control lives outside it in the DOM, positioned to sit visually on its corner. See Motion for the feed and count-up timing.
.approach .cardsThe "three rules" section, three numbered cards, each closing with a short tint bar drawn from a different wash color, the only place the four washes get named individually rather than used as background atmosphere.
Fast on the easy parts, careful on the ones that bite later.
.row · #peekTen client rows, each a number, a Fraunces name, a description, a tag and an "Open" arrow. On hover the row nudges 12-18px right, gains an accent underline, and the name turns accent-colored. On hover-capable devices a floating screenshot preview (#peek) follows the cursor with rAF lerp easing and a -2deg tilt; on touch or narrow screens the same screenshot renders inline above the row instead, no hover to fake.
#portrait · .p-frame · .p-capLayered scroll-depth photo (see Motion) with a dotted paper-3 back-panel offset behind the frame, and a small floating caption chip (name, role, studio) anchored to the bottom-right corner of the image.
favicon.svg · CLAUDE.md 2026-08-19The only system icon is the typographic favicon.svg, Kazim-approved in the 2026-08-19 brand triage alongside the ten live Work screenshots and assets/kazim.jpg. There is no separate app-icon composite, no square glyph anywhere in the tree, that family was purged for good.
favicon.svg, typographic, referenced directly in <head>Small, repeated motifs that hold the editorial-but-technical register together across every section.
.eyebrowUppercase mono kicker with a 24px accent rule leading into it, ahead of nearly every section title.
h1 .ci · .h2 i · .big iThe single recurring emphasis device: one word per heading set in Fraunces italic 500 and the accent color, "feels obvious," "real products," "worth building." Never bold, never all-caps, for emphasis inside a heading.
.approach / .work / .cap / .about / .contact { border-top }Every major band after the hero opens with a single 1px --line rule instead of a background color change or a shadow, the page reads as one continuous sheet of paper, not stacked cards.
.draft-grid · .washA fixed, page-wide layer of faint dotted "plan paper" (30px grid, legacy-orange dots at 14% opacity, radially masked so it fades toward the bottom) sits under three large, heavily blurred wash blobs. Both layers are position:fixed, z-index:0, and never animate, the atmosphere is static texture, not motion.
.card .num · .row .rnumMono two-digit numbers (01, 02…) label both the Approach cards and the Work index rows, the site's one recurring "ordered list" motif, always mono, always accent or faint, never a bullet or an icon.
house canon, K13 brand rules (2026-08-13)One hue carries every interactive and emphasis surface on this page, links, CTAs, eyebrows, the wordmark's "13," hovers, focus states. Success green is the sole sanctioned exception, reserved for confirmation only (the status dot, the sent-form ring). This also follows a K13-wide rule from the studio's own brand canon: never a colored strip down a card's left edge, it reads as generic template AI work. Where this site wants a card to carry color, it tints the whole tag (approach card's tint bar) or the whole page (the wash blobs), never a left border.
The numbers behind the look, plus the operational rules that govern this repo specifically.
index.html, inline <style>outline:none and rely on :focus-within border-color instead, and the skip-link's own translate-into-viewCLAUDE.md · vercel.jsonThis repo carries its own operating rules on top of the visual system, worth knowing before touching it.
script-src 'unsafe-inline' is a known, tracked exception since the JS is inline with no build stepindex.html is the whole application; edits deserve the same care as a source tree, and concurrent agents should partition by section