diff --git a/DESIGN.md b/DESIGN.md index 69c75fe..f75695d 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -2,23 +2,23 @@ name: Polymodel description: Blueprint/technical-drawing design system for an AT Protocol model-sharing app. colors: - base: "#f5f1e8" - surface: "#fffdf7" - overlay: "#e8edf0" - ink: "#17252f" - emphasis: "#0c1f2c" - subtle: "#445461" - muted: "#6a747b" - primary: "#1f6d8a" - secondary: "#5a8797" - tertiary: "#0f4159" - action: "#c5652a" - link: "#a24d1f" - border: "#a9b8bf" - highlight: "#d8e5e9" - error: "#a13f32" - warning: "#b36a16" - success: "#2d7358" + base: "oklab(0.980696 -0.001930 -0.004746)" + surface: "oklab(1.000000 0.000000 0.000000)" + overlay: "oklab(0.940351 -0.008108 -0.017910)" + ink: "oklab(0.252380 -0.009714 -0.034170)" + emphasis: "oklab(0.218461 -0.012406 -0.039864)" + subtle: "oklab(0.436442 -0.012368 -0.044729)" + muted: "oklab(0.550853 -0.008208 -0.033125)" + primary: "oklab(0.479428 -0.035191 -0.111636)" + secondary: "oklab(0.613677 -0.025079 -0.065437)" + tertiary: "oklab(0.367809 -0.026626 -0.097956)" + action: "oklab(0.516800 -0.033898 -0.129915)" + link: "oklab(0.485173 -0.035448 -0.128511)" + border: "oklab(0.776085 -0.009713 -0.026566)" + highlight: "oklab(0.902143 -0.011298 -0.030437)" + error: "oklab(0.499559 0.115162 0.066600)" + warning: "oklab(0.528919 0.016251 0.103026)" + success: "oklab(0.503030 -0.080259 0.021719)" typography: heading: fontFamily: "Proza Libre, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif" @@ -76,12 +76,12 @@ components: **Creative North Star: "The Drafting Table"** -Polymodel looks like a set of well-kept engineering blueprints rendered for the web. The page is drafting paper; content sits on crisp bordered panels with near-square corners; technical metadata is set in monospace the way a drawing carries its measurements; empty media reads as a faint drafting grid awaiting geometry. The teal primary is drawing-ink blue; a single warm orange is the one action accent, used like a redline. It is a **product** surface: design serves the task of browsing, judging, downloading, and publishing printable things. The tool should disappear into the work. +Polymodel looks like a set of well-kept engineering blueprints rendered for the web. The page is cool drafting stock; content sits on crisp bordered panels with near-square corners; technical metadata is set in monospace the way a drawing carries its measurements; empty media reads as a faint drafting grid awaiting geometry. The primary is drawing-ink blue; the action accent is a stronger blue, used like the one marked-up instruction on the sheet. It is a **product** surface: design serves the task of browsing, judging, downloading, and publishing printable things. The tool should disappear into the work. -This system explicitly rejects the flat-SaaS dashboard look (rounded cards everywhere, purple/blue gradients, soft shadows, Inter-for-everything) and the reflexive dark-terminal "developer tool" aesthetic. Warmth comes from the paper tone, the humanist type, and the orange accent — not from decoration. Familiarity is a feature: a maker fluent in Printables should trust every control on sight. +This system explicitly rejects the flat-SaaS dashboard look (rounded cards everywhere, purple/blue gradients, soft shadows, Inter-for-everything) and the reflexive dark-terminal "developer tool" aesthetic. Warmth is minimal and functional — mostly semantic warning/error states — while the product identity comes from cool stock, blue ink, humanist type, and crisp linework. Familiarity is a feature: a maker fluent in Printables should trust every control on sight. **Key Characteristics:** -- Drafting-paper base, drawing-ink teal, single warm-orange action accent. +- Cool drafting-stock base, drawing-ink blue, single stronger-blue action accent. - Near-square corners (2px panels, 0px controls); crisp 1px borders over shadow. - Monospace for all technical metadata (dimensions, formats, DIDs/handles, counts, status). - Drafting-grid placeholders instead of gray boxes. @@ -89,37 +89,37 @@ This system explicitly rejects the flat-SaaS dashboard look (rounded cards every ## 2. Colors -A restrained palette: a tinted drafting-paper neutral ramp, one drawing-ink teal that carries structure, and a single warm orange reserved for action. Every token has a dark-scheme value (see `assets/styling/theme.css`; tonal/dark values live in the `.impeccable/design.json` sidecar). +A restrained palette: a cool drafting-stock neutral ramp, one drawing-ink blue that carries structure, and a single stronger blue reserved for action. Every token has a dark-scheme value (see `assets/styling/theme.css`; tonal/dark values live in the `.impeccable/design.json` sidecar). ### Primary -- **Drawing-Ink Teal** (#1f6d8a): The structural brand color — active tabs, selected state, focus rings, section emphasis, grid lines (at low alpha). Carries identity without being the action color. +- **Drawing-Ink Blue** (`oklab(0.479428 -0.035191 -0.111636)`): The structural brand color — active tabs, selected state, focus rings, section emphasis, grid lines (at low alpha). Carries identity without being the action color. ### Secondary -- **Slate Teal** (#5a8797): Supporting teal for secondary controls and quieter structural accents. -- **Deep Teal** (#0f4159): High-emphasis teal for hover ink and strong labels against light surfaces. +- **Slate Blue** (`oklab(0.613677 -0.025079 -0.065437)`): Supporting blue for secondary controls and quieter structural accents. +- **Deep Blueprint Blue** (`oklab(0.367809 -0.026626 -0.097956)`): High-emphasis blue for hover ink and strong labels against light surfaces. ### Tertiary -- **Redline Orange** (#c5652a): The single warm action accent — primary buttons and the one element that should pull the eye to "do this." **Action only, never decoration.** -- **Rust Link** (#a24d1f): Inline text links, distinct from the action button so links don't read as buttons. +- **Action Blue** (`oklab(0.516800 -0.033898 -0.129915)`): The single action accent — primary buttons and the one element that should pull the eye to "do this." **Action only, never decoration.** +- **Link Blue** (`oklab(0.485173 -0.035448 -0.128511)`): Inline text links, distinct from the action button so links don't read as buttons. ### Neutral -- **Drafting Paper** (#f5f1e8): The body background. A warm paper tone tinted toward the brand — the blueprint substrate, not a generic off-white. -- **Sheet** (#fffdf7): Raised panel/card/surface background. -- **Blueprint Overlay** (#e8edf0): Cool inset background for media wells and grid placeholders. -- **Ink** (#17252f): Body text. -- **Emphasis** (#0c1f2c) / **Subtle** (#445461) / **Muted** (#6a747b): The text-emphasis ramp; pick by importance, never drop body to muted-gray on the paper base. -- **Border** (#a9b8bf): The 1px line on every panel, control, and pill. -- **Highlight** (#d8e5e9): Selection/skeleton shimmer tint. +- **Drafting Stock** (`oklab(0.980696 -0.001930 -0.004746)`): The body background. A cool blue-white substrate — blueprint-adjacent without drifting into warm cream or flat SaaS white. +- **Sheet** (`oklab(1.000000 0.000000 0.000000)`): Raised panel/card/surface background. +- **Blueprint Overlay** (`oklab(0.940351 -0.008108 -0.017910)`): Cool inset background for media wells and grid placeholders. +- **Ink** (`oklab(0.252380 -0.009714 -0.034170)`): Body text. +- **Emphasis** (`oklab(0.218461 -0.012406 -0.039864)`) / **Subtle** (`oklab(0.436442 -0.012368 -0.044729)`) / **Muted** (`oklab(0.550853 -0.008208 -0.033125)`): The text-emphasis ramp; pick by importance, never drop body to low-contrast gray on the stock base. +- **Border** (`oklab(0.776085 -0.009713 -0.026566)`): The 1px line on every panel, control, and pill. +- **Highlight** (`oklab(0.902143 -0.011298 -0.030437)`): Selection/skeleton shimmer tint. ### Status -- **Error** (#a13f32) / **Warning** (#b36a16) / **Success** (#2d7358): Semantic state only, paired with shape/label, never color-alone. +- **Error** (`oklab(0.499559 0.115162 0.066600)`) / **Warning** (`oklab(0.528919 0.016251 0.103026)`) / **Success** (`oklab(0.503030 -0.080259 0.021719)`): Semantic state only, paired with shape/label, never color-alone. ### Named Rules -**The One Redline Rule.** Redline Orange (#c5652a) is the action accent. It marks the single primary action in a view and nothing decorative. If two things on a screen are orange, one is wrong. +**The One Action Rule.** Action Blue (`oklab(0.516800 -0.033898 -0.129915)`) is the action accent. It marks the single primary action in a view and nothing decorative. If two elements compete as primary action, one is wrong. -**The Paper-Is-Identity Rule.** The body background is drafting paper (#f5f1e8), a deliberate tinted neutral — not the AI warm-cream default. Never rename it `--paper`/`--cream`/`--sand` and never swap it for a flat #fff/off-white; the paper tone carries the blueprint metaphor. +**The Stock-Is-Identity Rule.** The body background is cool drafting stock (`oklab(0.980696 -0.001930 -0.004746)`), a deliberate blue-white neutral — not warm cream and not flat SaaS white. Never rename it `--paper`/`--cream`/`--sand`; the cool stock tone carries the blueprint metaphor. -**The Ink-Not-Gray Rule.** Body text reaches for the ink end of the ramp. Light-gray "for elegance" on the tinted paper is the contrast trap; when a value is close to 4.5:1, move toward Ink/Emphasis, not Muted. +**The Ink-Not-Gray Rule.** Body text reaches for the ink end of the ramp. Light-gray "for elegance" on the cool stock is the contrast trap; when a value is close to 4.5:1, move toward Ink/Emphasis, not Muted. ## 3. Typography @@ -127,7 +127,7 @@ A restrained palette: a tinted drafting-paper neutral ramp, one drawing-ink teal **Body Font:** Proza Libre (with system-ui, -apple-system, Segoe UI, sans-serif) **Label/Mono Font:** Ioskeley Mono (with IBM Plex Mono, Consolas, monospace) -**Character:** One humanist sans (Proza Libre) carries headings, body, labels, and buttons — warm and legible, the workshop-manual voice. A distinctive monospace (Ioskeley Mono) carries everything technical, like dimensions stamped on a drawing. The contrast axis is sans-vs-mono, not two near-identical sans faces. +**Character:** One humanist sans (Proza Libre) carries headings, body, labels, and buttons — legible and workshop-manual direct. A distinctive monospace (Ioskeley Mono) carries everything technical, like dimensions stamped on a drawing. The contrast axis is sans-vs-mono, not two near-identical sans faces. ### Hierarchy - **Heading** (Proza Libre, 600, ~1rem–1.18rem, line-height 1.3): Card titles, section and page headings. Fixed rem scale, tight ratio. @@ -144,7 +144,7 @@ A restrained palette: a tinted drafting-paper neutral ramp, one drawing-ink teal ## 4. Elevation -Flat by default. Depth comes from crisp 1px borders and tonal layering (paper → sheet → overlay), not shadows. The only shadow in the system is a 1px hairline under panels that reads as a sheet of paper lifting off the table, not a floating SaaS card. +Flat by default. Depth comes from crisp 1px borders and tonal layering (stock → sheet → overlay), not shadows. The only shadow in the system is a 1px hairline under panels that reads as a sheet lifting off the table, not a floating SaaS card. ### Shadow Vocabulary - **Paper hairline** (`box-shadow: 0 1px 0 color-mix(in srgb, var(--color-text) 8%, transparent)`): The single resting elevation on cards/panels. Borders do the structural work; this only seats the sheet. @@ -159,26 +159,26 @@ Flat by default. Depth comes from crisp 1px borders and tonal layering (paper ### Buttons - **Shape:** Near-square (2px radius); base controls render at 0px corners. Never round to pill (except deliberate tags) or 12px+. -- **Default:** Sheet background, 1px border, ink text. Hover shifts border to teal and text to deep teal. -- **Primary:** Redline Orange fill, paper-colored text — the one action. Hover brightens slightly (`filter: brightness(1.04)`), no transform bounce. -- **Secondary / Ghost:** Teal border + deep-teal text (secondary); transparent background (ghost). +- **Default:** Sheet background, 1px border, ink text. Hover shifts border to blue and text to deep blueprint blue. +- **Primary:** Action Blue fill, stock-coloured text — the one action. Hover brightens slightly (`filter: brightness(1.04)`), no transform bounce. +- **Secondary / Ghost:** Blue border + deep-blue text (secondary); transparent background (ghost). ### Chips / Tabs / Status pills - **Style:** 1px border, near-square, mono text, ~0.72rem. Transparent at rest. -- **State:** Active tab / selected pill take a teal border, deep-teal text, and an 8% teal wash. Muted and error variants recolor the border + text + faint wash to match the semantic role. +- **State:** Active tab / selected pill take a blue border, deep-blue text, and an 8% blue wash. Muted and error variants recolor the border + text + faint wash to match the semantic role. - **Pill radius:** `--radius-pill` (999px) is reserved for genuinely round badges — the circular part-index marker and deliberate tag chips — never for cards, inputs, or buttons. ### Cards / Containers - **Corner Style:** 2px (panel radius). -- **Background:** Sheet (#fffdf7) over the paper base. -- **Border:** 1px Border (#a9b8bf) — the defining line. +- **Background:** Sheet (`oklab(1.000000 0.000000 0.000000)`) over the stock base. +- **Border:** 1px Border (`oklab(0.776085 -0.009713 -0.026566)`) — the defining line. - **Shadow Strategy:** Paper hairline only (see Elevation). - **Internal Padding:** ~1rem; metadata rows in mono, subordinate to title/creator. - **Media:** Drafting-grid background (20px grid, grid-line color) for previews and placeholders — never a flat gray box; missing media draws nested registration rectangles, not fake content. ### Inputs / Fields -- **Style:** Paper-base fill, 1px border, 2px radius, body sans. -- **Focus:** Border shifts to teal with a 2px translucent teal outline (`outline: 2px solid color-mix(... primary 25% ...)`). Focus is always visible. +- **Style:** Stock-base fill, 1px border, 2px radius, body sans. +- **Focus:** Border shifts to blue with a 2px translucent blue outline (`outline: 2px solid color-mix(... primary 25% ...)`). Focus is always visible. - **Error / Disabled:** Error recolors border+text to Error and adds a faint wash; disabled drops contrast and removes the pointer affordance. ### Navigation @@ -198,10 +198,10 @@ The drafting-grid media well (`.blueprint-media`) and the shimmer skeletons (`.s - **Do** keep motion to 150–250ms, ease-out, for state/feedback/loading/viewer-readiness only, with a `prefers-reduced-motion` fallback. ### Don't: -- **Don't** swap the drafting-paper base for a flat off-white, or rename it `--paper`/`--cream`/`--sand`. +- **Don't** swap the cool drafting-stock base for warm cream or a flat off-white, or rename it `--paper`/`--cream`/`--sand`. - **Don't** round cards/inputs to 12px+ or reach for full pills outside tags; the near-square corner is the identity. -- **Don't** use more than one Redline-Orange action per view, or use the action color for decoration. +- **Don't** use more than one primary action per view, or use the action color for decoration. - **Don't** use gradient text, glassmorphism-by-default, hero-metric templates, identical icon-card grids, or an uppercase eyebrow above every section. - **Don't** pair a 1px border with a wide soft drop shadow (ghost-card), use `border-left` >1px as a colored stripe, or animate `` on hover. -- **Don't** put a display font — or any non-mono face — in technical metadata, or drop body text to muted gray on the paper base. +- **Don't** put a display font — or any non-mono face — in technical metadata, or drop body text to muted gray on the stock base. - **Don't** land on generic flat-SaaS or generic dark-terminal looks; the answer to "what is this" is the blueprint identity. diff --git a/assets/styling/theme.css b/assets/styling/theme.css index c990d80..a565586 100644 --- a/assets/styling/theme.css +++ b/assets/styling/theme.css @@ -52,24 +52,24 @@ :root { color-scheme: light dark; - --color-base: #f5f1e8; - --color-surface: #fffdf7; - --color-overlay: #e8edf0; - --color-text: #17252f; - --color-muted: #6a747b; - --color-subtle: #445461; - --color-emphasis: #0c1f2c; - --color-primary: #1f6d8a; - --color-secondary: #5a8797; - --color-tertiary: #0f4159; - --color-error: #a13f32; - --color-warning: #b36a16; - --color-success: #2d7358; - --color-border: #a9b8bf; - --color-link: #a24d1f; - --color-highlight: #d8e5e9; + --color-base: oklab(0.980696 -0.001930 -0.004746); + --color-surface: oklab(1.000000 0.000000 0.000000); + --color-overlay: oklab(0.940351 -0.008108 -0.017910); + --color-text: oklab(0.252380 -0.009714 -0.034170); + --color-muted: oklab(0.550853 -0.008208 -0.033125); + --color-subtle: oklab(0.436442 -0.012368 -0.044729); + --color-emphasis: oklab(0.218461 -0.012406 -0.039864); + --color-primary: oklab(0.479428 -0.035191 -0.111636); + --color-secondary: oklab(0.613677 -0.025079 -0.065437); + --color-tertiary: oklab(0.367809 -0.026626 -0.097956); + --color-error: oklab(0.499559 0.115162 0.066600); + --color-warning: oklab(0.528919 0.016251 0.103026); + --color-success: oklab(0.503030 -0.080259 0.021719); + --color-border: oklab(0.776085 -0.009713 -0.026566); + --color-link: oklab(0.485173 -0.035448 -0.128511); + --color-highlight: oklab(0.902143 -0.011298 -0.030437); --color-grid-line: color-mix(in srgb, var(--color-primary) 16%, transparent); - --color-action: #c5652a; + --color-action: oklab(0.516800 -0.033898 -0.129915); --font-ui: "Proza Libre", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --font-heading: "Proza Libre", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; @@ -91,23 +91,23 @@ @media (prefers-color-scheme: dark) { :root { - --color-base: #07141c; - --color-surface: #0e202a; - --color-overlay: #152d39; - --color-text: #e5edf0; - --color-muted: #8ea1aa; - --color-subtle: #b7c7ce; - --color-emphasis: #f5fbfd; - --color-primary: #75bfd1; - --color-secondary: #4f91a6; - --color-tertiary: #a8dce8; - --color-error: #ef846f; - --color-warning: #e5a852; - --color-success: #7fcaa8; - --color-border: #2a4856; - --color-link: #f0a06a; - --color-highlight: #193847; + --color-base: oklab(0.176154 -0.007764 -0.032073); + --color-surface: oklab(0.215442 -0.009550 -0.037250); + --color-overlay: oklab(0.285117 -0.013120 -0.061969); + --color-text: oklab(0.952023 -0.004426 -0.015339); + --color-muted: oklab(0.712425 -0.010427 -0.037918); + --color-subtle: oklab(0.850584 -0.011008 -0.036559); + --color-emphasis: oklab(0.986205 -0.002567 -0.006321); + --color-primary: oklab(0.747996 -0.020067 -0.113276); + --color-secondary: oklab(0.644236 -0.026081 -0.109450); + --color-tertiary: oklab(0.860427 -0.009380 -0.067849); + --color-error: oklab(0.726139 0.114649 0.072209); + --color-warning: oklab(0.782530 0.004064 0.111403); + --color-success: oklab(0.780344 -0.086383 0.024957); + --color-border: oklab(0.385469 -0.016889 -0.062851); + --color-link: oklab(0.808828 -0.013072 -0.094844); + --color-highlight: oklab(0.351947 -0.019583 -0.081890); --color-grid-line: color-mix(in srgb, var(--color-primary) 22%, transparent); - --color-action: #e38b4b; + --color-action: oklab(0.740366 -0.013739 -0.116173); } }