Add Positive Pay, statement guide v1.0, onboarding, and switch every feature on
- Positive Pay on the 12 Oct /pps contract (account number, not account ID): OTP enrollment, cheque submit, saved cheques, detail and stop payment. Full flow passed on the phone against mobile-banking-backend.lincpay. - Statement & Mini Statement guide v1.0 (14 Oct): mini statement JSON on Home and the Statement screen; dated PDF export with the password rule. - Onboarding slides and splash screen, Inter font, shared Icon and TypewriterText components, nearby branches via OpenStreetMap. - Every feature switched on; the 14 Oct switch set is kept in featureConfig.stage-2026-10-14.ts. Loans run on demo data until the backend has /loans routes. - npm run android wraps run-android for shells spawned from VS Code. - OpenProject work packages updated to 14-10-2026 status, with screenshots of Positive Pay, statement, loans and cards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5fbd13ba12
commit
f960a119e8
+132
-119
@@ -21,11 +21,18 @@
|
||||
* it is added to the other, which is deliberate — a role that only exists in
|
||||
* light mode is a screen that breaks in dark mode.
|
||||
*
|
||||
* ── THE DESIGN LANGUAGE ─────────────────────────────────────────────────────
|
||||
* Royal blue on white, with deep navy for the full-bleed moments. Clean,
|
||||
* airy, institutional: a white card on a cool blue-grey ground, one vivid blue
|
||||
* for everything tappable, and navy reserved for the sign-in wash and the
|
||||
* header band on Home. The neutrals are tinted a few degrees toward the brand
|
||||
* hue, so the greys read as part of the blue family rather than as flat grey.
|
||||
*
|
||||
* ── THE RULES THESE VALUES SATISFY ──────────────────────────────────────────
|
||||
* Every value was measured with a WCAG 2.1 validator, not chosen by eye, and
|
||||
* the measured ratio is stated next to it. The constraints:
|
||||
*
|
||||
* - Brand navy #124577 is locked in light mode. It stays the identity.
|
||||
* - Brand blue #0B57D0 is the identity in light mode.
|
||||
* - Body text and any figure showing money reach AA (4.5:1), validated
|
||||
* against all three text-bearing surfaces — `surface`, `background` and
|
||||
* `surfaceMuted` — with a margin over 4.5 so device rounding cannot drop
|
||||
@@ -42,8 +49,8 @@
|
||||
* DARK INK, because a dark theme's tones are lightened to be legible on a dark
|
||||
* ground, and white on a lightened tone fails badly:
|
||||
*
|
||||
* dark mode, white on `brand` 2.61:1 FAILS
|
||||
* dark mode, ink on `brand` 7.08:1 AA
|
||||
* dark mode, white on `brand` 2.39:1 FAILS
|
||||
* dark mode, ink on `brand` 7.75:1 AA
|
||||
*
|
||||
* This is why a button must use `theme.colors.textOnBrand` and never a
|
||||
* hardcoded '#FFF'. A white label is correct in light mode and unreadable in
|
||||
@@ -97,8 +104,15 @@ export type Palette = {
|
||||
brandDeep: string;
|
||||
brandSurface: string;
|
||||
brandBorder: string;
|
||||
/** The full-bleed brand wash — sign-in and registration. */
|
||||
/** The full-bleed navy wash — sign-in, registration, the Home header band. */
|
||||
brandGradient: [string, string, string];
|
||||
/**
|
||||
* The vivid blue gradient for a hero object — the account card, a promo
|
||||
* banner. Brighter than `brandGradient`, which is a backdrop; this is a
|
||||
* thing sitting on the page. Carries the same on-brand tiers, and the
|
||||
* contrast script validates them against its lightest stop too.
|
||||
*/
|
||||
heroGradient: [string, string, string];
|
||||
|
||||
/* ── on the brand wash ────────────────────────────────────────────────── */
|
||||
onBrandPrimary: string;
|
||||
@@ -116,12 +130,12 @@ export type Palette = {
|
||||
/**
|
||||
* The tone that sits on `accentFill`.
|
||||
*
|
||||
* Dark ink in BOTH ramps — the vivid brass is light enough that white fails
|
||||
* on it either way (2.26:1 in light, 1.99:1 in dark). It needs a role of its
|
||||
* own because the role that happens to BE dark ink differs between the two:
|
||||
* `textPrimary` in light, `textOnFill` in dark. Without this, a component
|
||||
* drawing a brass fill would need a `theme.isDark` branch to pick the right
|
||||
* one, which is the exact thing these roles exist to remove.
|
||||
* Dark ink in BOTH ramps — the vivid gold is light enough that white fails
|
||||
* on it either way. It needs a role of its own because the role that
|
||||
* happens to BE dark ink differs between the two: `textPrimary` in light,
|
||||
* `textOnFill` in dark. Without this, a component drawing a gold fill would
|
||||
* need a `theme.isDark` branch to pick the right one, which is the exact
|
||||
* thing these roles exist to remove.
|
||||
*/
|
||||
textOnAccentFill: string;
|
||||
accentSurface: string;
|
||||
@@ -177,79 +191,76 @@ export type Palette = {
|
||||
* ══════════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
export const light: Palette = {
|
||||
/* Warm neutrals, tinted toward the brand hue (~2°) at 14% saturation so
|
||||
* the greys read as part of the red family rather than as flat web grey.
|
||||
* Each step keeps the luminance of the navy-tinted ramp it replaced, so
|
||||
* every text-on-surface ratio in this file is unchanged.
|
||||
* Steps are spaced by CIE L*, which is the honest metric between two
|
||||
* near-white fills — a WCAG ratio is not meaningful there. */
|
||||
background: '#F4F0F0', // L* 95.3 app background
|
||||
/* Cool neutrals, tinted toward the brand blue. A white card on a pale
|
||||
* blue-grey ground is the whole look: the step between them is small, so
|
||||
* cards are separated by a real border and a soft lift, not by a heavy
|
||||
* tonal jump. */
|
||||
background: '#F3F6FB', // app background — cool, barely-blue
|
||||
backgroundElevated: '#FFFFFF',
|
||||
backgroundGradient: ['#FFFFFF', '#FAF9F8', '#F4F0F0'],
|
||||
surface: '#FFFFFF', // L* 100.0 cards
|
||||
surfaceMuted: '#EDE8E7', // L* 92.3 pressed rows, wells
|
||||
surfaceSunk: '#E5DCDC', // L* 88.6 non-text only
|
||||
border: '#E3DAD9', // 1.32:1 on a card, so it is actually visible
|
||||
borderStrong: '#CDBDBD',
|
||||
backgroundGradient: ['#FFFFFF', '#F8FAFD', '#F3F6FB'],
|
||||
surface: '#FFFFFF', // cards
|
||||
surfaceMuted: '#EDF1F8', // pressed rows, wells, input fills
|
||||
surfaceSunk: '#E2E8F2', // non-text only
|
||||
border: '#DCE3EE', // 1.29:1 on a card, so it is actually visible
|
||||
borderStrong: '#C7D2E1', // 1.53:1
|
||||
|
||||
textPrimary: '#0D1B2A', // 17.39 / 15.47 / 14.32
|
||||
textSecondary: '#48596B', // 7.20 / 6.40 / 5.93 — a neutral slate, NOT
|
||||
// the brand navy, which is what it used to be
|
||||
// and why the whole app read as one flat colour
|
||||
textMuted: '#5A697A', // 5.62 / 5.00 / 4.63
|
||||
textOnFill: '#FFFFFF', // white on brand red is 5.25:1
|
||||
textPrimary: '#0B1B3F', // 16.90 / 15.60 / 14.92 — a navy ink, not black
|
||||
textSecondary: '#4A5872', // 7.17 / 6.62 / 6.33
|
||||
textMuted: '#5C6A82', // 5.47 / 5.05 / 4.83
|
||||
textOnFill: '#FFFFFF', // white on brand blue is 6.39:1
|
||||
|
||||
brand: '#CF2927', // ◀ LOCKED IDENTITY — 5.25 / 4.67 / 4.32. Below
|
||||
// AA on surfaceMuted, so body text on a muted
|
||||
// well should use textPrimary, not brand
|
||||
brandLight: '#E0453F', // decorative only — too light for white text
|
||||
brandDark: '#A81F1D', // pressed fill; white on it 7.29:1
|
||||
brandDeep: '#6E1312',
|
||||
brandSurface: '#FDF0EF', // brand on it 4.72:1; separation from a card 1.11
|
||||
brandBorder: '#F0B9B6', // 1.70:1 against a card
|
||||
// Deliberately DEEPER than `brand`. #CF2927 is too light a red to carry the
|
||||
// translucent on-brand tiers (white @0.75 on it is 3.53:1), so the wash
|
||||
// starts at a darker red, where every tier below clears AA.
|
||||
brandGradient: ['#A81E1C', '#8F1918', '#731413'],
|
||||
brand: '#0B57D0', // ◀ IDENTITY — 6.39 / 5.90 / 5.64
|
||||
brandLight: '#3D7BEA', // decorative only — a gradient stop, an illustration
|
||||
brandDark: '#0845A8', // pressed fill; white on it 8.65:1
|
||||
brandDeep: '#06296E',
|
||||
brandSurface: '#EAF1FD', // brand on it 5.63:1; separation from a card 1.14
|
||||
brandBorder: '#BBD0F6', // 1.56:1 against a card
|
||||
// Deep navy, not the brand blue. It is a BACKDROP — the sign-in screen and
|
||||
// the Home header — so it has to sit behind a blue button and white text
|
||||
// without competing with either. Every on-brand tier clears AA on it with a
|
||||
// wide margin.
|
||||
brandGradient: ['#0A2F78', '#072260', '#051843'],
|
||||
// The vivid one, for an object on the page. The lightest stop is the
|
||||
// binding case for the translucent tiers: white @0.75 on #0F4CC9 is 4.78:1.
|
||||
heroGradient: ['#0F4CC9', '#0B3FAE', '#082F86'],
|
||||
|
||||
/* On the red wash. Each tier is validated against the LIGHTEST stop
|
||||
* (#A81E1C), which is the worst case.
|
||||
/* On the navy wash. Each tier is validated against the LIGHTEST stop of
|
||||
* both gradients, which is the worst case.
|
||||
*
|
||||
* THE TIERS DO NOT STACK. A translucent fill lightens the wash beneath it,
|
||||
* so a translucent tone on a translucent fill has less to work with.
|
||||
* Text directly on the wash may use any tier. Text on a FILL takes the
|
||||
* solid tone, always. */
|
||||
onBrandPrimary: '#FFFFFF', // 7.32:1 on the lightest stop
|
||||
onBrandSecondary: 'rgba(255, 255, 255, 0.85)', // 5.64:1 — body-safe
|
||||
onBrandMuted: 'rgba(255, 255, 255, 0.75)', // 4.69:1 — still AA
|
||||
onBrandSurface: 'rgba(255, 255, 255, 0.12)', // white on it 5.94:1
|
||||
onBrandSurfaceStrong: 'rgba(255, 255, 255, 0.18)', // white on it 5.22:1 —
|
||||
// this is the ceiling
|
||||
onBrandPrimary: '#FFFFFF', // 12.42:1 wash, 7.33 hero
|
||||
onBrandSecondary: 'rgba(255, 255, 255, 0.85)', // body-safe on both
|
||||
onBrandMuted: 'rgba(255, 255, 255, 0.75)', // 4.78:1 on the hero stop
|
||||
onBrandSurface: 'rgba(255, 255, 255, 0.12)',
|
||||
onBrandSurfaceStrong: 'rgba(255, 255, 255, 0.18)', // the ceiling for a
|
||||
// fill carrying white
|
||||
onBrandBorder: 'rgba(255, 255, 255, 0.24)',
|
||||
|
||||
/* Brass. Navy and gold is the pairing a bank has used for a century, and it
|
||||
* deliberately avoids the acid-green / violet-on-near-black look. Accent and
|
||||
* success used to be the same #10B981, so a promotional highlight and a
|
||||
* success state were indistinguishable. */
|
||||
accent: '#876013', // 5.66 / 5.03 / 4.66 — and white-on-it 5.66:1
|
||||
/* Gold, for rewards and offers. Blue and gold is a pairing a bank has used
|
||||
* for a century, and it keeps a promotional highlight visibly different
|
||||
* from a success state. */
|
||||
accent: '#876013', // 5.66 / 5.22 / 4.99 — and white-on-it 5.66:1
|
||||
accentStrong: '#6B4C0F',
|
||||
accentFill: '#DDA22C', // ink on it 7.69:1; WHITE ON IT IS 2.26:1
|
||||
textOnAccentFill: '#0D1B2A', // 7.69:1 — the same ink as `textPrimary` here
|
||||
accentFill: '#E9B23C', // ink on it 8.77:1; WHITE ON IT IS 1.93:1
|
||||
textOnAccentFill: '#0B1B3F', // 8.77:1 — the same ink as `textPrimary` here
|
||||
accentSurface: '#FEF7EA',
|
||||
accentBorder: '#EBCB8A',
|
||||
|
||||
/* Each tone is the lightest — so most vivid — value that still clears 4.6:1
|
||||
* on all three text-bearing surfaces. */
|
||||
success: '#0C7645', // 5.69 / 5.06 / 4.68
|
||||
success: '#0C7645', // 5.69 / 5.25 / 5.02
|
||||
successSurface: '#E6F5ED',
|
||||
successBorder: '#9FD8BC',
|
||||
warning: '#955A00', // 5.61 / 4.99 / 4.62
|
||||
warning: '#955A00', // 5.61 / 5.18 / 4.96
|
||||
warningSurface: '#FDF3E3',
|
||||
warningBorder: '#EFCB8C',
|
||||
danger: '#C52A1F', // 5.64 / 5.01 / 4.64
|
||||
danger: '#C52A1F', // 5.64 / 5.20 / 4.98
|
||||
dangerSurface: '#FCEBE9',
|
||||
dangerBorder: '#EFB4AE',
|
||||
info: '#0F6CAA', // 5.61 / 4.99 / 4.61
|
||||
info: '#0F6CAA', // 5.61 / 5.18 / 4.95
|
||||
infoSurface: '#E8F1F8',
|
||||
infoBorder: '#A7C9E2',
|
||||
|
||||
@@ -265,9 +276,11 @@ export const light: Palette = {
|
||||
indigo: { tone: '#4F46E5', surface: '#ECEAFE' }, // 5.85 / 5.07 / 1.13
|
||||
},
|
||||
|
||||
overlay: 'rgba(13, 27, 42, 0.55)',
|
||||
overlay: 'rgba(11, 27, 63, 0.55)',
|
||||
white: '#FFFFFF',
|
||||
shadow: '#0D1B2A',
|
||||
// A navy shadow rather than black: on a blue-grey ground a black shadow
|
||||
// reads as dirt, a navy one reads as depth.
|
||||
shadow: '#0B1B3F',
|
||||
};
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════════════════
|
||||
@@ -275,76 +288,76 @@ export const light: Palette = {
|
||||
*
|
||||
* Not the light ramp inverted. Three things genuinely change:
|
||||
*
|
||||
* 1. Every tone LIGHTENS. #124577 on a dark ground is 1.6:1 — the brand
|
||||
* navy is invisible in dark mode, so the interactive brand becomes a
|
||||
* lighter navy and the identity is carried by hue, not by that exact hex.
|
||||
* 1. Every tone LIGHTENS. #0B57D0 on a dark ground is under 3:1, so the
|
||||
* interactive brand becomes a lighter periwinkle blue and the identity
|
||||
* is carried by hue, not by that exact hex.
|
||||
* 2. `textOnFill` becomes DARK INK. See the note at the top of this file.
|
||||
* 3. Depth stops coming from shadow. A shadow on a near-black ground is
|
||||
* invisible, so separation is carried by the surface steps and the
|
||||
* borders below — which is why each step is measured against its
|
||||
* neighbour and not in isolation.
|
||||
*
|
||||
* The ground is warm red-tinted rather than neutral black: it keeps the app in the
|
||||
* brand family, and pure #000 under light text is the classic recipe for
|
||||
* halation on an OLED panel.
|
||||
* The ground is a deep midnight navy rather than neutral black: it keeps the
|
||||
* app in the brand family, and pure #000 under light text is the classic
|
||||
* recipe for halation on an OLED panel.
|
||||
* ══════════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
export const dark: Palette = {
|
||||
background: '#171312',
|
||||
backgroundElevated: '#241C1C',
|
||||
backgroundGradient: ['#241C1C', '#1E1817', '#171312'],
|
||||
surface: '#241C1C',
|
||||
surfaceMuted: '#2F2625',
|
||||
surfaceSunk: '#3B2F2E', // non-text; only textPrimary 11.31, textSecondary
|
||||
// 7.39 and brand 4.93 are legible on it
|
||||
border: '#4A3A3A', // 1.57:1 against a card
|
||||
borderStrong: '#634F4E', // 2.17:1
|
||||
background: '#0A0F1C',
|
||||
backgroundElevated: '#121A2B',
|
||||
backgroundGradient: ['#121A2B', '#0E1523', '#0A0F1C'],
|
||||
surface: '#121A2B',
|
||||
surfaceMuted: '#1A2338',
|
||||
surfaceSunk: '#222D46', // non-text; only textPrimary 12.04, textSecondary
|
||||
// 7.86 and brand 5.74 are legible on it
|
||||
border: '#28344E', // 1.40:1 against a card
|
||||
borderStrong: '#3A4866', // 1.90:1
|
||||
|
||||
textPrimary: '#EAF1F8', // 14.63 / 16.24 / 12.99
|
||||
textSecondary: '#B6C6D6', // 9.55 / 10.60 / 8.48
|
||||
textMuted: '#93A6B9', // 6.66 / 7.40 / 5.92
|
||||
textOnFill: '#0B1420', // ink on `brand` 7.44:1 — white would fail
|
||||
textPrimary: '#EAF1F8', // 15.26 / 16.79 / 13.74
|
||||
textSecondary: '#B6C6D6', // 9.96 / 10.96 / 8.97
|
||||
textMuted: '#93A6B9', // 6.95 / 7.65 / 6.26
|
||||
textOnFill: '#0B1420', // ink on `brand` 7.75:1 — white would fail
|
||||
|
||||
brand: '#F28580', // 6.70 / 7.44 / 5.95
|
||||
brandLight: '#F7A9A5',
|
||||
brandDark: '#D9564F',
|
||||
brandDeep: '#2A0E0E',
|
||||
brandSurface: '#3A1E24', // brand on it 6.07:1; separation from a card 1.10
|
||||
brandBorder: '#663038', // 1.62:1 against a card
|
||||
// The wash DARKENS in dark mode rather than lightening. White on the
|
||||
// lightest stop is 11.24:1, so every on-brand tier below clears AA with
|
||||
// room to spare — they were calibrated against the far lighter light-mode
|
||||
// wash, which is the harder case.
|
||||
brandGradient: ['#6E1E1F', '#521616', '#380F0F'],
|
||||
brand: '#7AA7FF', // 7.28 / 8.01 / 6.56
|
||||
brandLight: '#A6C4FF',
|
||||
brandDark: '#4F86F0', // pressed; ink on it 5.29:1
|
||||
brandDeep: '#0A1A3D',
|
||||
brandSurface: '#15264A', // brand on it 6.25:1; separation from a card 1.17
|
||||
brandBorder: '#2A4478', // 1.82:1 against a card
|
||||
// The wash stays a saturated navy in dark mode, a step brighter than the
|
||||
// ground so the header band still reads as a band.
|
||||
brandGradient: ['#14378A', '#0E296B', '#091B4A'],
|
||||
// Lightest stop: white @0.75 on #1E4FB8 is 4.87:1.
|
||||
heroGradient: ['#1E4FB8', '#163F99', '#0F2E73'],
|
||||
|
||||
onBrandPrimary: '#FFFFFF', // 11.24:1 on the lightest stop
|
||||
onBrandSecondary: 'rgba(255, 255, 255, 0.85)', // 8.48:1
|
||||
onBrandMuted: 'rgba(255, 255, 255, 0.75)', // 6.96:1
|
||||
onBrandSurface: 'rgba(255, 255, 255, 0.12)', // white on it 8.24:1
|
||||
onBrandPrimary: '#FFFFFF', // 10.81 wash, 7.33 hero
|
||||
onBrandSecondary: 'rgba(255, 255, 255, 0.85)',
|
||||
onBrandMuted: 'rgba(255, 255, 255, 0.75)',
|
||||
onBrandSurface: 'rgba(255, 255, 255, 0.12)',
|
||||
onBrandSurfaceStrong: 'rgba(255, 255, 255, 0.18)',
|
||||
onBrandBorder: 'rgba(255, 255, 255, 0.24)',
|
||||
|
||||
accent: '#E8BC63', // 9.37 / 10.40 / 8.32
|
||||
accent: '#E8BC63', // 9.77 / 10.75 / 8.80
|
||||
accentStrong: '#F0CE8A',
|
||||
accentFill: '#DDA22C', // the same fill as light mode, and the same rule:
|
||||
accentFill: '#E9B23C', // the same fill as light mode, and the same rule:
|
||||
// it takes ink, never white
|
||||
textOnAccentFill: '#0B1420', // 8.17:1. Note this is NOT `textPrimary`, which
|
||||
// is near-white here and only 1.99:1 on it —
|
||||
textOnAccentFill: '#0B1420', // 9.60:1. Note this is NOT `textPrimary`, which is
|
||||
// near-white here and only 1.69:1 on the gold —
|
||||
// the reason this role exists at all
|
||||
accentSurface: '#332A18', // accent on it 7.95:1; separation 1.18
|
||||
accentSurface: '#2E2817', // accent on it 8.24:1; separation 1.19
|
||||
accentBorder: '#5A4520',
|
||||
|
||||
success: '#4FC98D', // 7.99 / 8.87 / 7.10
|
||||
successSurface: '#143223', // success on it 6.67:1; separation 1.20
|
||||
success: '#4FC98D', // 8.34 / 9.17 / 7.51
|
||||
successSurface: '#123026', // success on it 6.82:1; separation 1.22
|
||||
successBorder: '#245C40',
|
||||
warning: '#E3AC4E', // 8.16 / 9.05 / 7.24
|
||||
warningSurface: '#322717', // warning on it 7.15:1; separation 1.14
|
||||
warning: '#E3AC4E', // 8.51 / 9.38 / 7.66
|
||||
warningSurface: '#2E2717', // warning on it 7.24:1
|
||||
warningBorder: '#57431D',
|
||||
danger: '#F2827A', // 6.55 / 7.27 / 5.81
|
||||
dangerSurface: '#472420', // danger on it 5.35:1; separation 1.22
|
||||
dangerBorder: '#5E2E2A',
|
||||
info: '#63B0E3', // 7.02 / 7.80 / 6.24
|
||||
infoSurface: '#152C3A', // info on it 6.09:1; separation 1.15
|
||||
danger: '#F2827A', // 6.83 / 7.51 / 6.15
|
||||
dangerSurface: '#3F2228', // danger on it 5.61:1
|
||||
dangerBorder: '#5E2E34',
|
||||
info: '#63B0E3', // 7.32 / 8.06 / 6.60
|
||||
infoSurface: '#132B3E', // info on it 6.13:1; separation 1.19
|
||||
infoBorder: '#265066',
|
||||
|
||||
/* Same hues, lightened onto the dark card, each with a deepened tint. The
|
||||
@@ -352,19 +365,19 @@ export const dark: Palette = {
|
||||
* across themes, so a tile a customer knows as the violet one stays violet.
|
||||
* Ratios: tone-on-card / tone-on-its-own-tint / tint-vs-card. */
|
||||
category: {
|
||||
blue: { tone: '#7FA8F5', surface: '#1A2544' }, // 7.13 / 5.34 / 1.14
|
||||
green: { tone: '#4FC98D', surface: '#143223' }, // 7.99 / 6.67 / 1.20
|
||||
violet: { tone: '#C08CF0', surface: '#2A1D3D' }, // 7.28 / 5.86 / 1.11
|
||||
amber: { tone: '#E3AC4E', surface: '#322717' }, // 8.16 / 7.15 / 1.14
|
||||
pink: { tone: '#F58AB4', surface: '#3A1D2C' }, // 7.28 / 6.59 / 1.11
|
||||
sky: { tone: '#63B0E3', surface: '#152C3A' }, // 7.02 / 6.09 / 1.15
|
||||
teal: { tone: '#3FC5BC', surface: '#0F2E2C' }, // 7.60 / 6.63 / 1.13
|
||||
indigo: { tone: '#A5A0FB', surface: '#221F42' }, // 7.35 / 5.72 / 1.12
|
||||
blue: { tone: '#7FA8F5', surface: '#1A2A50' }, // 7.30 / 5.92 / 1.23
|
||||
green: { tone: '#4FC98D', surface: '#123026' }, // 8.34 / 6.82 / 1.22
|
||||
violet: { tone: '#C08CF0', surface: '#2A1F45' }, // 6.83 / 5.98 / 1.14
|
||||
amber: { tone: '#E3AC4E', surface: '#2E2717' }, // 8.51 / 7.24 / 1.19
|
||||
pink: { tone: '#F58AB4', surface: '#371F35' }, // 7.59 / 6.51 / 1.17
|
||||
sky: { tone: '#63B0E3', surface: '#132B3E' }, // 7.32 / 6.13 / 1.19
|
||||
teal: { tone: '#3FC5BC', surface: '#0F2E33' }, // 8.21 / 6.80 / 1.21
|
||||
indigo: { tone: '#A5A0FB', surface: '#22224A' }, // 7.47 / 6.46 / 1.16
|
||||
},
|
||||
|
||||
// Heavier than the light scrim: the sheet beneath it is dark too, so the
|
||||
// scrim has less tonal distance to work with.
|
||||
overlay: 'rgba(4, 9, 15, 0.72)',
|
||||
overlay: 'rgba(3, 7, 18, 0.72)',
|
||||
white: '#FFFFFF',
|
||||
shadow: '#000000',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user