update position page design
This commit is contained in:
166
src/index.css
166
src/index.css
@@ -13,33 +13,56 @@
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
/* ── KROW ambient theme ─────────────────────────────────────────────
|
||||
The named tokens the theme is specified in, kept as literal hex so the
|
||||
source values are readable at a glance. Everything below them is the same
|
||||
palette expressed as HSL triplets, which is the form Tailwind consumes —
|
||||
so components keep using `bg-surface`, `text-ink-1`, `border-border` and
|
||||
pick the theme up without a single component being edited.
|
||||
|
||||
Two vocabularies, one palette. Nothing in the app should reach for a raw
|
||||
hex; these exist so the theme has a stated source, not so components can
|
||||
bypass the semantic tokens. */
|
||||
--krow-bg: #F8F8F8;
|
||||
--krow-bg-blue: #E8F0F8;
|
||||
--krow-bg-warm: #F8F8E8;
|
||||
--krow-primary: #0838E0;
|
||||
--krow-text: #101820;
|
||||
--krow-text-secondary: #687386;
|
||||
--krow-text-muted: #8B94A5;
|
||||
--krow-border: #E0E4EA;
|
||||
--krow-border-strong: #D8DDE5;
|
||||
--krow-success: #16A765;
|
||||
--krow-warning: #E7B900;
|
||||
--krow-error: #D64545;
|
||||
|
||||
/* KROW Official Brand Colors */
|
||||
/* Primary: KROW Blue #0A39DF (Pantone 286CP) */
|
||||
/* Primary: KROW Blue #0838E0 */
|
||||
/* Accent: KROW Yellow #F9E547 (Pantone 106CP) */
|
||||
/* Pale Yellow: #F8E08E (Pantone 1205CP) */
|
||||
/* Dark Navy: #333F48 (Pantone 432CP) */
|
||||
/* Mint: #D1E0D7 (Pantone 621CP) */
|
||||
|
||||
--background: 150 10% 96%;
|
||||
--foreground: 210 17% 24%;
|
||||
--background: 0 0% 97%; /* #F8F8F8 — the neutral base */
|
||||
--foreground: 210 33% 9%; /* #101820 */
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 210 17% 24%;
|
||||
--card-foreground: 210 33% 9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 210 17% 24%;
|
||||
--primary: 229 89% 45%;
|
||||
--popover-foreground: 210 33% 9%;
|
||||
--primary: 227 93% 45%; /* #0838E0 */
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--secondary: 224 89% 96%;
|
||||
--secondary-foreground: 224 89% 30%;
|
||||
--muted: 150 10% 93%;
|
||||
--muted-foreground: 210 10% 46%;
|
||||
--accent: 224 89% 94%;
|
||||
--accent-foreground: 224 89% 25%;
|
||||
--destructive: 0 84% 60%;
|
||||
--secondary: 227 89% 96%;
|
||||
--secondary-foreground: 227 89% 30%;
|
||||
--muted: 210 16% 95%;
|
||||
--muted-foreground: 218 13% 47%; /* #687386 */
|
||||
--accent: 227 89% 94%;
|
||||
--accent-foreground: 227 89% 25%;
|
||||
--destructive: 0 64% 55%; /* #D64545 */
|
||||
--destructive-foreground: 0 0% 100%;
|
||||
--border: 150 8% 87%;
|
||||
--input: 150 8% 87%;
|
||||
--ring: 229 89% 45%;
|
||||
--chart-1: 229 89% 45%;
|
||||
--border: 216 19% 90%; /* #E0E4EA */
|
||||
--input: 215 21% 89%; /* #DDE2E9 */
|
||||
--ring: 227 93% 45%;
|
||||
--chart-1: 227 93% 45%;
|
||||
--chart-2: 52 91% 63%;
|
||||
--chart-3: 210 17% 24%;
|
||||
--chart-4: 42 73% 74%;
|
||||
@@ -63,35 +86,43 @@
|
||||
rather than referenced as raw CSS in components. */
|
||||
|
||||
/* Semantic status — used by StatusBadge, Alert, KpiCard trends */
|
||||
--success: 142 71% 36%;
|
||||
--success: 153 77% 37%; /* #16A765 */
|
||||
--success-foreground: 0 0% 100%;
|
||||
--success-muted: 142 60% 95%;
|
||||
--warning: 32 95% 44%;
|
||||
--success-muted: 146 50% 95%; /* #EAF8F0 */
|
||||
--warning: 48 100% 40%; /* #E7B900, darkened for text contrast */
|
||||
--warning-foreground: 0 0% 100%;
|
||||
--warning-muted: 40 96% 94%;
|
||||
--info: 229 89% 45%;
|
||||
--warning-muted: 48 90% 94%;
|
||||
--info: 227 93% 45%;
|
||||
--info-foreground: 0 0% 100%;
|
||||
--info-muted: 224 89% 96%;
|
||||
--neutral: 210 17% 24%;
|
||||
--info-muted: 227 89% 96%;
|
||||
--neutral: 210 33% 9%;
|
||||
--neutral-foreground: 0 0% 100%;
|
||||
--neutral-muted: 210 12% 94%;
|
||||
--destructive-muted: 0 86% 97%;
|
||||
--neutral-muted: 216 14% 94%;
|
||||
--destructive-muted: 0 70% 97%;
|
||||
|
||||
/* Ink scale — the text hierarchy every component uses */
|
||||
--ink-1: 222 47% 11%; /* headings */
|
||||
--ink-2: 215 25% 27%; /* body */
|
||||
--ink-3: 220 9% 46%; /* secondary */
|
||||
--ink-4: 220 9% 64%; /* placeholder / meta */
|
||||
--ink-1: 210 33% 9%; /* #101820 — headings */
|
||||
--ink-2: 216 17% 30%; /* body, one step above secondary */
|
||||
--ink-3: 218 13% 47%; /* #687386 — secondary */
|
||||
--ink-4: 219 13% 60%; /* #8B94A5 — placeholder / meta */
|
||||
|
||||
/* Surfaces */
|
||||
/* Surfaces.
|
||||
Cards stay opaque white by default: the ambient tint is supplied by the
|
||||
canvas behind them, and making every card translucent would cost
|
||||
readability for a difference nobody can name. The `.surface-translucent`
|
||||
utility below exists for the few places a surface genuinely wants the
|
||||
tint to read through it. */
|
||||
--surface: 0 0% 100%;
|
||||
--surface-subtle: 210 20% 98%;
|
||||
--surface-sunken: 220 14% 96%;
|
||||
--surface-sunken: 216 16% 96%;
|
||||
|
||||
/* Elevation — a 4-step scale, tinted with brand blue not neutral black */
|
||||
--shadow-xs: 0 1px 2px 0 rgb(16 24 40 / 0.04);
|
||||
--shadow-sm: 0 1px 3px 0 rgb(16 24 40 / 0.06), 0 1px 2px -1px rgb(16 24 40 / 0.04);
|
||||
--shadow-md: 0 4px 12px -2px rgb(16 24 40 / 0.08), 0 2px 4px -2px rgb(16 24 40 / 0.04);
|
||||
/* Softened for the ambient canvas: with a tinted background providing the
|
||||
separation, a card only needs to lift off it — not cast a shadow that
|
||||
announces itself. `sm` is the reference's own `0 2px 10px / 0.04`. */
|
||||
--shadow-xs: 0 1px 2px 0 rgb(16 24 32 / 0.03);
|
||||
--shadow-sm: 0 2px 10px 0 rgb(16 24 32 / 0.04);
|
||||
--shadow-md: 0 4px 16px -2px rgb(16 24 32 / 0.06), 0 2px 6px -3px rgb(16 24 32 / 0.04);
|
||||
--shadow-lg: 0 12px 28px -6px rgb(16 24 40 / 0.12), 0 4px 10px -4px rgb(16 24 40 / 0.06);
|
||||
--shadow-xl: 0 24px 56px -12px rgb(16 24 40 / 0.18), 0 8px 20px -8px rgb(16 24 40 / 0.08);
|
||||
--shadow-brand: 0 10px 30px -6px rgb(10 57 223 / 0.24), 0 2px 6px -2px rgb(51 63 72 / 0.08);
|
||||
@@ -165,9 +196,64 @@
|
||||
body {
|
||||
@apply bg-background text-foreground font-body;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ambient canvas.
|
||||
*
|
||||
* Cool blue on the left, neutral through the middle, the faintest warm cream
|
||||
* on the right — the atmosphere the whole product sits in. Three decisions
|
||||
* worth stating:
|
||||
*
|
||||
* A fixed pseudo-element rather than a background on `body`. The gradient runs
|
||||
* left to right, so it must be sized to the *viewport*, not to the document —
|
||||
* on a long page a body background stretches and the tint stops landing where
|
||||
* it was drawn. Fixed also means it paints once and never repaints on scroll.
|
||||
*
|
||||
* `z-index: -1` puts it behind everything without entering the layout at all,
|
||||
* so no shell had to grow a wrapper to hold it.
|
||||
*
|
||||
* The stops are close together in lightness on purpose. The reference reads as
|
||||
* "softer", not as "there is a gradient" — at this spread the eye registers
|
||||
* warmth and coolness without resolving a band.
|
||||
*/
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
var(--krow-bg-blue) 0%,
|
||||
#F1F4F7 28%,
|
||||
#F5F6F7 45%,
|
||||
var(--krow-bg) 65%,
|
||||
#F8F8F1 86%,
|
||||
var(--krow-bg-warm) 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* The dark palette is configured (`darkMode: 'class'`) but nothing in the app
|
||||
applies the class today. This keeps the canvas from being a trap the day
|
||||
something does: a fixed light gradient behind a dark theme would wash out
|
||||
every page at once. */
|
||||
.dark body::before {
|
||||
background: hsl(var(--background));
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
/**
|
||||
* A surface that lets the ambient canvas tint read through it.
|
||||
*
|
||||
* Opt-in rather than the default for cards: at 0.82 the tint is present
|
||||
* without body text losing contrast, but applied everywhere it turns the page
|
||||
* into glassmorphism, which is the thing the theme is explicitly not.
|
||||
*/
|
||||
.surface-translucent {
|
||||
background-color: rgb(255 255 255 / 0.82);
|
||||
}
|
||||
|
||||
.glass {
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(24px) saturate(180%);
|
||||
@@ -186,7 +272,7 @@
|
||||
radial-gradient(at 10% 90%, rgba(209, 224, 215, 0.20) 0px, transparent 50%);
|
||||
}
|
||||
.gradient-text {
|
||||
color: #0A39DF;
|
||||
color: #0838E0;
|
||||
}
|
||||
.glow-blue {
|
||||
box-shadow: 0 0 40px rgba(10, 57, 223, 0.15);
|
||||
@@ -220,10 +306,10 @@
|
||||
identical everywhere and never relies on the browser default. */
|
||||
.focus-ring {
|
||||
@apply outline-none ring-offset-2 ring-offset-background
|
||||
focus-visible:ring-2 focus-visible:ring-[#0A39DF]/60;
|
||||
focus-visible:ring-2 focus-visible:ring-[#0838E0]/60;
|
||||
}
|
||||
.focus-ring-inset {
|
||||
@apply outline-none focus-visible:ring-2 focus-visible:ring-[#0A39DF]/60;
|
||||
@apply outline-none focus-visible:ring-2 focus-visible:ring-[#0838E0]/60;
|
||||
}
|
||||
|
||||
/* Skeleton shimmer — a moving highlight reads as loading far better than a
|
||||
@@ -264,9 +350,9 @@
|
||||
*/
|
||||
.krow-astryx {
|
||||
/* The selected indicator rule. KROW blue is the active state. */
|
||||
--color-accent: #0A39DF;
|
||||
--color-accent: #0838E0;
|
||||
/* Tab labels: selected picks up brand, the rest the app's secondary ink. */
|
||||
--color-text-primary: #0A39DF;
|
||||
--color-text-primary: #0838E0;
|
||||
--color-text-secondary: hsl(var(--ink-3));
|
||||
--color-border: hsl(var(--border));
|
||||
/* The hover wash sits *over* the label, so it has to stay translucent — an
|
||||
|
||||
Reference in New Issue
Block a user