UI: warm daylight design system (Tailwind v4 @theme palette, gh-* component classes, watercolor grain, Zen Maru Gothic + Klee One fonts), animated SSR-safe GhibliBackground (drifting clouds, meadow hills, soot sprites), and a full reskin of navbar, connect button, dapp page, loan cards, settings modal, and readme. Fixes the bg-white-on-dark loan-card inconsistency. Web3/business logic untouched. Docs: converted docs/ into an Obsidian vault (frontmatter, [[wikilinks]], callouts, Home MOC, folders Architecture/Operations/Audits) and added a full-project audit note (Project Audit 2026-06). Redacted a real leaked Schedy key value from the security audit example (rotate it at Schedy). Also commits the previously-untracked server layer: app/api (cron + tasks routes) and lib (redis, ssrf-guard, task-store). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
276 lines
9.2 KiB
CSS
276 lines
9.2 KiB
CSS
@import "tailwindcss";
|
|
|
|
/* =====================================================================
|
|
MortgageFi — "Studio Ghibli" daylight theme
|
|
A warm, painterly design system: meadow greens, sky blues, parchment
|
|
creams, sunset apricot. Soft rounded shapes, gentle motion, no harsh
|
|
edges. Inspired by Miyazaki landscapes.
|
|
===================================================================== */
|
|
|
|
@theme {
|
|
/* Palette ---------------------------------------------------------- */
|
|
--color-sky: #a9d8ef; /* clear daylight sky */
|
|
--color-sky-deep: #6fb2d6; /* deeper sky / water */
|
|
--color-cloud: #fbf6ea; /* warm parchment / cloud white */
|
|
--color-cloud-soft: #f3e8cf; /* aged paper */
|
|
--color-forest: #6f9a5a; /* Totoro meadow green */
|
|
--color-forest-deep: #466a3a; /* deep forest */
|
|
--color-moss: #9cb87f; /* soft moss */
|
|
--color-sunset: #e89a5e; /* warm apricot sun */
|
|
--color-sunset-soft: #f4c89a; /* hazy sunset glow */
|
|
--color-earth: #8a6d52; /* warm bark brown */
|
|
--color-ink: #3b352a; /* warm charcoal text */
|
|
--color-ink-soft: #6b6051; /* muted text */
|
|
--color-petal: #e7a39b; /* soft sakura pink */
|
|
--color-sun: #f4d27a; /* sunflower yellow */
|
|
--color-line: #e3d4b3; /* hairline on parchment */
|
|
--color-line-soft: #efe6cf; /* faint divider */
|
|
--color-danger: #c2622f; /* terracotta warning */
|
|
--color-danger-soft: #f6e3d2;
|
|
|
|
/* Typography ------------------------------------------------------- */
|
|
--font-sans: var(--font-zen), ui-sans-serif, system-ui, sans-serif;
|
|
--font-display: var(--font-klee), var(--font-zen), serif;
|
|
|
|
/* Soft shadows ----------------------------------------------------- */
|
|
--shadow-soft: 0 10px 30px -12px rgba(58, 51, 38, 0.35);
|
|
--shadow-float: 0 18px 40px -16px rgba(58, 51, 38, 0.45);
|
|
|
|
/* Named animations (usable as `animate-drift`, etc.) ---------------- */
|
|
--animate-drift: drift 60s linear infinite;
|
|
--animate-sway: sway 7s ease-in-out infinite;
|
|
--animate-rise: rise 14s ease-in-out infinite;
|
|
--animate-breathe: breathe 6s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes drift {
|
|
from { transform: translateX(-12vw); }
|
|
to { transform: translateX(112vw); }
|
|
}
|
|
|
|
@keyframes sway {
|
|
0%, 100% { transform: translateY(0) rotate(-1.5deg); }
|
|
50% { transform: translateY(-8px) rotate(1.5deg); }
|
|
}
|
|
|
|
/* soot-sprite float: rise upward while swaying side to side, then fade */
|
|
@keyframes rise {
|
|
0% { transform: translate(0, 0) scale(0.9); opacity: 0; }
|
|
10% { opacity: 0.7; }
|
|
50% { transform: translate(14px, -42vh) scale(1); opacity: 0.55; }
|
|
90% { opacity: 0.4; }
|
|
100% { transform: translate(-10px, -82vh) scale(0.85); opacity: 0; }
|
|
}
|
|
|
|
@keyframes breathe {
|
|
0%, 100% { transform: scale(1); opacity: 0.9; }
|
|
50% { transform: scale(1.04); opacity: 1; }
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
Base
|
|
------------------------------------------------------------------- */
|
|
html {
|
|
color-scheme: light;
|
|
}
|
|
|
|
body {
|
|
font-family: var(--font-sans);
|
|
color: var(--color-ink);
|
|
/* layered daylight sky: warm horizon glow rising into clear blue */
|
|
background:
|
|
radial-gradient(120% 80% at 50% 118%, var(--color-sunset-soft) 0%, transparent 42%),
|
|
linear-gradient(180deg, #bfe6f5 0%, #cfeaf2 38%, #e8f1e0 72%, #f3ecd6 100%);
|
|
background-attachment: fixed;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* faint watercolor-paper grain over everything */
|
|
body::after {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: -1;
|
|
pointer-events: none;
|
|
opacity: 0.05;
|
|
mix-blend-mode: multiply;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
|
|
}
|
|
|
|
::selection {
|
|
background: var(--color-sun);
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
/* gentle, rounded scrollbar to match the soft theme */
|
|
* {
|
|
scrollbar-color: var(--color-moss) transparent;
|
|
}
|
|
*::-webkit-scrollbar { width: 10px; height: 10px; }
|
|
*::-webkit-scrollbar-thumb {
|
|
background: var(--color-moss);
|
|
border-radius: 9999px;
|
|
border: 2px solid transparent;
|
|
background-clip: content-box;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
Component layer — reusable Ghibli primitives
|
|
------------------------------------------------------------------- */
|
|
@layer components {
|
|
/* Parchment card: the workhorse surface */
|
|
.gh-card {
|
|
border-radius: 1.5rem;
|
|
border: 1px solid var(--color-line);
|
|
background: color-mix(in srgb, var(--color-cloud) 88%, transparent);
|
|
box-shadow: var(--shadow-soft);
|
|
backdrop-filter: blur(6px);
|
|
}
|
|
.gh-card-hover {
|
|
transition: transform 0.25s ease, box-shadow 0.25s ease;
|
|
}
|
|
.gh-card-hover:hover {
|
|
transform: translateY(-3px);
|
|
box-shadow: var(--shadow-float);
|
|
}
|
|
|
|
/* A softer inner panel (for nested groups, details) */
|
|
.gh-panel {
|
|
border-radius: 1rem;
|
|
border: 1px solid var(--color-line-soft);
|
|
background: color-mix(in srgb, var(--color-cloud-soft) 70%, transparent);
|
|
}
|
|
|
|
/* Section heading eyebrow */
|
|
.gh-eyebrow {
|
|
font-family: var(--font-display);
|
|
color: var(--color-forest-deep);
|
|
letter-spacing: 0.02em;
|
|
}
|
|
|
|
/* Buttons --------------------------------------------------------- */
|
|
.gh-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.5rem;
|
|
border-radius: 9999px;
|
|
padding: 0.5rem 1.1rem;
|
|
font-weight: 600;
|
|
line-height: 1.1;
|
|
transition: transform 0.15s ease, box-shadow 0.2s ease, background-color 0.2s ease, filter 0.2s ease;
|
|
cursor: pointer;
|
|
}
|
|
.gh-btn:active { transform: translateY(1px) scale(0.99); }
|
|
.gh-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
|
|
.gh-btn-primary {
|
|
background: var(--color-forest);
|
|
color: var(--color-cloud);
|
|
box-shadow: 0 6px 16px -8px rgba(70, 106, 58, 0.9);
|
|
}
|
|
.gh-btn-primary:not(:disabled):hover { background: var(--color-forest-deep); }
|
|
|
|
.gh-btn-sun {
|
|
background: var(--color-sunset);
|
|
color: #fff;
|
|
box-shadow: 0 6px 16px -8px rgba(232, 154, 94, 0.9);
|
|
}
|
|
.gh-btn-sun:not(:disabled):hover { filter: brightness(1.05); }
|
|
|
|
.gh-btn-sky {
|
|
background: var(--color-sky-deep);
|
|
color: #fff;
|
|
box-shadow: 0 6px 16px -8px rgba(111, 178, 214, 0.9);
|
|
}
|
|
.gh-btn-sky:not(:disabled):hover { filter: brightness(1.05); }
|
|
|
|
.gh-btn-ghost {
|
|
background: color-mix(in srgb, var(--color-cloud) 85%, transparent);
|
|
color: var(--color-ink);
|
|
border: 1px solid var(--color-line);
|
|
}
|
|
.gh-btn-ghost:not(:disabled):hover { background: color-mix(in srgb, var(--color-sun) 28%, var(--color-cloud)); }
|
|
|
|
.gh-btn-danger {
|
|
background: transparent;
|
|
color: var(--color-danger);
|
|
border: 1px solid color-mix(in srgb, var(--color-danger) 45%, transparent);
|
|
}
|
|
.gh-btn-danger:not(:disabled):hover { background: var(--color-danger-soft); }
|
|
|
|
/* Form controls --------------------------------------------------- */
|
|
.gh-input,
|
|
.gh-select {
|
|
width: 100%;
|
|
margin-top: 0.25rem;
|
|
border-radius: 0.75rem;
|
|
border: 1px solid var(--color-line);
|
|
background: color-mix(in srgb, var(--color-cloud) 92%, #fff);
|
|
padding: 0.5rem 0.75rem;
|
|
color: var(--color-ink);
|
|
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
|
}
|
|
.gh-input::placeholder { color: color-mix(in srgb, var(--color-earth) 55%, transparent); }
|
|
.gh-input:focus,
|
|
.gh-select:focus {
|
|
outline: none;
|
|
border-color: var(--color-sky-deep);
|
|
box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-sky) 55%, transparent);
|
|
}
|
|
|
|
.gh-label { display: block; font-size: 0.875rem; color: var(--color-ink-soft); }
|
|
|
|
/* Pills / badges -------------------------------------------------- */
|
|
.gh-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.3rem;
|
|
border-radius: 9999px;
|
|
padding: 0.1rem 0.6rem;
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
}
|
|
.gh-badge-warn {
|
|
background: var(--color-danger-soft);
|
|
color: var(--color-danger);
|
|
border: 1px solid color-mix(in srgb, var(--color-danger) 30%, transparent);
|
|
}
|
|
.gh-badge-ok {
|
|
background: color-mix(in srgb, var(--color-forest) 18%, var(--color-cloud));
|
|
color: var(--color-forest-deep);
|
|
border: 1px solid color-mix(in srgb, var(--color-forest) 35%, transparent);
|
|
}
|
|
|
|
/* Notes / callouts ------------------------------------------------ */
|
|
.gh-note {
|
|
border-radius: 0.9rem;
|
|
padding: 0.75rem 1rem;
|
|
font-size: 0.85rem;
|
|
border: 1px solid var(--color-line);
|
|
background: color-mix(in srgb, var(--color-sun) 16%, var(--color-cloud));
|
|
color: var(--color-ink);
|
|
}
|
|
.gh-note-warn {
|
|
border-color: color-mix(in srgb, var(--color-danger) 35%, transparent);
|
|
background: var(--color-danger-soft);
|
|
color: var(--color-danger);
|
|
}
|
|
|
|
/* Decorative soot sprite used by the background */
|
|
.gh-soot {
|
|
position: absolute;
|
|
bottom: 8vh;
|
|
border-radius: 9999px;
|
|
background: radial-gradient(circle at 35% 30%, #5a5247, #2c2722 70%);
|
|
box-shadow: 0 0 0 3px rgba(44, 39, 34, 0.08);
|
|
filter: blur(0.3px);
|
|
}
|
|
}
|
|
|
|
/* Respect reduced-motion preferences */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.gh-anim,
|
|
[class*="animate-"] { animation: none !important; }
|
|
}
|