@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300..900;1,9..144,300..900&family=Inter:ital,wght@0,400;0,500;1,400&family=JetBrains+Mono:ital,wght@0,400;1,400&display=swap'); /* ========================================================================== GENERATED FROM THE DESIGN SYSTEM — Scribe (design system 2), which inherits the FabledSword house style (design system 1). Do not hand-edit the --fs-* block below. Edit the design system in the app and regenerate: /design-systems -> Master stylesheet -> Copy. DARK IS THE BASE LAYER. The kit is dark-mode-first, so :root carries the dark palette and [data-theme="light"] overrides it. That is the inverse of how this file used to read, and it is deliberate: the light palette was never specified by any rule, so it is recorded as a departure rather than as the default. Only 12 tokens differ between modes. Everything else — spacing, type, motion, radius, and every derived colour — is stated once, because a value built with var() resolves where it is USED, not where it is written. ========================================================================== */ :root { /* accent */ --fs-accent: #5B4A8A; /* Scribe's signature colour */ --fs-accent-soft: color-mix(in srgb, var(--fs-accent) 15%, transparent); /* Pill, tag and badge backgrounds */ --fs-accent-faint: color-mix(in srgb, var(--fs-accent) 8%, transparent); /* The faintest accent wash */ --fs-accent-deep: color-mix(in srgb, var(--fs-accent) 70%, black); /* The accent, darkened */ --fs-accent-wash: color-mix(in srgb, var(--fs-accent) 22%, transparent); /* Heaviest accent tint */ --fs-gradient-cta: linear-gradient(135deg, var(--fs-accent), var(--fs-accent-deep)); --fs-glow-cta: 0 2px 10px color-mix(in srgb, var(--fs-accent) 35%, transparent); --fs-glow-cta-hover: 0 4px 24px color-mix(in srgb, var(--fs-accent) 65%, transparent); /* action */ --fs-action-primary: #4A5D3F; /* Save, Submit, Confirm */ --fs-action-secondary: #8B7355; /* Non-destructive alternates */ --fs-action-tertiary: var(--fs-border-color); /* Ghost / outline actions */ --fs-action-destructive: var(--fs-destructive); --fs-action-primary-hover: color-mix(in srgb, var(--fs-action-primary) 88%, white); --fs-action-secondary-hover: color-mix(in srgb, var(--fs-action-secondary) 88%, white); --fs-action-destructive-hover: color-mix(in srgb, var(--fs-action-destructive) 88%, white); /* border */ --fs-border-color: #3F4651; /* Borders, dividers and ghost outlines */ --fs-border: 0.5px solid var(--fs-border-color); --fs-border-hover: 0.5px solid color-mix(in srgb, var(--fs-text-secondary) 30%, transparent); --fs-border-active: 2px solid var(--fs-accent); /* Selected card or active tab only */ /* editor */ --fs-wikilink: var(--fs-accent); /* elevation */ --fs-shadow-1: 0 1px 0 rgba(0,0,0,0.4); /* Hairline lift */ --fs-shadow-2: 0 4px 12px rgba(0,0,0,0.35); /* Dropdowns, popovers */ --fs-shadow-3: 0 16px 40px rgba(0,0,0,0.5); /* Modals */ /* focus */ --fs-focus-ring: 0 0 0 2px var(--fs-accent); /* font */ --fs-font-display: 'Fraunces', Georgia, serif; --fs-font-body: 'Inter', system-ui, sans-serif; --fs-font-mono: 'JetBrains Mono', ui-monospace, Menlo, Consolas, monospace; /* icon */ --fs-icon-stroke: 1.5px; /* at 24px */ --fs-icon-stroke-sm: 1px; /* at 16px */ /* layout */ --fs-layout-page-max: 1200px; --fs-layout-page-pad: 1rem; --fs-layout-sidebar: 260px; --fs-layout-header: 52px; /* motion */ --fs-ease: cubic-bezier(0.2, 0.6, 0.2, 1); /* the one curve */ --fs-dur-fast: 120ms; --fs-dur-base: 180ms; --fs-dur-slow: 280ms; /* priority */ --fs-priority-low: var(--fs-info); --fs-priority-low-bg: color-mix(in srgb, var(--fs-priority-low) 12%, transparent); --fs-priority-medium: var(--fs-warning); --fs-priority-medium-bg: color-mix(in srgb, var(--fs-priority-medium) 12%, transparent); --fs-priority-high: var(--fs-error); --fs-priority-high-bg: color-mix(in srgb, var(--fs-priority-high) 12%, transparent); /* radius */ --fs-radius-sm: 4px; /* pills, tags, code spans */ --fs-radius-md: 8px; /* buttons, inputs, small cards */ --fs-radius-lg: 12px; /* cards, panels, modals */ --fs-radius-xl: 16px; /* hero containers */ --fs-radius-pill: 9999px; /* semantic */ --fs-success: var(--fs-action-primary); --fs-warning: #8B6F1E; --fs-error: #C04A1F; --fs-info: #3D5A6E; --fs-destructive: #6B2118; /* irreversible — deliberately not the error colour */ /* space */ --fs-space-1: 4px; --fs-space-2: 8px; --fs-space-3: 12px; --fs-space-4: 16px; --fs-space-5: 20px; --fs-space-6: 24px; --fs-space-7: 32px; --fs-space-8: 48px; --fs-space-9: 64px; --fs-space-10: 96px; /* state */ --fs-disabled-opacity: 0.5; --fs-overlay: rgba(0, 0, 0, 0.65); /* status */ --fs-status-todo: var(--fs-border-color); --fs-status-todo-bg: color-mix(in srgb, var(--fs-status-todo) 12%, transparent); --fs-status-in-progress: var(--fs-accent); --fs-status-in-progress-bg: color-mix(in srgb, var(--fs-status-in-progress) 12%, transparent); --fs-status-done: var(--fs-success); --fs-status-done-bg: color-mix(in srgb, var(--fs-status-done) 12%, transparent); --fs-overdue: var(--fs-error); --fs-status-cancelled: var(--fs-text-tertiary); /* set aside, not failed */ /* surface */ --fs-surface-page: #14171A; /* page bg, deepest surface */ --fs-surface-raised: #1E2228; /* cards, raised elements */ --fs-surface-hover: #2C313A; /* hovered surfaces */ --fs-surface-code: var(--fs-surface-page); --fs-surface-code-inline: var(--fs-surface-raised); --fs-table-stripe: color-mix(in srgb, var(--fs-text-primary) 3%, transparent); /* text */ --fs-text-primary: #E8E4D8; /* also the text colour on filled action buttons */ --fs-text-secondary: #C2BFB4; --fs-text-tertiary: #9C9A92; /* type */ --fs-size-display: 40px; --fs-size-h1: 32px; --fs-size-h2: 24px; --fs-size-h3: 18px; --fs-size-body: 15px; --fs-size-body-sm: 13px; --fs-size-label: 12px; --fs-size-code: 13px; --fs-size-tiny: 11px; /* the only ALL CAPS, the only non-default tracking */ --fs-weight-regular: 400; --fs-weight-medium: 500; /* the heaviest the system goes */ --fs-leading-heading: 1.3; --fs-leading-body: 1.5; --fs-leading-longform: 1.7; --fs-tracking-tiny: 0.08em; } [data-theme="light"] { /* accent */ --fs-accent-wash: color-mix(in srgb, var(--fs-accent) 20%, transparent); --fs-glow-cta-hover: 0 4px 20px color-mix(in srgb, var(--fs-accent) 55%, transparent); /* border */ --fs-border-color: #D9D6CE; /* state */ --fs-overlay: rgba(0, 0, 0, 0.45); /* surface */ --fs-surface-page: #F5F1E8; --fs-surface-raised: #FBF8F0; --fs-surface-hover: #EFEAE0; --fs-surface-code: #EBEDF0; --fs-surface-code-inline: #EBEDF0; /* text */ --fs-text-primary: #14171A; --fs-text-secondary: #5A5852; --fs-text-tertiary: #9A9890; } /* SUPERSEDES — write the token, not the literal. * #fff -> --fs-text-primary * #ffffff -> --fs-text-primary * white -> --fs-text-primary * bold -> --fs-weight-medium * bolder -> --fs-weight-medium */ /* ========================================================================== COMPATIBILITY ALIASES — the app's historical names, pointing at the system. These exist so ~55 components keep working while they migrate to --fs-* one at a time. Every one is a plain var() reference, which is what lets this block be declared ONCE: when [data-theme="light"] moves --fs-surface-page, --color-bg follows, because the alias resolves at use time. That is why this file lost 48 of its 60 dark-mode overrides — they were all restating relationships the aliases now express directly. Removing this block is a rename sweep across the components, tracked separately. Nothing new should reference a --color-* name. ========================================================================== */ :root { /* surfaces */ --color-bg: var(--fs-surface-page); --color-bg-secondary: var(--fs-surface-raised); --color-bg-card: var(--fs-surface-raised); --color-surface: var(--fs-surface-hover); --color-code-bg: var(--fs-surface-code); --color-code-inline-bg: var(--fs-surface-code-inline); --color-table-stripe: var(--fs-table-stripe); --color-overlay: var(--fs-overlay); /* text */ --color-text: var(--fs-text-primary); --color-text-secondary: var(--fs-text-secondary); --color-text-muted: var(--fs-text-tertiary); /* lines */ --color-border: var(--fs-border-color); --color-input-border: var(--fs-border-color); --focus-ring: var(--fs-focus-ring); /* brand */ --color-primary: var(--fs-accent); --color-primary-solid: var(--fs-accent); --color-primary-deep: var(--fs-accent-deep); --color-primary-faint: var(--fs-accent-faint); --color-primary-tint: var(--fs-accent-soft); --color-primary-wash: var(--fs-accent-wash); --color-tag-bg: var(--fs-accent-soft); --color-tag-text: var(--fs-accent); --color-wikilink: var(--fs-wikilink); --color-wikilink-bg: var(--fs-accent-soft); --gradient-cta: var(--fs-gradient-cta); --glow-cta: var(--fs-glow-cta); --glow-cta-hover: var(--fs-glow-cta-hover); /* actions */ --color-action-primary: var(--fs-action-primary); --color-action-primary-hover: var(--fs-action-primary-hover); --color-action-secondary: var(--fs-action-secondary); --color-action-secondary-hover: var(--fs-action-secondary-hover); --color-action-destructive: var(--fs-action-destructive); --color-action-destructive-hover: var(--fs-action-destructive-hover); /* semantic */ --color-success: var(--fs-success); --color-warning: var(--fs-warning); --color-danger: var(--fs-error); --color-overdue: var(--fs-overdue); --color-toast-success: var(--fs-success); --color-toast-error: var(--fs-error); --color-shadow: rgba(0, 0, 0, 0.4); /* task status + priority */ --color-status-todo: var(--fs-status-todo); --color-status-todo-bg: var(--fs-status-todo-bg); --color-status-in-progress: var(--fs-status-in-progress); --color-status-in-progress-bg: var(--fs-status-in-progress-bg); --color-status-done: var(--fs-status-done); --color-status-done-bg: var(--fs-status-done-bg); --color-priority-low: var(--fs-priority-low); --color-priority-low-bg: var(--fs-priority-low-bg); --color-priority-medium: var(--fs-priority-medium); --color-priority-medium-bg: var(--fs-priority-medium-bg); --color-priority-high: var(--fs-priority-high); --color-priority-high-bg: var(--fs-priority-high-bg); /* geometry */ --radius-sm: var(--fs-radius-sm); --radius-md: var(--fs-radius-lg); /* NB: the app's "md" is the system's LARGE */ --radius-lg: var(--fs-radius-xl); /* and the app's "lg" is the system's XL */ --page-max-width: var(--fs-layout-page-max); --page-padding-x: var(--fs-layout-page-pad); --sidebar-width: var(--fs-layout-sidebar); --header-height: var(--fs-layout-header); /* ------------------------------------------------------------------ Names components reference that were NEVER declared anywhere. Each of these was reached for with a hardcoded fallback, so the page rendered — but the fallback was what rendered, always, and several were off-palette: --color-primary-bg fell back to an indigo, --color-destructive to a brick that is not the oxblood, --color-status-cancelled to a grey from no palette in this system. Wiring them to real tokens is the whole point of the exercise. Expect small visual shifts exactly where a fallback had drifted; that shift IS the fix. ------------------------------------------------------------------ */ --color-accent: var(--fs-accent); --color-accent-fg: var(--fs-text-primary); --color-hover: var(--fs-surface-hover); --color-bg-hover: var(--fs-surface-hover); --color-bg-tertiary: var(--fs-surface-hover); --color-surface-2: var(--fs-surface-hover); --color-surface-alt: var(--fs-surface-hover); --color-surface-raised: var(--fs-surface-raised); --color-input-bg: var(--fs-surface-page); --color-muted: var(--fs-text-tertiary); --color-destructive: var(--fs-destructive); --color-primary-bg: var(--fs-accent-soft); --color-status-cancelled: var(--fs-status-cancelled); --font-display: var(--fs-font-display); --font-mono: var(--fs-font-mono); } /* ========================================================================== Base element styles ========================================================================== */ *, *::before, *::after { box-sizing: border-box; } body { margin: 0; background: var(--fs-surface-page); color: var(--fs-text-primary); font-family: var(--fs-font-body); font-feature-settings: "cv11"; line-height: var(--fs-leading-body); transition: background-color var(--fs-dur-base) var(--fs-ease), color var(--fs-dur-base) var(--fs-ease); } h1, h2 { font-family: var(--fs-font-display); font-optical-sizing: auto; font-weight: var(--fs-weight-medium); line-height: var(--fs-leading-heading); } h3 { font-family: var(--fs-font-body); font-weight: var(--fs-weight-medium); line-height: var(--fs-leading-heading); } code, pre, kbd, samp { font-family: var(--fs-font-mono); font-feature-settings: "liga", "calt"; } ::selection { background: var(--fs-accent-wash); color: var(--fs-text-primary); } input:focus-visible, textarea:focus-visible, select:focus-visible, button:focus-visible, a:focus-visible { outline: none; box-shadow: var(--fs-focus-ring); border-radius: var(--fs-radius-sm); } button:not(:disabled):active, .btn:not(:disabled):active, [role="button"]:not(:disabled):active { transform: scale(0.97); transition: transform 0.08s var(--fs-ease); } /* Responsive breakpoints: 480px (phone), 768px (tablet), 1024px (desktop) */ @media (max-width: 768px) { .hide-mobile { display: none !important; } button, [role="button"], .btn-new-conv, .btn-send { min-height: 44px; } } @media (min-width: 769px) { .hide-desktop { display: none !important; } } /* Neutral hairline scrollbars — chrome is structural, not branded */ ::-webkit-scrollbar { width: 4px; height: 4px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--fs-border-color); border-radius: var(--fs-radius-pill); } ::-webkit-scrollbar-thumb:hover { background: var(--fs-text-tertiary); } /* Floating inline assist button (teleported to body, cannot be scoped) */ .inline-assist-btn { position: fixed; z-index: 150; transform: translateX(-50%); background: var(--fs-accent); color: var(--fs-text-primary); border: none; border-radius: var(--fs-radius-pill); padding: 0.3rem 0.8rem; font-size: var(--fs-size-body-sm); cursor: pointer; box-shadow: var(--fs-shadow-2); white-space: nowrap; } .inline-assist-btn:hover { filter: brightness(1.1); }