zurich_kotak/src/index.css

238 lines
7.4 KiB
CSS

/* ── Zurich Kotak brand typeface ───────────────────────────── */
@font-face {
font-family: 'Zurich Sans';
src: url('./assets/fonts/ZurichSans-Light.otf') format('opentype');
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Zurich Sans';
src: url('./assets/fonts/ZurichSans-Regular.otf') format('opentype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Zurich Sans';
src: url('./assets/fonts/ZurichSans-Medium.otf') format('opentype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
:root {
/* Brand palette lifted from zurichkotak.com */
--zk-blue: #2167ae;
--zk-blue-dark: #1a5490;
--zk-blue-deep: #1a528b;
--zk-navy: #23366f;
--zk-blue-mid: #5495cf;
--zk-blue-light: #91bfe3;
--zk-cyan: #c7ebf9;
--zk-teal: #0e7c74;
--zk-teal-ink: #0b5f59;
--zk-teal-tint: #e3f4f2;
--zk-teal-line: #a5d8d3;
--zk-good: #1f9d63;
--zk-ink: #2b2e31;
--zk-muted: #5d6162;
--zk-grey: #a6adaf;
--zk-line: #dde4e3;
--zk-line-soft: #eceeef;
--zk-tint: #f4f9fc;
--zk-tint-blue: #ebf3fb;
--zk-white: #fff;
--zk-danger: #d32f2f;
/* Amber and red accents already used for people / lapsed renewals, named so
they stop being magic hex literals scattered across four stylesheets. */
--zk-amber: #b5761f;
--zk-amber-ink: #93500f;
--zk-amber-tint: #fdf1e7;
--zk-amber-line: #f0c69a;
--zk-danger-ink: #a3261f;
--zk-danger-tint: #fdeceb;
--zk-danger-line: #f0c2bd;
/* ── Shape, depth, motion ────────────────────────────────────
One scale, used everywhere. The palette above is untouched; every shadow
below is the brand navy at low alpha, so depth reads as part of the brand
rather than as generic grey haze. */
--r-xs: 6px;
--r-sm: 8px;
--r-md: 12px;
--r-lg: 16px;
--r-xl: 20px;
--r-pill: 999px;
--sh-xs: 0 1px 2px rgba(35, 54, 111, 0.05);
--sh-sm: 0 1px 2px rgba(35, 54, 111, 0.05), 0 2px 6px -2px rgba(35, 54, 111, 0.07);
--sh-md: 0 1px 2px rgba(35, 54, 111, 0.05), 0 10px 24px -8px rgba(35, 54, 111, 0.14);
--sh-lg: 0 2px 6px rgba(35, 54, 111, 0.06), 0 20px 42px -14px rgba(35, 54, 111, 0.22);
--ring: 0 0 0 3px rgba(33, 103, 174, 0.16);
--ease: cubic-bezier(0.4, 0, 0.2, 1);
--t-fast: 0.14s var(--ease);
--t: 0.2s var(--ease);
--grad-blue: linear-gradient(135deg, var(--zk-blue) 0%, var(--zk-blue-deep) 100%);
--grad-blue-hover: linear-gradient(135deg, var(--zk-blue-dark) 0%, var(--zk-navy) 100%);
/* ── TYPE SCALE ───────────────────────────────────────────────
The app had FIFTY-FOUR distinct font sizes, and forty of them sat
between 0.58rem and 0.95rem — a three-pixel band. The most-used size
was 0.78rem, which is 12.5px of body copy. That is not a hierarchy;
it is a fog of small grey text, and it is exactly why the screen read
as a decade-old enterprise tool. Nothing could be emphasised, because
everything was already the same size.
Nine steps, with real jumps between them. Body sits at 15px, labels
at 14, and 12px is the FLOOR — reserved for uppercase eyebrows, never
for anything a person has to read. Size does the prioritising so the
reader does not have to. */
--fs-3xs: 0.75rem; /* 12px — uppercase eyebrows only */
--fs-2xs: 0.8125rem; /* 13px — timestamps, meta */
--fs-xs: 0.875rem; /* 14px — field labels */
--fs-sm: 0.9375rem; /* 15px — body, field values */
--fs-md: 1rem; /* 16px — emphasis */
--fs-lg: 1.125rem; /* 18px — panel titles */
--fs-xl: 1.375rem; /* 22px — section headings */
--fs-2xl: 1.75rem; /* 28px — page title */
--fs-3xl: 2.25rem; /* 36px — the one number that matters */
--lh-tight: 1.25;
--lh-snug: 1.4;
--lh-normal: 1.55;
--fw-normal: 400;
--fw-medium: 500;
--fw-semi: 600;
/* ── SPACING ──────────────────────────────────────────────────
One rhythm. Panels breathe at 24-28px rather than 14-18px, which is
the other half of why this felt cramped. */
--sp-1: 4px;
--sp-2: 8px;
--sp-3: 12px;
--sp-4: 16px;
--sp-5: 20px;
--sp-6: 24px;
--sp-7: 32px;
--sp-8: 40px;
--sp-9: 56px;
/* Display and body are the SAME brand face — Zurich Sans has no bold,
so headings and figures lean on weight 500 and tighter tracking, set per
use, not on a second family. */
--font-display: 'Zurich Sans', Arial, Helvetica, sans-serif;
--font-zurich: 'Zurich Sans', Arial, Helvetica, sans-serif;
--font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
font-family: var(--font-zurich);
/* The root MUST stay an absolute size — every --fs-* token is rem, so
sizing the root from one of them is circular. */
font-size: 16px;
line-height: var(--lh-normal);
color: var(--zk-ink);
/* ONE CANVAS. The app used to be white cards floating on a grey-blue
ground — the generic admin-template look. The content ground is white
now; the sidebar is the only tinted surface, and sections are separated
by hairlines and space rather than boxed in shadowed cards. */
background: var(--zk-white);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
* {
box-sizing: border-box;
}
html,
body,
#root {
height: 100%;
}
body {
margin: 0;
background: var(--zk-white);
}
button,
input,
select,
textarea {
font: inherit;
color: inherit;
}
/* One focus treatment for the whole console: a soft brand ring, never the
browser's default outline halfway through a card's rounded corner. */
:focus-visible {
outline: 2px solid var(--zk-blue);
outline-offset: 2px;
}
::selection {
background: var(--zk-tint-blue);
color: var(--zk-blue-dark);
}
/* Scrollbars, toned to the palette. Chrome/Safari take the ::-webkit rules,
Firefox the standard properties. */
* {
scrollbar-width: thin;
scrollbar-color: var(--zk-line) transparent;
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
border: 3px solid transparent;
border-radius: var(--r-pill);
background-clip: content-box;
background-color: var(--zk-line);
}
::-webkit-scrollbar-thumb:hover {
background-color: var(--zk-grey);
}
@keyframes zk-rise {
/* Opacity ONLY. A translateY here promoted every element it touched to a GPU
layer, and text composited on a transformed layer renders blurry in Chrome
on Linux — which made the whole app look soft. The fade alone gives the
entrance without ever moving text onto a fractional-pixel layer. */
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes zk-shimmer {
from { background-position: -420px 0; }
to { background-position: 420px 0; }
}
/* Motion is decoration here — every animation is an entrance or a hover, so
dropping them costs nothing. */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
scroll-behavior: auto !important;
}
}