@tailwindcss/vite:generate:serve threw 'Invalid declaration: getCurrentWindow' on ResizeHandles.svelte?svelte&type=style&lang.css even after comment sanitisation. The style block is plain CSS with no Tailwind directives, but the per-component virtual CSS module route was hitting a parse bug in the Tailwind v4 + Svelte 5 combination. Workaround: move the CSS into app.css (class names are already component-specific, no scoping loss) and drop the component-local <style> block. This sidesteps the virtual-module route entirely. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
494 lines
12 KiB
CSS
494 lines
12 KiB
CSS
/* === Bundled Fonts — offline-first === */
|
|
@font-face {
|
|
font-family: 'Lexend';
|
|
src: url('/fonts/lexend-variable.woff2') format('woff2');
|
|
font-weight: 100 900;
|
|
font-display: swap;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'Instrument Serif';
|
|
src: url('/fonts/instrument-serif-italic.woff2') format('woff2');
|
|
font-style: italic;
|
|
font-weight: 400;
|
|
font-display: swap;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'JetBrains Mono';
|
|
src: url('/fonts/jetbrains-mono.woff2') format('woff2');
|
|
font-weight: 100 800;
|
|
font-display: swap;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'Atkinson Hyperlegible Next';
|
|
src: url('/fonts/atkinson-hyperlegible-next.woff2') format('woff2');
|
|
font-weight: 400 700;
|
|
font-display: swap;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'OpenDyslexic';
|
|
src: url('/fonts/opendyslexic.woff2') format('woff2');
|
|
font-weight: 400 700;
|
|
font-display: swap;
|
|
}
|
|
|
|
@import "tailwindcss";
|
|
|
|
/* === Kon Design Tokens === */
|
|
@theme {
|
|
/* Surfaces — warm layered depth */
|
|
--color-bg: #0f0e0c;
|
|
--color-bg-elevated: #171614;
|
|
--color-bg-card: #1b1a17;
|
|
--color-bg-input: #151412;
|
|
--color-border: #2c2923;
|
|
--color-border-subtle: #221f1b;
|
|
|
|
/* Text — warm hierarchy */
|
|
--color-text: #f0ece4;
|
|
--color-text-secondary: #9a9486;
|
|
--color-text-tertiary: #716b60;
|
|
|
|
/* Accent — warm amber/copper */
|
|
--color-accent: #e8a87c;
|
|
--color-accent-hover: #d4976a;
|
|
--color-accent-subtle: #e8a87c10;
|
|
--color-accent-glow: #e8a87c25;
|
|
|
|
/* Semantic */
|
|
--color-success: #7ec89a;
|
|
--color-danger: #e87171;
|
|
--color-warning: #e8c86e;
|
|
|
|
/* Layout */
|
|
--color-sidebar: #13120f;
|
|
--color-nav-active: #201e1a;
|
|
--color-hover: #1e1c18;
|
|
|
|
/* === Layout Tokens === */
|
|
--radius-sm: 6px;
|
|
--radius-md: 8px;
|
|
--radius-lg: 12px;
|
|
--radius-xl: 16px;
|
|
--title-size: 26px;
|
|
|
|
/* Typography */
|
|
--font-family-body: 'Lexend', system-ui, sans-serif;
|
|
--font-family-display: 'Instrument Serif', serif;
|
|
--font-family-mono: 'JetBrains Mono', monospace;
|
|
--font-size-body: 16px;
|
|
--line-height-body: 1.5;
|
|
--letter-spacing-body: 0;
|
|
|
|
/* Motion */
|
|
--duration-ui: 150ms;
|
|
--duration-decorative: 300ms;
|
|
|
|
/* Window resize hit zones — consumed by ResizeHandles.svelte. One source
|
|
of truth so every Kon window feels identical. */
|
|
--kon-resize-edge: 12px;
|
|
--kon-resize-corner: 20px;
|
|
}
|
|
|
|
/* === Button Component Classes === */
|
|
.btn-sm { @apply px-2.5 py-1 text-[11px]; }
|
|
.btn-md { @apply px-3 py-1.5 text-[12px]; }
|
|
.btn-lg { @apply px-4 py-2 text-[13px]; }
|
|
|
|
/* === Light theme overrides === */
|
|
:root[data-theme="light"] {
|
|
--color-bg: #faf8f5;
|
|
--color-bg-elevated: #f3f0eb;
|
|
--color-bg-card: #ffffff;
|
|
--color-bg-input: #f0ede8;
|
|
--color-border: #ddd8d0;
|
|
--color-border-subtle: #e6e2da;
|
|
|
|
--color-text: #1a1816;
|
|
--color-text-secondary: #5c574d;
|
|
--color-text-tertiary: #8a8578;
|
|
|
|
--color-accent: #b87a4a;
|
|
--color-accent-hover: #a06b3e;
|
|
--color-accent-subtle: #b87a4a10;
|
|
--color-accent-glow: #b87a4a20;
|
|
|
|
--color-success: #3d8a5a;
|
|
--color-danger: #c44d4d;
|
|
--color-warning: #b89a3e;
|
|
|
|
--color-sidebar: #f5f2ed;
|
|
--color-nav-active: #eae6e0;
|
|
--color-hover: #ede9e3;
|
|
}
|
|
|
|
:root[data-theme="light"] ::-webkit-scrollbar-thumb {
|
|
background: #d0ccc4;
|
|
}
|
|
:root[data-theme="light"] ::-webkit-scrollbar-thumb:hover {
|
|
background: #b8b3aa;
|
|
}
|
|
|
|
/* === Sensory Zones — Dark Theme === */
|
|
/* Zones tint surfaces only. Accent tokens (amber) stay constant across all zones —
|
|
the brand colour is the constant, the environment is the variable. */
|
|
:root[data-zone="cave"] {
|
|
--color-bg: #0f1214;
|
|
--color-bg-elevated: #141a1e;
|
|
--color-bg-card: #171f24;
|
|
--color-sidebar: #0d1012;
|
|
}
|
|
:root[data-zone="energy"] {
|
|
--color-bg: #100e0b;
|
|
--color-bg-elevated: #1c1815;
|
|
--color-bg-card: #211d18;
|
|
--color-sidebar: #141110;
|
|
}
|
|
:root[data-zone="reset"] {
|
|
--color-bg: #0e100e;
|
|
--color-bg-elevated: #161a16;
|
|
--color-bg-card: #1a1f1a;
|
|
--color-sidebar: #0c0e0c;
|
|
}
|
|
/* === Sensory Zones — Light Theme === */
|
|
:root[data-theme="light"][data-zone="cave"] {
|
|
--color-bg: #f0f5f7;
|
|
--color-bg-elevated: #e8f0f2;
|
|
--color-bg-card: #f5fafc;
|
|
--color-sidebar: #eaf2f4;
|
|
}
|
|
:root[data-theme="light"][data-zone="energy"] {
|
|
--color-bg: #faf7f3;
|
|
--color-bg-elevated: #f5f0e8;
|
|
--color-bg-card: #fffcf7;
|
|
--color-sidebar: #f5f0ea;
|
|
}
|
|
:root[data-theme="light"][data-zone="reset"] {
|
|
--color-bg: #f3f7f2;
|
|
--color-bg-elevated: #edf2ea;
|
|
--color-bg-card: #f8fcf6;
|
|
--color-sidebar: #eff4ec;
|
|
}
|
|
|
|
/* === Base === */
|
|
html, body {
|
|
margin: 0;
|
|
padding: 0;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
background: var(--color-bg);
|
|
color: var(--color-text);
|
|
font-family: var(--font-family-body);
|
|
font-size: var(--font-size-body);
|
|
line-height: var(--line-height-body);
|
|
letter-spacing: var(--letter-spacing-body);
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
user-select: none;
|
|
}
|
|
|
|
/* === Display font === */
|
|
.font-display {
|
|
font-family: var(--font-family-display);
|
|
}
|
|
|
|
/* === Transcript font — optimised for reading === */
|
|
.font-transcript {
|
|
font-family: var(--font-family-body);
|
|
font-size: var(--text-transcript, 16px);
|
|
line-height: 1.85;
|
|
letter-spacing: 0.01em;
|
|
font-feature-settings: "liga" 1, "kern" 1;
|
|
}
|
|
|
|
/* === Grain texture overlay === */
|
|
.grain::after {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
opacity: 0.025;
|
|
background-image: url('/textures/grain.png');
|
|
background-repeat: repeat;
|
|
background-size: 200px 200px;
|
|
z-index: 50;
|
|
}
|
|
:root[data-theme="light"] .grain::after {
|
|
opacity: 0.015;
|
|
}
|
|
|
|
/* === Scrollbar — thin, appears on hover === */
|
|
::-webkit-scrollbar {
|
|
width: 5px;
|
|
}
|
|
::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
::-webkit-scrollbar-thumb {
|
|
background: #2c2923;
|
|
border-radius: 999px;
|
|
}
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: #3d3830;
|
|
}
|
|
|
|
/* === Smooth transitions (global) === */
|
|
* {
|
|
transition-property: background-color, border-color, color, opacity, box-shadow;
|
|
transition-duration: var(--duration-ui);
|
|
transition-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
|
|
}
|
|
|
|
/* Opt out for inputs */
|
|
textarea, input, [data-no-transition] {
|
|
transition: none;
|
|
}
|
|
|
|
/* === Focus ring — consistent, accessible === */
|
|
:focus-visible {
|
|
outline: 2px solid var(--color-accent);
|
|
outline-offset: 3px;
|
|
border-radius: var(--radius-md);
|
|
}
|
|
|
|
/* === Selection colour === */
|
|
::selection {
|
|
background: var(--color-accent-glow);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
/* === Animations === */
|
|
@keyframes fade-in {
|
|
from { opacity: 0; transform: translateY(4px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
@keyframes pulse-soft {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.4; }
|
|
}
|
|
|
|
@keyframes pulse-warm {
|
|
0%, 100% { box-shadow: 0 0 24px rgba(232, 168, 124, 0.25), 0 0 48px rgba(232, 168, 124, 0.08); }
|
|
50% { box-shadow: 0 0 32px rgba(232, 168, 124, 0.4), 0 0 64px rgba(232, 168, 124, 0.15); }
|
|
}
|
|
|
|
@keyframes slide-up {
|
|
from { opacity: 0; transform: translateY(8px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
@keyframes breathe {
|
|
0%, 100% { transform: scale(1); }
|
|
50% { transform: scale(1.04); }
|
|
}
|
|
|
|
.animate-fade-in {
|
|
animation: fade-in var(--duration-decorative) ease-out;
|
|
}
|
|
|
|
.animate-pulse-soft {
|
|
animation: pulse-soft 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
.animate-pulse-warm {
|
|
animation: pulse-warm 2s ease-in-out infinite;
|
|
}
|
|
|
|
.animate-slide-up {
|
|
animation: slide-up var(--duration-decorative) ease-out;
|
|
}
|
|
|
|
.animate-breathe {
|
|
animation: breathe 3s ease-in-out infinite;
|
|
}
|
|
|
|
/* === Task sidebar slide === */
|
|
@keyframes slide-in-right {
|
|
from { transform: translateX(100%); opacity: 0; }
|
|
to { transform: translateX(0); opacity: 1; }
|
|
}
|
|
@keyframes slide-out-right {
|
|
from { transform: translateX(0); opacity: 1; }
|
|
to { transform: translateX(100%); opacity: 0; }
|
|
}
|
|
|
|
/* Task extraction highlight */
|
|
@keyframes highlight-warm {
|
|
0% { border-left-color: var(--color-accent); }
|
|
100% { border-left-color: transparent; }
|
|
}
|
|
|
|
/* Checkbox pop */
|
|
@keyframes scale-pop {
|
|
0% { transform: scale(0.95); }
|
|
100% { transform: scale(1); }
|
|
}
|
|
|
|
.animate-slide-in-right {
|
|
animation: slide-in-right var(--duration-decorative) ease-out;
|
|
}
|
|
.animate-highlight-warm {
|
|
border-left: 3px solid transparent;
|
|
animation: highlight-warm 2s ease-out;
|
|
}
|
|
.animate-scale-pop {
|
|
animation: scale-pop 50ms ease-out;
|
|
}
|
|
|
|
/* Window focus glow */
|
|
@keyframes glow-pulse {
|
|
0% { box-shadow: 0 0 0 0 rgba(232, 168, 124, 0); }
|
|
30% { box-shadow: 0 0 20px 4px rgba(232, 168, 124, 0.35), inset 0 0 12px rgba(232, 168, 124, 0.08); }
|
|
100% { box-shadow: 0 0 0 0 rgba(232, 168, 124, 0); }
|
|
}
|
|
|
|
.animate-glow-pulse {
|
|
animation: glow-pulse 700ms ease-out;
|
|
}
|
|
|
|
:root[data-theme="light"] .animate-glow-pulse {
|
|
animation: glow-pulse-light 700ms ease-out;
|
|
}
|
|
|
|
@keyframes glow-pulse-light {
|
|
0% { box-shadow: 0 0 0 0 rgba(184, 122, 74, 0); }
|
|
30% { box-shadow: 0 0 20px 4px rgba(184, 122, 74, 0.3), inset 0 0 12px rgba(184, 122, 74, 0.06); }
|
|
100% { box-shadow: 0 0 0 0 rgba(184, 122, 74, 0); }
|
|
}
|
|
|
|
/* Float window entrance */
|
|
@keyframes float-enter {
|
|
from { opacity: 0; transform: scale(0.97); }
|
|
to { opacity: 1; transform: scale(1); }
|
|
}
|
|
|
|
.animate-float-enter {
|
|
animation: float-enter var(--duration-decorative) ease-out;
|
|
}
|
|
|
|
/* === Custom titlebar buttons === */
|
|
.titlebar-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 46px;
|
|
height: 32px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
/* Sinhala character spin (decorative, during recording) */
|
|
@keyframes sinhala-spin {
|
|
from { transform: rotate(0deg); }
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
.animate-sinhala-spin {
|
|
animation: sinhala-spin 2s linear infinite;
|
|
}
|
|
|
|
/* === Reduced Motion === */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
}
|
|
}
|
|
|
|
/* === Data-attribute reduce-motion support === */
|
|
:root[data-reduce-motion="true"],
|
|
:root[data-reduce-motion="true"] *,
|
|
:root[data-reduce-motion="true"] *::before,
|
|
:root[data-reduce-motion="true"] *::after {
|
|
--duration-ui: 0ms;
|
|
--duration-decorative: 0ms;
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
}
|
|
|
|
/* === Window resize handles (see ResizeHandles.svelte) ===
|
|
Lives in the global sheet so @tailwindcss/vite does not try to
|
|
parse it as a per-component virtual CSS module, which triggers an
|
|
"Invalid declaration" error on plain CSS inputs in some Tailwind v4
|
|
+ Svelte 5 combinations. */
|
|
.kon-rh {
|
|
position: fixed;
|
|
z-index: 2147483646;
|
|
background: transparent;
|
|
pointer-events: auto;
|
|
touch-action: none;
|
|
user-select: none;
|
|
-webkit-user-select: none;
|
|
}
|
|
|
|
.kon-rh-nw,
|
|
.kon-rh-ne,
|
|
.kon-rh-sw,
|
|
.kon-rh-se {
|
|
z-index: 2147483647;
|
|
}
|
|
|
|
.kon-rh-n {
|
|
top: 0;
|
|
left: var(--kon-resize-corner);
|
|
right: var(--kon-resize-corner);
|
|
height: var(--kon-resize-edge);
|
|
cursor: n-resize;
|
|
}
|
|
.kon-rh-s {
|
|
bottom: 0;
|
|
left: var(--kon-resize-corner);
|
|
right: var(--kon-resize-corner);
|
|
height: var(--kon-resize-edge);
|
|
cursor: s-resize;
|
|
}
|
|
.kon-rh-w {
|
|
top: var(--kon-resize-corner);
|
|
bottom: var(--kon-resize-corner);
|
|
left: 0;
|
|
width: var(--kon-resize-edge);
|
|
cursor: w-resize;
|
|
}
|
|
.kon-rh-e {
|
|
top: var(--kon-resize-corner);
|
|
bottom: var(--kon-resize-corner);
|
|
right: 0;
|
|
width: var(--kon-resize-edge);
|
|
cursor: e-resize;
|
|
}
|
|
|
|
.kon-rh-nw {
|
|
top: 0;
|
|
left: 0;
|
|
width: var(--kon-resize-corner);
|
|
height: var(--kon-resize-corner);
|
|
cursor: nw-resize;
|
|
}
|
|
.kon-rh-ne {
|
|
top: 0;
|
|
right: 0;
|
|
width: var(--kon-resize-corner);
|
|
height: var(--kon-resize-corner);
|
|
cursor: ne-resize;
|
|
}
|
|
.kon-rh-sw {
|
|
bottom: 0;
|
|
left: 0;
|
|
width: var(--kon-resize-corner);
|
|
height: var(--kon-resize-corner);
|
|
cursor: sw-resize;
|
|
}
|
|
.kon-rh-se {
|
|
bottom: 0;
|
|
right: 0;
|
|
width: var(--kon-resize-corner);
|
|
height: var(--kon-resize-corner);
|
|
cursor: se-resize;
|
|
}
|