Files
flxn-app/src/themes/ocean/theme.css
T
2026-08-23 17:17:04 -07:00

424 lines
16 KiB
CSS

/* Deep Sea: a submarine descent. Dark is the primary mood — a fixed
abyssal deep-teal→ink-navy backdrop with sparse static rising bubbles;
surfaces are opaque pressure-hull panels with 1px bioluminescent rims,
focus states are sonar rings (double accent box-shadow), avatars are
portholes. Light is the sunlit shallows: sand-and-seafoam with a very
subtle refracted-caustic hint. The fixed teal rim/scenery is decoration;
everything interactive derives from --mantine-primary-color-* (the eight
ramps are retuned in manifest.ts as bioluminescent sea colors). No
backdrop-filter anywhere — hulls are solid. */
/* ---------------------------------------------------------------- */
/* 1. Tokens for any scheme */
/* ---------------------------------------------------------------- */
[data-theme="ocean"][data-theme] {
--mantine-font-family: "Figtree", "Avenir Next", "Helvetica Neue", sans-serif;
--mantine-font-family-headings: "Comfortaa", "Figtree", sans-serif;
--mantine-heading-font-weight: 700;
/* rounded, water-worn radii */
--mantine-radius-xs: 0.375rem;
--mantine-radius-sm: 0.5625rem;
--mantine-radius-md: 0.75rem;
--mantine-radius-lg: 1rem;
--mantine-radius-xl: 1.5rem;
--mantine-radius-default: 0.75rem;
/* porthole avatars: circle + bold hull ring (the frame owns the border) */
--flxn-avatar-radius: 50%;
--flxn-avatar-border: 3px solid var(--ocean-porthole);
--flxn-badge-radius: 14px;
/* sonar focus ring: two accent rings, inner solid + outer echo */
--ocean-sonar: 0 0 0 2px
color-mix(in srgb, var(--mantine-primary-color-filled) 90%, transparent),
0 0 0 6px
color-mix(in srgb, var(--mantine-primary-color-filled) 28%, transparent);
}
/* ---------------------------------------------------------------- */
/* 2. Per-scheme tokens */
/* ---------------------------------------------------------------- */
[data-theme="ocean"][data-theme][data-mantine-color-scheme="dark"] {
--mantine-color-body: #062632;
--mantine-color-text: #d9f2f0;
--mantine-color-bright: #f2fffd;
--mantine-color-dimmed: #93bcc0;
--mantine-color-placeholder: #628e96;
--mantine-color-default: #0c3745;
--mantine-color-default-hover: #11424f;
--mantine-color-default-color: #d9f2f0;
--mantine-color-default-border: rgba(103, 232, 214, 0.24);
/* deep-water elevation with a faint bioluminescent edge */
--mantine-shadow-xs: 0 0 0 1px rgba(103, 232, 214, 0.06), 0 2px 6px rgba(1, 10, 16, 0.5);
--mantine-shadow-sm: 0 0 0 1px rgba(103, 232, 214, 0.08), 0 4px 12px rgba(1, 10, 16, 0.55);
--mantine-shadow-md: 0 0 0 1px rgba(103, 232, 214, 0.1), 0 8px 24px rgba(1, 10, 16, 0.6);
--mantine-shadow-lg: 0 0 0 1px rgba(103, 232, 214, 0.12), 0 12px 34px rgba(1, 10, 16, 0.65);
--mantine-shadow-xl: 0 0 0 1px rgba(103, 232, 214, 0.14), 0 18px 48px rgba(1, 10, 16, 0.7);
/* pressure-hull ingredients */
--ocean-hull: #0a3240;
--ocean-hull-raised: #0e3d4d;
--ocean-deep: #041d27;
--ocean-rim: rgba(103, 232, 214, 0.22);
--ocean-rim-strong: rgba(103, 232, 214, 0.38);
--ocean-chrome: #052430;
--ocean-porthole: #2c7482;
--ocean-porthole-glow: 0 0 0 1px rgba(103, 232, 214, 0.25),
0 0 12px rgba(103, 232, 214, 0.2);
--ocean-tooltip-bg: #0d3947;
--ocean-tooltip-color: #dcf5f2;
/* app tokens */
--flxn-gold: #f2c14b;
--flxn-silver: #a9c3cb;
--flxn-bronze: #dd9364;
--flxn-toast-success: #6fe3a5;
--flxn-toast-error: #ff8f9f;
--flxn-showcase-bg: #0a3240;
--flxn-overlay: rgba(2, 10, 16, 0.62);
--flxn-dotgrid-color: rgba(103, 232, 214, 0.16);
--flxn-pop-shadow: rgba(0, 0, 0, 0.55);
/* podium as glowing depth tiers */
--flxn-podium-1-bg: rgba(242, 193, 75, 0.1);
--flxn-podium-1-border: rgba(242, 193, 75, 0.38);
--flxn-podium-1-label: #f2c14b;
--flxn-podium-2-bg: rgba(169, 195, 203, 0.08);
--flxn-podium-2-border: rgba(169, 195, 203, 0.3);
--flxn-podium-2-label: #b8ccd2;
--flxn-podium-3-bg: rgba(221, 147, 100, 0.1);
--flxn-podium-3-border: rgba(221, 147, 100, 0.36);
--flxn-podium-3-label: #e5a273;
}
[data-theme="ocean"][data-theme][data-mantine-color-scheme="light"] {
--mantine-color-body: #eaf6f6;
--mantine-color-text: #11373f;
--mantine-color-bright: #072229;
--mantine-color-dimmed: #4a6e72;
--mantine-color-placeholder: #5f858a;
--mantine-color-default: #ffffff;
--mantine-color-default-hover: #f0f7f4;
--mantine-color-default-color: #11373f;
--mantine-color-default-border: rgba(23, 115, 110, 0.3);
/* soft sea-tinted elevation */
--mantine-shadow-xs: 0 1px 3px rgba(15, 80, 90, 0.1);
--mantine-shadow-sm: 0 2px 8px rgba(15, 80, 90, 0.12);
--mantine-shadow-md: 0 6px 18px rgba(15, 80, 90, 0.14);
--mantine-shadow-lg: 0 10px 28px rgba(15, 80, 90, 0.16);
--mantine-shadow-xl: 0 16px 44px rgba(15, 80, 90, 0.2);
/* sand-and-seafoam ingredients */
--ocean-hull: #fbfaf3;
--ocean-hull-raised: #ffffff;
--ocean-deep: #ddeeea;
--ocean-rim: rgba(23, 115, 110, 0.25);
--ocean-rim-strong: rgba(23, 115, 110, 0.42);
--ocean-chrome: #f3f9f6;
--ocean-porthole: #7fb5ae;
--ocean-porthole-glow: 0 0 0 1px rgba(23, 115, 110, 0.18),
0 2px 8px rgba(15, 80, 90, 0.16);
--ocean-tooltip-bg: #14424d;
--ocean-tooltip-color: #e4f6f3;
/* app tokens */
--flxn-gold: #d8a419;
--flxn-silver: #8ba7ad;
--flxn-bronze: #c76e34;
--flxn-toast-success: #2e9e6b;
--flxn-toast-error: #d64d64;
--flxn-showcase-bg: #ffffff;
--flxn-overlay: rgba(10, 50, 60, 0.4);
--flxn-dotgrid-color: rgba(23, 115, 110, 0.2);
--flxn-pop-shadow: rgba(15, 80, 90, 0.28);
/* podium as sunlit sand tiers */
--flxn-podium-1-bg: rgba(216, 164, 25, 0.14);
--flxn-podium-1-border: rgba(179, 131, 16, 0.45);
--flxn-podium-1-label: #7c5a0b;
--flxn-podium-2-bg: rgba(90, 120, 125, 0.1);
--flxn-podium-2-border: rgba(90, 120, 125, 0.35);
--flxn-podium-2-label: #47666a;
--flxn-podium-3-bg: rgba(199, 110, 52, 0.12);
--flxn-podium-3-border: rgba(199, 110, 52, 0.42);
--flxn-podium-3-label: #8a4c1d;
}
/* ---------------------------------------------------------------- */
/* 3. Fixed backdrop (below all content) */
/* ---------------------------------------------------------------- */
[data-theme="ocean"] body::before {
content: "";
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
}
/* Abyssal descent: deep teal fading to ink navy, sparse static bubbles
rising (bigger and brighter near the sea floor, fading toward the top). */
[data-theme="ocean"][data-mantine-color-scheme="dark"] body::before {
background-color: #062632;
background-image:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='640' viewBox='0 0 260 640'%3E%3Cg fill='none' stroke='%239beee2'%3E%3Ccircle cx='36' cy='584' r='5' stroke-opacity='.13'/%3E%3Ccircle cx='44' cy='512' r='3' stroke-opacity='.1'/%3E%3Ccircle cx='210' cy='612' r='4' stroke-opacity='.12'/%3E%3Ccircle cx='202' cy='540' r='2.5' stroke-opacity='.09'/%3E%3Ccircle cx='128' cy='430' r='3.5' stroke-opacity='.1'/%3E%3Ccircle cx='120' cy='360' r='2' stroke-opacity='.08'/%3E%3Ccircle cx='232' cy='300' r='3' stroke-opacity='.09'/%3E%3Ccircle cx='60' cy='250' r='2.5' stroke-opacity='.08'/%3E%3Ccircle cx='150' cy='160' r='2' stroke-opacity='.07'/%3E%3Ccircle cx='90' cy='80' r='1.5' stroke-opacity='.06'/%3E%3C/g%3E%3Cg fill='%239beee2'%3E%3Ccircle cx='70' cy='470' r='1.2' fill-opacity='.1'/%3E%3Ccircle cx='180' cy='390' r='1' fill-opacity='.09'/%3E%3Ccircle cx='40' cy='330' r='1' fill-opacity='.08'/%3E%3Ccircle cx='222' cy='190' r='1' fill-opacity='.07'/%3E%3Ccircle cx='140' cy='40' r='1' fill-opacity='.05'/%3E%3C/g%3E%3C/svg%3E"),
radial-gradient(50rem 30rem at 50% -10%, rgba(45, 160, 175, 0.18), transparent 65%),
linear-gradient(180deg, #0b3b46 0%, #072b38 45%, #03121e 100%);
background-repeat: repeat, no-repeat, no-repeat;
background-size: 260px 640px, auto, auto;
}
/* Sunlit shallows: seafoam fading to a sandy floor, with a faint white
caustic ripple tile — refracted light, kept very subtle. */
[data-theme="ocean"][data-mantine-color-scheme="light"] body::before {
background-color: #eaf6f6;
background-image:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='220' viewBox='0 0 320 220'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='1.4'%3E%3Cpath d='M0 40 Q 40 10 80 42 T 160 44 T 240 38 T 320 42' stroke-opacity='.4'/%3E%3Cpath d='M0 110 Q 45 82 90 112 T 180 110 T 268 114 T 320 108' stroke-opacity='.3'/%3E%3Cpath d='M0 180 Q 50 152 100 182 T 200 178 T 300 184 T 320 180' stroke-opacity='.35'/%3E%3C/g%3E%3C/svg%3E"),
radial-gradient(46rem 26rem at 30% -8%, rgba(255, 255, 255, 0.75), transparent 60%),
radial-gradient(60rem 22rem at 50% 108%, rgba(226, 214, 178, 0.5), transparent 70%),
linear-gradient(180deg, #d8efee 0%, #eaf6f6 55%, #f2f3e9 100%);
background-repeat: repeat, no-repeat, no-repeat, no-repeat;
background-size: 320px 220px, auto, auto, auto;
}
/* ---------------------------------------------------------------- */
/* 4. Pressure-hull surfaces: solid panels, bioluminescent rims */
/* ---------------------------------------------------------------- */
[data-theme="ocean"] .mantine-Paper-root,
[data-theme="ocean"] .mantine-Card-root {
background-color: var(--ocean-hull);
border: 1px solid var(--ocean-rim);
box-shadow: var(--mantine-shadow-sm);
}
[data-theme="ocean"] .mantine-Modal-content {
background-color: var(--ocean-hull);
border: 1px solid var(--ocean-rim-strong);
box-shadow: var(--mantine-shadow-xl);
}
[data-theme="ocean"] .mantine-Modal-header {
background-color: transparent;
}
[data-theme="ocean"] .mantine-Popover-dropdown {
background-color: var(--ocean-hull);
border: 1px solid var(--ocean-rim-strong);
box-shadow: var(--mantine-shadow-lg);
}
[data-theme="ocean"] .mantine-Notification-root {
background-color: var(--ocean-hull);
border: 1px solid var(--ocean-rim-strong);
box-shadow: var(--mantine-shadow-lg);
}
/* AppShell chrome: the conning tower and lower deck — solid hull strips
sealed with a stronger rim seam. */
[data-theme="ocean"] .mantine-AppShell-header {
background-color: var(--ocean-chrome);
border-bottom: 1px solid var(--ocean-rim-strong);
box-shadow: var(--mantine-shadow-sm);
}
[data-theme="ocean"] .mantine-AppShell-navbar {
background-color: var(--ocean-chrome);
border-inline-end: 1px solid var(--ocean-rim-strong);
}
/* ---------------------------------------------------------------- */
/* 5. Sonar focus rings */
/* ---------------------------------------------------------------- */
/* The transparent outline stays invisible here but becomes a real ring in
forced-colors mode, where the box-shadow sonar is stripped. */
[data-theme="ocean"] :focus-visible {
outline: 2px solid transparent;
outline-offset: 2px;
box-shadow: var(--ocean-sonar);
}
[data-theme="ocean"] .mantine-Input-input:focus,
[data-theme="ocean"] .mantine-Input-input:focus-within {
border-color: var(--mantine-primary-color-filled);
box-shadow: var(--ocean-sonar);
}
/* ---------------------------------------------------------------- */
/* 6. Controls */
/* ---------------------------------------------------------------- */
/* Filled controls give off a faint accent glow; the transparent border
keeps a real edge for forced-colors mode. */
[data-theme="ocean"] .mantine-Button-root[data-variant="filled"],
[data-theme="ocean"] .mantine-ActionIcon-root[data-variant="filled"] {
border: 1px solid transparent;
box-shadow:
0 0 14px -4px color-mix(in srgb, var(--mantine-primary-color-filled) 55%, transparent),
var(--mantine-shadow-xs);
}
[data-theme="ocean"] .mantine-Button-root {
font-weight: 600;
}
[data-theme="ocean"] .mantine-Input-input {
background-color: var(--ocean-deep);
border: 1px solid var(--ocean-rim);
}
[data-theme="ocean"] .mantine-Checkbox-input {
background-color: var(--ocean-deep);
border-color: var(--ocean-rim-strong);
}
[data-theme="ocean"] .mantine-SegmentedControl-root {
background-color: var(--ocean-deep);
border: 1px solid var(--ocean-rim);
}
[data-theme="ocean"] .mantine-SegmentedControl-indicator {
background-color: var(--ocean-hull-raised);
border: 1px solid var(--ocean-rim-strong);
box-shadow: var(--mantine-shadow-xs);
}
[data-theme="ocean"] .mantine-Progress-root {
background-color: var(--ocean-deep);
border: 1px solid var(--ocean-rim);
}
[data-theme="ocean"] .mantine-Badge-root[data-variant="default"] {
background-color: var(--mantine-color-default);
border: 1px solid var(--ocean-rim);
}
[data-theme="ocean"] .mantine-Tabs-list {
--tabs-list-border-color: var(--mantine-color-default-border);
}
[data-theme="ocean"] .mantine-Tabs-tab:hover,
[data-theme="ocean"] .mantine-NavLink-root:hover {
background-color: var(--mantine-color-default-hover);
}
[data-theme="ocean"] .mantine-Tooltip-tooltip {
background-color: var(--ocean-tooltip-bg);
color: var(--ocean-tooltip-color);
border-radius: var(--mantine-radius-md);
box-shadow: var(--mantine-shadow-sm);
}
[data-theme="ocean"] ::selection {
background: color-mix(in srgb, var(--mantine-primary-color-filled) 30%, transparent);
}
/* ---------------------------------------------------------------- */
/* 7. Wave divider: repeating radial scallop line */
/* ---------------------------------------------------------------- */
[data-theme="ocean"] .mantine-Divider-root {
--divider-color: var(--ocean-rim-strong);
}
[data-theme="ocean"] .mantine-Divider-root[data-orientation="horizontal"]:not([data-with-label]) {
border-top: none;
height: 5px;
background-image: radial-gradient(
circle at 6px -2px,
transparent 4px,
var(--ocean-rim-strong) 4px,
var(--ocean-rim-strong) 5.4px,
transparent 5.4px
);
background-size: 12px 5px;
background-repeat: repeat-x;
}
@media (forced-colors: active) {
[data-theme="ocean"] .mantine-Divider-root[data-orientation="horizontal"]:not([data-with-label]) {
border-top: 1px solid CanvasText;
height: auto;
background-image: none;
}
}
/* ---------------------------------------------------------------- */
/* 8. App component hooks */
/* ---------------------------------------------------------------- */
/* Tab strip: flat while resting; docked it becomes a hull deck strip. */
[data-theme="ocean"] .flxn-tabs[data-stuck] {
background-color: var(--ocean-chrome);
border-bottom-color: var(--ocean-rim-strong);
box-shadow: var(--mantine-shadow-sm);
}
[data-theme="ocean"] .flxn-tab {
color: var(--mantine-color-dimmed);
font-weight: 500;
}
/* Underline indicator, so accent text on the active tab is allowed. */
[data-theme="ocean"] .flxn-tab[data-active] {
color: var(--mantine-primary-color-light-color);
font-weight: 700;
}
[data-theme="ocean"] .flxn-tabs-indicator {
border-bottom: 2px solid var(--mantine-primary-color-filled);
padding-inline: 0.5rem;
}
/* Nav grid tiles: instrument panels — hull plate with a lit top seam. */
[data-theme="ocean"] .flxn-tile {
background-color: var(--ocean-hull);
border: 1px solid var(--ocean-rim);
border-radius: var(--mantine-radius-lg);
box-shadow: var(--mantine-shadow-xs), inset 0 1px 0 var(--ocean-rim);
}
/* Flat accent-tinted glyph — no plate. */
[data-theme="ocean"] .flxn-tile-icon {
color: var(--mantine-primary-color-light-color);
}
/* "See all" as a depth-tag chip: accent wash + its dedicated on-color. */
[data-theme="ocean"] .flxn-see-all {
background-color: var(--mantine-primary-color-light);
color: var(--mantine-primary-color-light-color);
border: 1px solid
color-mix(in srgb, var(--mantine-primary-color-light-color) 35%, transparent);
}
/* Match card + reaction tray as one hull construction: same rim, tray one
deck lower (deeper water). */
[data-theme="ocean"] .flxn-match-card {
background-color: var(--ocean-hull);
border: 1px solid var(--ocean-rim);
}
[data-theme="ocean"] .flxn-reaction-row {
background-color: var(--ocean-deep);
border: 1px solid var(--ocean-rim);
}
/* Porthole: the bold ring comes from --flxn-avatar-border; the frame adds
the bioluminescent halo around it. */
[data-theme="ocean"] .flxn-avatar-frame {
border-radius: 50%;
box-shadow: var(--ocean-porthole-glow);
}
/* Press feedback: a brief bioluminescent flare (filter only — the global
scale transform stays untouched). */
[data-theme="ocean"] .flxn-press:active {
filter: brightness(1.06) saturate(1.08);
}