full dark theme for marimo, PFS payment calculator notebook, marimo check pre-commit hook
Rewrote retro-arcade CSS to properly integrate with marimo's theming: override all Radix color scales, Tailwind prose vars, and semantic variables so no dark blue or black text appears on the navy background. Switched marimo.toml to theme=dark. Added pfs_calcs.py notebook demonstrating three ways to look up PFS payment rates (carrier file, RVU calc, pure SQL). Fixed all marimo check warnings/errors across existing notebooks (branch expressions, empty cells, raw strings). Added marimo check to pre-commit hook.
This commit is contained in:
496
css/marimo.css
496
css/marimo.css
@@ -1,17 +1,8 @@
|
|||||||
/* THROWBACK THEME - Tecmo Super Bowl */
|
/* THROWBACK THEME - Tecmo Super Bowl */
|
||||||
/* Uses marimo's native CSS variable system for proper theming */
|
/* Full marimo theme: semantic vars, Radix scales, prose, CodeMirror */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
FONT CONFIGURATION
|
|
||||||
============================================ */
|
|
||||||
:root {
|
|
||||||
--marimo-monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
|
||||||
--marimo-text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
|
||||||
--marimo-heading-font: 'Press Start 2P', 'IBM Plex Mono', monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
THROWBACK COLOR PALETTE
|
THROWBACK COLOR PALETTE
|
||||||
============================================ */
|
============================================ */
|
||||||
@@ -20,126 +11,389 @@
|
|||||||
--tb-navy-light: #162040;
|
--tb-navy-light: #162040;
|
||||||
--tb-navy-mid: #1e2d50;
|
--tb-navy-mid: #1e2d50;
|
||||||
--tb-slate: #2a3f5f;
|
--tb-slate: #2a3f5f;
|
||||||
--tb-steel: #5a7090;
|
--tb-steel: #8a9fbb;
|
||||||
|
--tb-silver: #b0c0d8;
|
||||||
--tb-white: #f0f0f0;
|
--tb-white: #f0f0f0;
|
||||||
|
|
||||||
--tb-blue: #3366cc;
|
--tb-blue: #4477dd;
|
||||||
--tb-blue-light: #5588dd;
|
--tb-blue-light: #6699ee;
|
||||||
--tb-blue-bright: #88aaee;
|
--tb-blue-bright: #99bbff;
|
||||||
|
|
||||||
--tb-red: #cc2244;
|
--tb-red: #cc2244;
|
||||||
--tb-red-light: #dd4466;
|
--tb-red-light: #ee6688;
|
||||||
|
--tb-red-bright: #ffaabc;
|
||||||
|
|
||||||
--tb-green: #44aa44;
|
--tb-green: #44aa44;
|
||||||
--tb-green-light: #66cc66;
|
--tb-green-light: #77dd77;
|
||||||
--tb-yellow: #ddaa33;
|
--tb-green-bright: #b1f1b1;
|
||||||
|
|
||||||
|
--tb-yellow: #eebb44;
|
||||||
|
--tb-yellow-light: #ffdd77;
|
||||||
|
--tb-yellow-bright: #fff0bb;
|
||||||
|
|
||||||
|
--tb-purple: #9977cc;
|
||||||
|
--tb-purple-light: #bb99ee;
|
||||||
|
|
||||||
|
--tb-cyan: #55bbcc;
|
||||||
|
--tb-cyan-light: #88ddee;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
MARIMO THEME VARIABLES (Dark Mode)
|
FONT CONFIGURATION
|
||||||
|
============================================ */
|
||||||
|
:root {
|
||||||
|
--monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
|
--text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
|
--heading-font: 'Press Start 2P', 'IBM Plex Mono', monospace;
|
||||||
|
--marimo-monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
|
--marimo-text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
|
--marimo-heading-font: 'Press Start 2P', 'IBM Plex Mono', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
MARIMO SEMANTIC VARIABLES
|
||||||
============================================ */
|
============================================ */
|
||||||
:root {
|
:root {
|
||||||
/* Base colors */
|
|
||||||
--background: var(--tb-navy);
|
--background: var(--tb-navy);
|
||||||
--foreground: var(--tb-white);
|
--foreground: var(--tb-white);
|
||||||
|
|
||||||
/* Muted/secondary text */
|
|
||||||
--muted: var(--tb-navy-light);
|
--muted: var(--tb-navy-light);
|
||||||
--muted-foreground: var(--tb-steel);
|
--muted-foreground: var(--tb-steel);
|
||||||
|
|
||||||
/* Popover/dropdown backgrounds */
|
|
||||||
--popover: var(--tb-navy-light);
|
--popover: var(--tb-navy-light);
|
||||||
--popover-foreground: var(--tb-white);
|
--popover-foreground: var(--tb-white);
|
||||||
|
|
||||||
/* Cards (cells) */
|
|
||||||
--card: var(--tb-navy);
|
--card: var(--tb-navy);
|
||||||
--card-foreground: var(--tb-white);
|
--card-foreground: var(--tb-white);
|
||||||
|
|
||||||
/* Borders and inputs */
|
|
||||||
--border: var(--tb-slate);
|
--border: var(--tb-slate);
|
||||||
--input: var(--tb-navy-mid);
|
--input: var(--tb-navy-mid);
|
||||||
|
--ring: var(--tb-blue-light);
|
||||||
|
--radius: 2px;
|
||||||
|
|
||||||
/* Primary action color */
|
|
||||||
--primary: var(--tb-blue);
|
--primary: var(--tb-blue);
|
||||||
--primary-foreground: var(--tb-white);
|
--primary-foreground: var(--tb-white);
|
||||||
|
|
||||||
/* Secondary elements */
|
|
||||||
--secondary: var(--tb-slate);
|
--secondary: var(--tb-slate);
|
||||||
--secondary-foreground: var(--tb-white);
|
--secondary-foreground: var(--tb-white);
|
||||||
|
|
||||||
/* Accent/highlight */
|
--accent: var(--tb-navy-mid);
|
||||||
--accent: var(--tb-blue-light);
|
--accent-foreground: var(--tb-blue-bright);
|
||||||
--accent-foreground: var(--tb-white);
|
|
||||||
|
|
||||||
/* Focus ring */
|
|
||||||
--ring: var(--tb-blue-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
SEMANTIC COLORS
|
|
||||||
============================================ */
|
|
||||||
:root {
|
|
||||||
/* Error states */
|
|
||||||
--destructive: var(--tb-red);
|
--destructive: var(--tb-red);
|
||||||
--destructive-foreground: var(--tb-white);
|
--destructive-foreground: var(--tb-white);
|
||||||
|
|
||||||
--error: var(--tb-red);
|
--error: var(--tb-red);
|
||||||
--error-foreground: var(--tb-white);
|
--error-foreground: var(--tb-white);
|
||||||
|
|
||||||
/* Success states */
|
--success: var(--tb-green-light);
|
||||||
--success: var(--tb-green);
|
|
||||||
--success-foreground: var(--tb-white);
|
--success-foreground: var(--tb-white);
|
||||||
|
|
||||||
/* Action buttons (run, etc) */
|
--action: var(--tb-yellow);
|
||||||
--action: var(--tb-green);
|
--action-hover: var(--tb-yellow-light);
|
||||||
--action-hover: var(--tb-green-light);
|
|
||||||
--action-foreground: var(--tb-navy);
|
--action-foreground: var(--tb-navy);
|
||||||
|
|
||||||
/* Links */
|
|
||||||
--link: var(--tb-blue-bright);
|
--link: var(--tb-blue-bright);
|
||||||
--link-visited: var(--tb-blue-light);
|
--link-visited: var(--tb-purple-light);
|
||||||
|
|
||||||
/* Stale indicator */
|
--stale: rgba(238, 187, 68, 0.25);
|
||||||
--stale: rgba(221, 170, 51, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
SHADOWS
|
|
||||||
============================================ */
|
|
||||||
:root {
|
|
||||||
--base-shadow: rgba(0, 0, 0, 0.4);
|
--base-shadow: rgba(0, 0, 0, 0.4);
|
||||||
--base-shadow-darker: rgba(0, 0, 0, 0.6);
|
--base-shadow-darker: rgba(0, 0, 0, 0.6);
|
||||||
--base-shadow-opacity: 20%;
|
--base-shadow-opacity: 20%;
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
--cm-background: var(--tb-navy);
|
||||||
BACKGROUND
|
|
||||||
============================================ */
|
|
||||||
:root {
|
|
||||||
--background-image: none;
|
--background-image: none;
|
||||||
--background-repeat: no-repeat;
|
--background-repeat: no-repeat;
|
||||||
--background-attachment: fixed;
|
--background-attachment: fixed;
|
||||||
--background-size: cover;
|
--background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
RADIX COLOR SCALES - Navy-tinted
|
||||||
|
Remap neutral scales so all UI surfaces
|
||||||
|
use navy tones instead of default grays.
|
||||||
|
Steps 11-12 must be bright for text.
|
||||||
|
============================================ */
|
||||||
|
.dark, .dark-theme, :root {
|
||||||
|
/* Gray → Navy */
|
||||||
|
--gray-1: #0a1628;
|
||||||
|
--gray-2: #0f1b30;
|
||||||
|
--gray-3: #162040;
|
||||||
|
--gray-4: #1e2d50;
|
||||||
|
--gray-5: #253660;
|
||||||
|
--gray-6: #2a3f5f;
|
||||||
|
--gray-7: #3a5070;
|
||||||
|
--gray-8: #506888;
|
||||||
|
--gray-9: #6a82a0;
|
||||||
|
--gray-10: #7a94b4;
|
||||||
|
--gray-11: #a0b4cc;
|
||||||
|
--gray-12: #e8edf4;
|
||||||
|
|
||||||
|
/* Slate → Navy */
|
||||||
|
--slate-1: #0a1628;
|
||||||
|
--slate-2: #0f1b30;
|
||||||
|
--slate-3: #162040;
|
||||||
|
--slate-4: #1e2d50;
|
||||||
|
--slate-5: #253660;
|
||||||
|
--slate-6: #2a3f5f;
|
||||||
|
--slate-7: #3a5070;
|
||||||
|
--slate-8: #506888;
|
||||||
|
--slate-9: #6a82a0;
|
||||||
|
--slate-10: #7a94b4;
|
||||||
|
--slate-11: #a0b4cc;
|
||||||
|
--slate-12: #e8edf4;
|
||||||
|
|
||||||
|
/* Sage → Navy (slight green tint) */
|
||||||
|
--sage-1: #0a1620;
|
||||||
|
--sage-2: #0f1b2a;
|
||||||
|
--sage-3: #152038;
|
||||||
|
--sage-4: #1c2d48;
|
||||||
|
--sage-5: #243658;
|
||||||
|
--sage-6: #2a3f5a;
|
||||||
|
--sage-7: #38506a;
|
||||||
|
--sage-8: #4e6882;
|
||||||
|
--sage-9: #68829c;
|
||||||
|
--sage-10: #7894b0;
|
||||||
|
--sage-11: #a0b4c8;
|
||||||
|
--sage-12: #e6ecf2;
|
||||||
|
|
||||||
|
/* Blue - subtle navy tints for bg steps, bright for text steps */
|
||||||
|
--blue-1: #0a1628;
|
||||||
|
--blue-2: #0e1a30;
|
||||||
|
--blue-3: #121f3a;
|
||||||
|
--blue-4: #162544;
|
||||||
|
--blue-5: #1c2e52;
|
||||||
|
--blue-6: #243a62;
|
||||||
|
--blue-7: #2e4a78;
|
||||||
|
--blue-8: #3a5e96;
|
||||||
|
--blue-9: #4477dd;
|
||||||
|
--blue-10: #6699ee;
|
||||||
|
--blue-11: #99bbff;
|
||||||
|
--blue-12: #ccdcff;
|
||||||
|
|
||||||
|
/* Red */
|
||||||
|
--red-1: #1a0f14;
|
||||||
|
--red-2: #24121a;
|
||||||
|
--red-3: #3a1420;
|
||||||
|
--red-4: #50162a;
|
||||||
|
--red-5: #661a34;
|
||||||
|
--red-6: #802040;
|
||||||
|
--red-7: #aa3050;
|
||||||
|
--red-8: #cc2244;
|
||||||
|
--red-9: #dd4466;
|
||||||
|
--red-10: #ee6688;
|
||||||
|
--red-11: #ff99aa;
|
||||||
|
--red-12: #ffd0d8;
|
||||||
|
|
||||||
|
/* Green */
|
||||||
|
--green-1: #0c1610;
|
||||||
|
--green-2: #101e14;
|
||||||
|
--green-3: #162a1c;
|
||||||
|
--green-4: #1c3824;
|
||||||
|
--green-5: #22462e;
|
||||||
|
--green-6: #2a5838;
|
||||||
|
--green-7: #348844;
|
||||||
|
--green-8: #44aa44;
|
||||||
|
--green-9: #55bb55;
|
||||||
|
--green-10: #77dd77;
|
||||||
|
--green-11: #99ee99;
|
||||||
|
--green-12: #ccffcc;
|
||||||
|
|
||||||
|
/* Grass (similar to green) */
|
||||||
|
--grass-1: #0c1610;
|
||||||
|
--grass-2: #101e14;
|
||||||
|
--grass-3: #162a1c;
|
||||||
|
--grass-4: #1c3824;
|
||||||
|
--grass-5: #22462e;
|
||||||
|
--grass-6: #2a5838;
|
||||||
|
--grass-7: #348844;
|
||||||
|
--grass-8: #44aa44;
|
||||||
|
--grass-9: #55bb55;
|
||||||
|
--grass-10: #77dd77;
|
||||||
|
--grass-11: #99ee99;
|
||||||
|
--grass-12: #ccffcc;
|
||||||
|
|
||||||
|
/* Yellow */
|
||||||
|
--yellow-1: #16140a;
|
||||||
|
--yellow-2: #1e1c0e;
|
||||||
|
--yellow-3: #302804;
|
||||||
|
--yellow-4: #443800;
|
||||||
|
--yellow-5: #584800;
|
||||||
|
--yellow-6: #6c5a08;
|
||||||
|
--yellow-7: #887018;
|
||||||
|
--yellow-8: #aa8a28;
|
||||||
|
--yellow-9: #eebb44;
|
||||||
|
--yellow-10: #ffdd77;
|
||||||
|
--yellow-11: #ffee99;
|
||||||
|
--yellow-12: #fff8cc;
|
||||||
|
|
||||||
|
/* Amber */
|
||||||
|
--amber-1: #16120a;
|
||||||
|
--amber-2: #1e1a0e;
|
||||||
|
--amber-3: #302408;
|
||||||
|
--amber-4: #443200;
|
||||||
|
--amber-5: #584000;
|
||||||
|
--amber-6: #6c5008;
|
||||||
|
--amber-7: #886418;
|
||||||
|
--amber-8: #aa7c28;
|
||||||
|
--amber-9: #eebb44;
|
||||||
|
--amber-10: #ffcc55;
|
||||||
|
--amber-11: #ffdd88;
|
||||||
|
--amber-12: #fff0cc;
|
||||||
|
|
||||||
|
/* Purple */
|
||||||
|
--purple-1: #140f1e;
|
||||||
|
--purple-2: #1c1428;
|
||||||
|
--purple-3: #281c3a;
|
||||||
|
--purple-4: #34244e;
|
||||||
|
--purple-5: #402c60;
|
||||||
|
--purple-6: #503872;
|
||||||
|
--purple-7: #664888;
|
||||||
|
--purple-8: #8060aa;
|
||||||
|
--purple-9: #9977cc;
|
||||||
|
--purple-10: #aa88dd;
|
||||||
|
--purple-11: #cc99ff;
|
||||||
|
--purple-12: #e8ccff;
|
||||||
|
|
||||||
|
/* Crimson */
|
||||||
|
--crimson-1: #1a0e14;
|
||||||
|
--crimson-2: #24121c;
|
||||||
|
--crimson-3: #3a1428;
|
||||||
|
--crimson-4: #501634;
|
||||||
|
--crimson-5: #661840;
|
||||||
|
--crimson-6: #802050;
|
||||||
|
--crimson-7: #aa3068;
|
||||||
|
--crimson-8: #cc4080;
|
||||||
|
--crimson-9: #dd5090;
|
||||||
|
--crimson-10: #ee70a8;
|
||||||
|
--crimson-11: #ff99c4;
|
||||||
|
--crimson-12: #ffd0e4;
|
||||||
|
|
||||||
|
/* Cyan */
|
||||||
|
--cyan-1: #0a1418;
|
||||||
|
--cyan-2: #0e1c22;
|
||||||
|
--cyan-3: #122830;
|
||||||
|
--cyan-4: #163640;
|
||||||
|
--cyan-5: #1c4450;
|
||||||
|
--cyan-6: #225560;
|
||||||
|
--cyan-7: #306a78;
|
||||||
|
--cyan-8: #408898;
|
||||||
|
--cyan-9: #55aabc;
|
||||||
|
--cyan-10: #77ccdd;
|
||||||
|
--cyan-11: #99ddee;
|
||||||
|
--cyan-12: #ccf0f8;
|
||||||
|
|
||||||
|
/* Sky */
|
||||||
|
--sky-1: #0a1420;
|
||||||
|
--sky-2: #0e1c2c;
|
||||||
|
--sky-3: #122840;
|
||||||
|
--sky-4: #163656;
|
||||||
|
--sky-5: #1c4468;
|
||||||
|
--sky-6: #225580;
|
||||||
|
--sky-7: #306a98;
|
||||||
|
--sky-8: #4088b4;
|
||||||
|
--sky-9: #55aadd;
|
||||||
|
--sky-10: #77ccee;
|
||||||
|
--sky-11: #99ddff;
|
||||||
|
--sky-12: #ccf0ff;
|
||||||
|
|
||||||
|
/* Orange */
|
||||||
|
--orange-1: #1a1008;
|
||||||
|
--orange-2: #241810;
|
||||||
|
--orange-3: #38200a;
|
||||||
|
--orange-4: #4c2a00;
|
||||||
|
--orange-5: #603600;
|
||||||
|
--orange-6: #744408;
|
||||||
|
--orange-7: #905818;
|
||||||
|
--orange-8: #b07028;
|
||||||
|
--orange-9: #ee8833;
|
||||||
|
--orange-10: #ffaa55;
|
||||||
|
--orange-11: #ffcc88;
|
||||||
|
--orange-12: #ffe8cc;
|
||||||
|
|
||||||
|
/* Lime */
|
||||||
|
--lime-1: #12160a;
|
||||||
|
--lime-2: #1a1e0e;
|
||||||
|
--lime-3: #242c08;
|
||||||
|
--lime-4: #303a00;
|
||||||
|
--lime-5: #3e4800;
|
||||||
|
--lime-6: #4e5a08;
|
||||||
|
--lime-7: #627018;
|
||||||
|
--lime-8: #7a8a28;
|
||||||
|
--lime-9: #99aa44;
|
||||||
|
--lime-10: #bbcc66;
|
||||||
|
--lime-11: #ccee88;
|
||||||
|
--lime-12: #eeffcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
TAILWIND PROSE - Markdown content
|
||||||
|
============================================ */
|
||||||
|
:root {
|
||||||
|
--tw-prose-body: var(--tb-white);
|
||||||
|
--tw-prose-headings: var(--tb-white);
|
||||||
|
--tw-prose-lead: var(--tb-silver);
|
||||||
|
--tw-prose-links: var(--tb-blue-bright);
|
||||||
|
--tw-prose-bold: var(--tb-white);
|
||||||
|
--tw-prose-counters: var(--tb-steel);
|
||||||
|
--tw-prose-bullets: var(--tb-steel);
|
||||||
|
--tw-prose-hr: var(--tb-slate);
|
||||||
|
--tw-prose-quotes: var(--tb-silver);
|
||||||
|
--tw-prose-quote-borders: var(--tb-slate);
|
||||||
|
--tw-prose-captions: var(--tb-steel);
|
||||||
|
--tw-prose-kbd: var(--tb-white);
|
||||||
|
--tw-prose-kbd-shadows: rgba(240, 240, 240, 0.1);
|
||||||
|
--tw-prose-code: var(--tb-blue-bright);
|
||||||
|
--tw-prose-pre-code: var(--tb-silver);
|
||||||
|
--tw-prose-pre-bg: var(--tb-navy-light);
|
||||||
|
--tw-prose-th-borders: var(--tb-slate);
|
||||||
|
--tw-prose-td-borders: var(--tb-navy-mid);
|
||||||
|
|
||||||
|
/* Invert variants (used in dark mode) */
|
||||||
|
--tw-prose-invert-body: var(--tb-white);
|
||||||
|
--tw-prose-invert-headings: var(--tb-white);
|
||||||
|
--tw-prose-invert-lead: var(--tb-silver);
|
||||||
|
--tw-prose-invert-links: var(--tb-blue-bright);
|
||||||
|
--tw-prose-invert-bold: var(--tb-white);
|
||||||
|
--tw-prose-invert-counters: var(--tb-steel);
|
||||||
|
--tw-prose-invert-bullets: var(--tb-steel);
|
||||||
|
--tw-prose-invert-hr: var(--tb-slate);
|
||||||
|
--tw-prose-invert-quotes: var(--tb-silver);
|
||||||
|
--tw-prose-invert-quote-borders: var(--tb-slate);
|
||||||
|
--tw-prose-invert-captions: var(--tb-steel);
|
||||||
|
--tw-prose-invert-kbd: var(--tb-white);
|
||||||
|
--tw-prose-invert-kbd-shadows: rgba(240, 240, 240, 0.1);
|
||||||
|
--tw-prose-invert-code: var(--tb-blue-bright);
|
||||||
|
--tw-prose-invert-pre-code: var(--tb-silver);
|
||||||
|
--tw-prose-invert-pre-bg: var(--tb-navy-light);
|
||||||
|
--tw-prose-invert-th-borders: var(--tb-slate);
|
||||||
|
--tw-prose-invert-td-borders: var(--tb-navy-mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
BODY & BACKGROUNDS
|
||||||
|
============================================ */
|
||||||
body {
|
body {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--tb-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
CODE EDITOR - CODEMIRROR STYLING
|
CODE EDITOR - CODEMIRROR
|
||||||
============================================ */
|
============================================ */
|
||||||
.cm-editor {
|
.cm-editor {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--tb-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-content {
|
.cm-content {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-line {
|
.cm-line {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--tb-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +404,7 @@ body {
|
|||||||
|
|
||||||
.cm-lineNumbers .cm-gutterElement {
|
.cm-lineNumbers .cm-gutterElement {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--tb-steel) !important;
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,65 +422,52 @@ body {
|
|||||||
.tok-typeName { color: var(--tb-yellow) !important; }
|
.tok-typeName { color: var(--tb-yellow) !important; }
|
||||||
.tok-bool { color: var(--tb-red-light) !important; }
|
.tok-bool { color: var(--tb-red-light) !important; }
|
||||||
|
|
||||||
/* Cursor */
|
|
||||||
.cm-cursor {
|
.cm-cursor {
|
||||||
border-left: 2px solid var(--tb-white) !important;
|
border-left: 2px solid var(--tb-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Selection */
|
|
||||||
.cm-selectionBackground,
|
.cm-selectionBackground,
|
||||||
::selection {
|
::selection {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--tb-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Active line */
|
|
||||||
.cm-activeLine {
|
.cm-activeLine {
|
||||||
background: rgba(51, 102, 204, 0.15) !important;
|
background: rgba(68, 119, 221, 0.12) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
HEADINGS
|
HEADINGS
|
||||||
============================================ */
|
============================================ */
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
font-family: var(--marimo-heading-font) !important;
|
font-family: var(--heading-font) !important;
|
||||||
letter-spacing: 0.5px !important;
|
letter-spacing: 0.5px !important;
|
||||||
line-height: 1.8 !important;
|
line-height: 1.8 !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 { font-size: 18px !important; }
|
||||||
font-size: 18px !important;
|
h2 { font-size: 14px !important; color: var(--tb-blue-bright) !important; }
|
||||||
color: var(--tb-white) !important;
|
h3 { font-size: 12px !important; }
|
||||||
}
|
h4, h5, h6 { font-size: 11px !important; }
|
||||||
h2 {
|
|
||||||
font-size: 14px !important;
|
|
||||||
color: var(--tb-blue-bright) !important;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
font-size: 12px !important;
|
|
||||||
color: var(--tb-white) !important;
|
|
||||||
}
|
|
||||||
h4, h5, h6 {
|
|
||||||
font-size: 11px !important;
|
|
||||||
color: var(--tb-white) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
TABLES (Scoreboard style)
|
TABLES (Scoreboard style)
|
||||||
============================================ */
|
============================================ */
|
||||||
table {
|
table {
|
||||||
border-collapse: collapse !important;
|
border-collapse: collapse !important;
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--tb-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--tb-white) !important;
|
||||||
font-family: var(--marimo-heading-font) !important;
|
font-family: var(--heading-font) !important;
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
padding: 10px 12px !important;
|
padding: 10px 12px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 1px !important;
|
letter-spacing: 1px !important;
|
||||||
border: 1px solid var(--tb-blue-light) !important;
|
border: 1px solid var(--tb-slate) !important;
|
||||||
|
border-bottom: 2px solid var(--tb-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
@@ -242,7 +483,7 @@ tr:nth-child(even) td {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr:hover td {
|
tr:hover td {
|
||||||
background: rgba(51, 102, 204, 0.2) !important;
|
background: rgba(68, 119, 221, 0.2) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -251,18 +492,17 @@ tr:hover td {
|
|||||||
button,
|
button,
|
||||||
[role="button"],
|
[role="button"],
|
||||||
.btn {
|
.btn {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
font-weight: 500 !important;
|
font-weight: 500 !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 2px !important;
|
||||||
transition: all 0.15s ease !important;
|
transition: all 0.15s ease !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Primary/action buttons should be visible */
|
|
||||||
button[data-variant="primary"],
|
button[data-variant="primary"],
|
||||||
button.primary,
|
button.primary,
|
||||||
[data-action="run"] {
|
[data-action="run"] {
|
||||||
background: var(--tb-green) !important;
|
background: var(--tb-green) !important;
|
||||||
color: var(--tb-navy) !important;
|
color: var(--tb-white) !important;
|
||||||
border: 2px solid var(--tb-green-light) !important;
|
border: 2px solid var(--tb-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,11 +518,11 @@ button.primary:hover,
|
|||||||
input,
|
input,
|
||||||
textarea,
|
textarea,
|
||||||
select {
|
select {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--tb-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--tb-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--tb-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 2px !important;
|
||||||
padding: 8px 12px !important;
|
padding: 8px 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,28 +531,28 @@ textarea:focus,
|
|||||||
select:focus {
|
select:focus {
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--tb-blue-light) !important;
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
box-shadow: 0 0 0 2px rgba(85, 136, 221, 0.3) !important;
|
box-shadow: 0 0 0 2px rgba(102, 153, 238, 0.3) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
CODE BLOCKS (in markdown)
|
CODE BLOCKS (in markdown)
|
||||||
============================================ */
|
============================================ */
|
||||||
pre, code {
|
pre, code {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--tb-navy-light) !important;
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--tb-blue-bright) !important;
|
||||||
padding: 2px 6px !important;
|
padding: 2px 6px !important;
|
||||||
border-radius: 3px !important;
|
border-radius: 2px !important;
|
||||||
font-size: 0.9em !important;
|
font-size: 0.9em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--tb-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--tb-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 2px !important;
|
||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +576,7 @@ a:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a:visited {
|
a:visited {
|
||||||
color: var(--tb-blue-light) !important;
|
color: var(--tb-purple-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -362,26 +602,23 @@ a:visited {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
MISC UI REFINEMENTS
|
TOOLTIPS, DROPDOWNS, MENUS
|
||||||
============================================ */
|
============================================ */
|
||||||
|
|
||||||
/* Tooltips */
|
|
||||||
[role="tooltip"],
|
[role="tooltip"],
|
||||||
[data-state="open"][data-side] {
|
[data-state="open"][data-side] {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--tb-navy-light) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--tb-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--tb-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dropdown menus */
|
|
||||||
[role="menu"],
|
[role="menu"],
|
||||||
[role="listbox"] {
|
[role="listbox"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--tb-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--tb-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[role="menuitem"]:hover,
|
[role="menuitem"]:hover,
|
||||||
@@ -396,12 +633,11 @@ a:visited {
|
|||||||
[class*="badge"],
|
[class*="badge"],
|
||||||
[class*="pill"],
|
[class*="pill"],
|
||||||
[class*="tag"] {
|
[class*="tag"] {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
font-weight: 500 !important;
|
font-weight: 500 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Focus visible for accessibility */
|
|
||||||
:focus-visible {
|
:focus-visible {
|
||||||
outline: 2px solid var(--tb-blue-light) !important;
|
outline: 2px solid var(--tb-blue-light) !important;
|
||||||
outline-offset: 2px !important;
|
outline-offset: 2px !important;
|
||||||
@@ -417,12 +653,10 @@ a:visited {
|
|||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DataFrame outputs */
|
|
||||||
[class*="dataframe"] {
|
[class*="dataframe"] {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Plot/chart containers */
|
|
||||||
[class*="plot"],
|
[class*="plot"],
|
||||||
[class*="chart"],
|
[class*="chart"],
|
||||||
svg {
|
svg {
|
||||||
@@ -430,7 +664,7 @@ svg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
HOME PAGE - "CREATE NEW NOTEBOOK" CARD
|
HOME PAGE
|
||||||
============================================ */
|
============================================ */
|
||||||
a[rel="noreferrer"][target="_blank"] {
|
a[rel="noreferrer"][target="_blank"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--tb-navy-light) !important;
|
||||||
@@ -444,18 +678,15 @@ a[rel="noreferrer"][target="_blank"]:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a[rel="noreferrer"][target="_blank"] h2 {
|
a[rel="noreferrer"][target="_blank"] h2 {
|
||||||
font-family: var(--marimo-heading-font) !important;
|
font-family: var(--heading-font) !important;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--tb-white) !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 2px !important;
|
letter-spacing: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
HOME PAGE - SECTION HEADERS
|
|
||||||
============================================ */
|
|
||||||
h2.text-xl {
|
h2.text-xl {
|
||||||
font-family: var(--marimo-heading-font) !important;
|
font-family: var(--heading-font) !important;
|
||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 2px !important;
|
letter-spacing: 2px !important;
|
||||||
@@ -464,9 +695,6 @@ h2.text-xl {
|
|||||||
border-bottom: 2px solid var(--tb-slate);
|
border-bottom: 2px solid var(--tb-slate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
HOME PAGE - FILE LISTS (notebook lists)
|
|
||||||
============================================ */
|
|
||||||
.divide-y.border.rounded {
|
.divide-y.border.rounded {
|
||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--tb-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
@@ -481,23 +709,20 @@ h2.text-xl {
|
|||||||
|
|
||||||
.divide-y.border > a:hover,
|
.divide-y.border > a:hover,
|
||||||
.divide-y.border > div > a:hover {
|
.divide-y.border > div > a:hover {
|
||||||
background: rgba(51, 102, 204, 0.2) !important;
|
background: rgba(68, 119, 221, 0.2) !important;
|
||||||
border-left: 3px solid var(--tb-blue) !important;
|
border-left: 3px solid var(--tb-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divide-y.border a .flex-1 span {
|
.divide-y.border a .flex-1 span {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
HOME PAGE - WORKSPACE FILE TREE
|
|
||||||
============================================ */
|
|
||||||
[class*="cursor-pointer"][class*="whitespace-nowrap"]:hover {
|
[class*="cursor-pointer"][class*="whitespace-nowrap"]:hover {
|
||||||
background: rgba(51, 102, 204, 0.2) !important;
|
background: rgba(68, 119, 221, 0.2) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="cursor-pointer"][class*="whitespace-nowrap"] span {
|
[class*="cursor-pointer"][class*="whitespace-nowrap"] span {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
font-size: 13px !important;
|
font-size: 13px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,12 +760,12 @@ input#search {
|
|||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--tb-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--tb-navy) !important;
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
input#search:focus {
|
input#search:focus {
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--tb-blue-light) !important;
|
||||||
box-shadow: 0 0 8px rgba(85, 136, 221, 0.3) !important;
|
box-shadow: 0 0 8px rgba(102, 153, 238, 0.3) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -551,3 +776,16 @@ button:active,
|
|||||||
transform: translate(1px, 1px) !important;
|
transform: translate(1px, 1px) !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
CATCH-ALL: ensure no text is dark/black
|
||||||
|
============================================ */
|
||||||
|
.dark .text-foreground,
|
||||||
|
.text-foreground {
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .text-muted-foreground,
|
||||||
|
.text-muted-foreground {
|
||||||
|
color: var(--tb-steel) !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,73 @@
|
|||||||
|
[completion]
|
||||||
|
activate_on_typing = true
|
||||||
|
signature_hint_on_typing = false
|
||||||
|
copilot = false
|
||||||
|
|
||||||
|
[server]
|
||||||
|
browser = "default"
|
||||||
|
follow_symlink = false
|
||||||
|
|
||||||
|
[package_management]
|
||||||
|
manager = "uv"
|
||||||
|
|
||||||
|
[runtime]
|
||||||
|
auto_instantiate = false
|
||||||
|
auto_reload = "off"
|
||||||
|
reactive_tests = true
|
||||||
|
on_cell_change = "autorun"
|
||||||
|
watcher_on_save = "lazy"
|
||||||
|
output_max_bytes = 8000000
|
||||||
|
std_stream_max_bytes = 1000000
|
||||||
|
default_sql_output = "auto"
|
||||||
|
default_csv_encoding = "utf-8"
|
||||||
|
|
||||||
|
[formatting]
|
||||||
|
line_length = 79
|
||||||
|
|
||||||
|
[save]
|
||||||
|
autosave = "after_delay"
|
||||||
|
autosave_delay = 1000
|
||||||
|
format_on_save = false
|
||||||
|
|
||||||
|
[ai.models]
|
||||||
|
displayed_models = []
|
||||||
|
custom_models = []
|
||||||
|
|
||||||
|
[ai.custom_providers]
|
||||||
|
|
||||||
|
[diagnostics]
|
||||||
|
sql_linter = true
|
||||||
|
|
||||||
|
[language_servers.pylsp]
|
||||||
|
enabled = false
|
||||||
|
enable_mypy = true
|
||||||
|
enable_ruff = true
|
||||||
|
enable_flake8 = false
|
||||||
|
enable_pydocstyle = false
|
||||||
|
enable_pylint = false
|
||||||
|
enable_pyflakes = false
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
default_width = "medium"
|
||||||
|
dataframes = "rich"
|
||||||
|
cell_output = "below"
|
||||||
theme = "dark"
|
theme = "dark"
|
||||||
|
default_table_page_size = 10
|
||||||
|
default_table_max_columns = 50
|
||||||
|
reference_highlighting = true
|
||||||
custom_css = ["/home/kert/.config/marimo/retro-arcade.css"]
|
custom_css = ["/home/kert/.config/marimo/retro-arcade.css"]
|
||||||
|
code_editor_font_size = 14
|
||||||
|
|
||||||
|
[keymap]
|
||||||
|
preset = "default"
|
||||||
|
|
||||||
|
[keymap.overrides]
|
||||||
|
|
||||||
|
[snippets]
|
||||||
|
custom_paths = []
|
||||||
|
include_default_snippets = true
|
||||||
|
|
||||||
|
[mcp]
|
||||||
|
presets = []
|
||||||
|
|
||||||
|
[mcp.mcpServers]
|
||||||
|
|||||||
@@ -0,0 +1,553 @@
|
|||||||
|
/* THROWBACK THEME - Tecmo Super Bowl */
|
||||||
|
/* Uses marimo's native CSS variable system for proper theming */
|
||||||
|
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
FONT CONFIGURATION
|
||||||
|
============================================ */
|
||||||
|
:root {
|
||||||
|
--marimo-monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
|
--marimo-text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
|
--marimo-heading-font: 'Press Start 2P', 'IBM Plex Mono', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
THROWBACK COLOR PALETTE
|
||||||
|
============================================ */
|
||||||
|
:root {
|
||||||
|
--tb-navy: #0a1628;
|
||||||
|
--tb-navy-light: #162040;
|
||||||
|
--tb-navy-mid: #1e2d50;
|
||||||
|
--tb-slate: #2a3f5f;
|
||||||
|
--tb-steel: #8a9fbb;
|
||||||
|
--tb-white: #f0f0f0;
|
||||||
|
|
||||||
|
--tb-blue: #4477dd;
|
||||||
|
--tb-blue-light: #6699ee;
|
||||||
|
--tb-blue-bright: #99bbff;
|
||||||
|
|
||||||
|
--tb-red: #cc2244;
|
||||||
|
--tb-red-light: #ee6688;
|
||||||
|
|
||||||
|
--tb-green: #44aa44;
|
||||||
|
--tb-green-light: #77dd77;
|
||||||
|
--tb-yellow: #eebb44;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
MARIMO THEME VARIABLES (Dark Mode)
|
||||||
|
============================================ */
|
||||||
|
:root {
|
||||||
|
/* Base colors */
|
||||||
|
--background: var(--tb-navy);
|
||||||
|
--foreground: var(--tb-white);
|
||||||
|
|
||||||
|
/* Muted/secondary text */
|
||||||
|
--muted: var(--tb-navy-light);
|
||||||
|
--muted-foreground: var(--tb-steel);
|
||||||
|
|
||||||
|
/* Popover/dropdown backgrounds */
|
||||||
|
--popover: var(--tb-navy-light);
|
||||||
|
--popover-foreground: var(--tb-white);
|
||||||
|
|
||||||
|
/* Cards (cells) */
|
||||||
|
--card: var(--tb-navy);
|
||||||
|
--card-foreground: var(--tb-white);
|
||||||
|
|
||||||
|
/* Borders and inputs */
|
||||||
|
--border: var(--tb-slate);
|
||||||
|
--input: var(--tb-navy-mid);
|
||||||
|
|
||||||
|
/* Primary action color */
|
||||||
|
--primary: var(--tb-blue);
|
||||||
|
--primary-foreground: var(--tb-white);
|
||||||
|
|
||||||
|
/* Secondary elements */
|
||||||
|
--secondary: var(--tb-slate);
|
||||||
|
--secondary-foreground: var(--tb-white);
|
||||||
|
|
||||||
|
/* Accent/highlight */
|
||||||
|
--accent: var(--tb-blue-light);
|
||||||
|
--accent-foreground: var(--tb-white);
|
||||||
|
|
||||||
|
/* Focus ring */
|
||||||
|
--ring: var(--tb-blue-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
SEMANTIC COLORS
|
||||||
|
============================================ */
|
||||||
|
:root {
|
||||||
|
/* Error states */
|
||||||
|
--destructive: var(--tb-red);
|
||||||
|
--destructive-foreground: var(--tb-white);
|
||||||
|
--error: var(--tb-red);
|
||||||
|
--error-foreground: var(--tb-white);
|
||||||
|
|
||||||
|
/* Success states */
|
||||||
|
--success: var(--tb-green);
|
||||||
|
--success-foreground: var(--tb-white);
|
||||||
|
|
||||||
|
/* Action buttons (run, etc) */
|
||||||
|
--action: var(--tb-green);
|
||||||
|
--action-hover: var(--tb-green-light);
|
||||||
|
--action-foreground: var(--tb-white);
|
||||||
|
|
||||||
|
/* Links */
|
||||||
|
--link: var(--tb-blue-bright);
|
||||||
|
--link-visited: var(--tb-blue-light);
|
||||||
|
|
||||||
|
/* Stale indicator */
|
||||||
|
--stale: rgba(221, 170, 51, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
SHADOWS
|
||||||
|
============================================ */
|
||||||
|
:root {
|
||||||
|
--base-shadow: rgba(0, 0, 0, 0.4);
|
||||||
|
--base-shadow-darker: rgba(0, 0, 0, 0.6);
|
||||||
|
--base-shadow-opacity: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
BACKGROUND
|
||||||
|
============================================ */
|
||||||
|
:root {
|
||||||
|
--background-image: none;
|
||||||
|
--background-repeat: no-repeat;
|
||||||
|
--background-attachment: fixed;
|
||||||
|
--background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--tb-navy) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
CODE EDITOR - CODEMIRROR STYLING
|
||||||
|
============================================ */
|
||||||
|
.cm-editor {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
background: var(--tb-navy) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-content {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-line {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-gutters {
|
||||||
|
background: var(--tb-navy-light) !important;
|
||||||
|
border-right: 2px solid var(--tb-slate) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-lineNumbers .cm-gutterElement {
|
||||||
|
color: var(--tb-steel) !important;
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Syntax highlighting */
|
||||||
|
.cm-keyword, .tok-keyword { color: var(--tb-blue-bright) !important; }
|
||||||
|
.cm-string, .tok-string { color: var(--tb-green-light) !important; }
|
||||||
|
.cm-number, .tok-number { color: var(--tb-yellow) !important; }
|
||||||
|
.cm-comment, .tok-comment { color: var(--tb-steel) !important; font-style: italic !important; }
|
||||||
|
.cm-function, .tok-function { color: var(--tb-white) !important; }
|
||||||
|
.cm-variableName, .tok-variableName { color: var(--tb-white) !important; }
|
||||||
|
.cm-operator, .tok-operator { color: var(--tb-blue-light) !important; }
|
||||||
|
.cm-propertyName, .tok-propertyName { color: var(--tb-blue-bright) !important; }
|
||||||
|
.tok-standard, .cm-builtin { color: var(--tb-red-light) !important; }
|
||||||
|
.tok-definition, .cm-def { color: var(--tb-blue-bright) !important; }
|
||||||
|
.tok-typeName { color: var(--tb-yellow) !important; }
|
||||||
|
.tok-bool { color: var(--tb-red-light) !important; }
|
||||||
|
|
||||||
|
/* Cursor */
|
||||||
|
.cm-cursor {
|
||||||
|
border-left: 2px solid var(--tb-white) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Selection */
|
||||||
|
.cm-selectionBackground,
|
||||||
|
::selection {
|
||||||
|
background: var(--tb-blue) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Active line */
|
||||||
|
.cm-activeLine {
|
||||||
|
background: rgba(51, 102, 204, 0.15) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
HEADINGS
|
||||||
|
============================================ */
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: var(--marimo-heading-font) !important;
|
||||||
|
letter-spacing: 0.5px !important;
|
||||||
|
line-height: 1.8 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 18px !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 14px !important;
|
||||||
|
color: var(--tb-blue-bright) !important;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-size: 12px !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
}
|
||||||
|
h4, h5, h6 {
|
||||||
|
font-size: 11px !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
TABLES (Scoreboard style)
|
||||||
|
============================================ */
|
||||||
|
table {
|
||||||
|
border-collapse: collapse !important;
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: var(--tb-blue) !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
font-family: var(--marimo-heading-font) !important;
|
||||||
|
font-size: 10px !important;
|
||||||
|
padding: 10px 12px !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
letter-spacing: 1px !important;
|
||||||
|
border: 1px solid var(--tb-blue-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
background: var(--tb-navy) !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
padding: 8px 12px !important;
|
||||||
|
border: 1px solid var(--tb-navy-light) !important;
|
||||||
|
font-size: 13px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even) td {
|
||||||
|
background: var(--tb-navy-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:hover td {
|
||||||
|
background: rgba(51, 102, 204, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
BUTTONS
|
||||||
|
============================================ */
|
||||||
|
button,
|
||||||
|
[role="button"],
|
||||||
|
.btn {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
transition: all 0.15s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary/action buttons should be visible */
|
||||||
|
button[data-variant="primary"],
|
||||||
|
button.primary,
|
||||||
|
[data-action="run"] {
|
||||||
|
background: var(--tb-green) !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
border: 2px solid var(--tb-green-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[data-variant="primary"]:hover,
|
||||||
|
button.primary:hover,
|
||||||
|
[data-action="run"]:hover {
|
||||||
|
background: var(--tb-green-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
INPUTS AND FORMS
|
||||||
|
============================================ */
|
||||||
|
input,
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
background: var(--tb-navy-mid) !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
border: 2px solid var(--tb-slate) !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
padding: 8px 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus,
|
||||||
|
textarea:focus,
|
||||||
|
select:focus {
|
||||||
|
border-color: var(--tb-blue-light) !important;
|
||||||
|
outline: none !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(85, 136, 221, 0.3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
CODE BLOCKS (in markdown)
|
||||||
|
============================================ */
|
||||||
|
pre, code {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background: var(--tb-navy-light) !important;
|
||||||
|
color: var(--tb-blue-bright) !important;
|
||||||
|
padding: 2px 6px !important;
|
||||||
|
border-radius: 3px !important;
|
||||||
|
font-size: 0.9em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background: var(--tb-navy) !important;
|
||||||
|
border: 2px solid var(--tb-slate) !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
padding: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre code {
|
||||||
|
background: transparent !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
LINKS
|
||||||
|
============================================ */
|
||||||
|
a {
|
||||||
|
color: var(--tb-blue-bright) !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
transition: color 0.15s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
text-decoration: underline !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: var(--tb-blue-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
SCROLLBARS
|
||||||
|
============================================ */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: var(--tb-navy-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--tb-slate);
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 2px solid var(--tb-navy-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--tb-steel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
MISC UI REFINEMENTS
|
||||||
|
============================================ */
|
||||||
|
|
||||||
|
/* Tooltips */
|
||||||
|
[role="tooltip"],
|
||||||
|
[data-state="open"][data-side] {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
background: var(--tb-navy-light) !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
border: 2px solid var(--tb-slate) !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown menus */
|
||||||
|
[role="menu"],
|
||||||
|
[role="listbox"] {
|
||||||
|
background: var(--tb-navy-light) !important;
|
||||||
|
border: 2px solid var(--tb-slate) !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[role="menuitem"]:hover,
|
||||||
|
[role="option"]:hover,
|
||||||
|
[role="menuitem"][data-highlighted],
|
||||||
|
[role="option"][data-highlighted] {
|
||||||
|
background: var(--tb-blue) !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Badges and pills */
|
||||||
|
[class*="badge"],
|
||||||
|
[class*="pill"],
|
||||||
|
[class*="tag"] {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
font-size: 11px !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Focus visible for accessibility */
|
||||||
|
:focus-visible {
|
||||||
|
outline: 2px solid var(--tb-blue-light) !important;
|
||||||
|
outline-offset: 2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
CELL OUTPUT AREA
|
||||||
|
============================================ */
|
||||||
|
[data-testid="outputs"],
|
||||||
|
.output-area {
|
||||||
|
background: rgba(22, 32, 64, 0.5) !important;
|
||||||
|
border-top: 2px solid var(--tb-slate) !important;
|
||||||
|
padding: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DataFrame outputs */
|
||||||
|
[class*="dataframe"] {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Plot/chart containers */
|
||||||
|
[class*="plot"],
|
||||||
|
[class*="chart"],
|
||||||
|
svg {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
HOME PAGE - "CREATE NEW NOTEBOOK" CARD
|
||||||
|
============================================ */
|
||||||
|
a[rel="noreferrer"][target="_blank"] {
|
||||||
|
background: var(--tb-navy-light) !important;
|
||||||
|
border: 3px solid var(--tb-slate) !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[rel="noreferrer"][target="_blank"]:hover {
|
||||||
|
border-color: var(--tb-blue) !important;
|
||||||
|
background: var(--tb-navy-mid) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[rel="noreferrer"][target="_blank"] h2 {
|
||||||
|
font-family: var(--marimo-heading-font) !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
letter-spacing: 2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
HOME PAGE - SECTION HEADERS
|
||||||
|
============================================ */
|
||||||
|
h2.text-xl {
|
||||||
|
font-family: var(--marimo-heading-font) !important;
|
||||||
|
font-size: 11px !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
letter-spacing: 2px !important;
|
||||||
|
color: var(--tb-white) !important;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
border-bottom: 2px solid var(--tb-slate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
HOME PAGE - FILE LISTS (notebook lists)
|
||||||
|
============================================ */
|
||||||
|
.divide-y.border.rounded {
|
||||||
|
border: 3px solid var(--tb-slate) !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
background: var(--tb-navy) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divide-y.border > a,
|
||||||
|
.divide-y.border > div > a {
|
||||||
|
border-color: var(--tb-navy-light) !important;
|
||||||
|
transition: all 0.1s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divide-y.border > a:hover,
|
||||||
|
.divide-y.border > div > a:hover {
|
||||||
|
background: rgba(51, 102, 204, 0.2) !important;
|
||||||
|
border-left: 3px solid var(--tb-blue) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divide-y.border a .flex-1 span {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
HOME PAGE - WORKSPACE FILE TREE
|
||||||
|
============================================ */
|
||||||
|
[class*="cursor-pointer"][class*="whitespace-nowrap"]:hover {
|
||||||
|
background: rgba(51, 102, 204, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="cursor-pointer"][class*="whitespace-nowrap"] span {
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
font-size: 13px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
PIXEL-PERFECT BORDERS
|
||||||
|
============================================ */
|
||||||
|
.rounded-lg,
|
||||||
|
.rounded-md {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounded-sm,
|
||||||
|
.rounded {
|
||||||
|
border-radius: 2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
TOP BAR / ACTION BUTTONS
|
||||||
|
============================================ */
|
||||||
|
.absolute.top-3.right-5 button {
|
||||||
|
border: 2px solid var(--tb-slate) !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
background: var(--tb-navy-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.absolute.top-3.right-5 button:hover {
|
||||||
|
background: var(--tb-blue) !important;
|
||||||
|
border-color: var(--tb-blue-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
SEARCH INPUT
|
||||||
|
============================================ */
|
||||||
|
input#search {
|
||||||
|
border: 3px solid var(--tb-slate) !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
background: var(--tb-navy) !important;
|
||||||
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input#search:focus {
|
||||||
|
border-color: var(--tb-blue-light) !important;
|
||||||
|
box-shadow: 0 0 8px rgba(85, 136, 221, 0.3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
BUTTON PRESS EFFECT
|
||||||
|
============================================ */
|
||||||
|
button:active,
|
||||||
|
[role="button"]:active {
|
||||||
|
transform: translate(1px, 1px) !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import marimo
|
import marimo
|
||||||
|
|
||||||
__generated_with = "0.19.8"
|
__generated_with = "0.20.2"
|
||||||
app = marimo.App(width="full")
|
app = marimo.App(width="full")
|
||||||
|
|
||||||
|
|
||||||
@@ -313,7 +313,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q, pl):
|
def _(alt, mo, pl, q):
|
||||||
risk = q("""
|
risk = q("""
|
||||||
SELECT r.person_id, r.payment_risk_score, r.v24_risk_score,
|
SELECT r.person_id, r.payment_risk_score, r.v24_risk_score,
|
||||||
r.normalized_risk_score, r.member_months,
|
r.normalized_risk_score, r.member_months,
|
||||||
@@ -469,7 +469,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q, pl):
|
def _(alt, mo, pl, q):
|
||||||
qm = q("""
|
qm = q("""
|
||||||
SELECT measure_id, measure_name, denominator_sum, numerator_sum,
|
SELECT measure_id, measure_name, denominator_sum, numerator_sum,
|
||||||
exclusion_sum, performance_rate
|
exclusion_sum, performance_rate
|
||||||
@@ -694,7 +694,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q, pl):
|
def _(alt, mo, pl, q):
|
||||||
brand_gen = q("""
|
brand_gen = q("""
|
||||||
SELECT brand_vs_generic, count(*) AS claims,
|
SELECT brand_vs_generic, count(*) AS claims,
|
||||||
round(sum(paid_amount), 2) AS total_paid
|
round(sum(paid_amount), 2) AS total_paid
|
||||||
|
|||||||
@@ -70,26 +70,28 @@ def _(ZOTERO_DB, mo, store):
|
|||||||
_item_count = store._con().execute("SELECT COUNT(*) FROM items").fetchone()[0]
|
_item_count = store._con().execute("SELECT COUNT(*) FROM items").fetchone()[0]
|
||||||
|
|
||||||
if _item_count > 0:
|
if _item_count > 0:
|
||||||
mo.md(f"""
|
_msg = f"""
|
||||||
## 2. Migration
|
## 2. Migration
|
||||||
|
|
||||||
Database already has **{_item_count}** items — migration not needed.
|
Database already has **{_item_count}** items — migration not needed.
|
||||||
|
|
||||||
To re-migrate, delete `data/bib.sqlite` and restart.
|
To re-migrate, delete `data/bib.sqlite` and restart.
|
||||||
""")
|
"""
|
||||||
elif not ZOTERO_DB.exists():
|
elif not ZOTERO_DB.exists():
|
||||||
mo.md("""
|
_msg = """
|
||||||
## 2. Migration
|
## 2. Migration
|
||||||
|
|
||||||
No Zotero database found at `/home/kert/zotero/zotero.sqlite`.
|
No Zotero database found at `/home/kert/zotero/zotero.sqlite`.
|
||||||
Start the Zotero container first, or add items manually below.
|
Start the Zotero container first, or add items manually below.
|
||||||
""")
|
"""
|
||||||
else:
|
else:
|
||||||
mo.md("""
|
_msg = """
|
||||||
## 2. Migration
|
## 2. Migration
|
||||||
|
|
||||||
Database is empty and Zotero source is available. Click **Migrate** to import.
|
Database is empty and Zotero source is available. Click **Migrate** to import.
|
||||||
""")
|
"""
|
||||||
|
|
||||||
|
mo.md(_msg)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -643,15 +645,17 @@ def _(
|
|||||||
_item = _fn(_url)
|
_item = _fn(_url)
|
||||||
_key = store.upsert(_item)
|
_key = store.upsert(_item)
|
||||||
_cite = format_citation(_item, style="apa")
|
_cite = format_citation(_item, style="apa")
|
||||||
mo.md(f"""
|
_msg = f"""
|
||||||
Saved as `{_key}`: **{_item.title}**
|
Saved as `{_key}`: **{_item.title}**
|
||||||
|
|
||||||
Tags: {', '.join(f'`{t}`' for t in _item.tags)}
|
Tags: {', '.join(f'`{t}`' for t in _item.tags)}
|
||||||
|
|
||||||
> {_cite}
|
> {_cite}
|
||||||
""")
|
"""
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
mo.md(f"Translation failed: `{e}`")
|
_msg = f"Translation failed: `{e}`"
|
||||||
|
|
||||||
|
mo.md(_msg)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -694,19 +698,23 @@ def _(mo):
|
|||||||
def _(mo, store):
|
def _(mo, store):
|
||||||
try:
|
try:
|
||||||
library_df = store.to_dataframe()
|
library_df = store.to_dataframe()
|
||||||
mo.md(f"Exported **{library_df.height}** items to `library_df`")
|
_msg = f"Exported **{library_df.height}** items to `library_df`"
|
||||||
except Exception:
|
except Exception:
|
||||||
library_df = None
|
library_df = None
|
||||||
mo.md("No items to export.")
|
_msg = "No items to export."
|
||||||
|
|
||||||
|
mo.md(_msg)
|
||||||
return (library_df,)
|
return (library_df,)
|
||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(library_df, mo):
|
def _(library_df, mo):
|
||||||
if library_df is not None and library_df.height > 0:
|
_out = (
|
||||||
mo.ui.dataframe(library_df)
|
mo.ui.dataframe(library_df)
|
||||||
else:
|
if library_df is not None and library_df.height > 0
|
||||||
mo.md("DataFrame is empty. Add some items first.")
|
else mo.md("DataFrame is empty. Add some items first.")
|
||||||
|
)
|
||||||
|
_out
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
256
notebooks/pfs_calcs.py
Normal file
256
notebooks/pfs_calcs.py
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
import marimo
|
||||||
|
|
||||||
|
__generated_with = "0.20.2"
|
||||||
|
app = marimo.App(width="medium")
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _():
|
||||||
|
import marimo as mo
|
||||||
|
|
||||||
|
return (mo,)
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(mo):
|
||||||
|
mo.md("""
|
||||||
|
# PFS Payment Calculator
|
||||||
|
|
||||||
|
Three ways to get a Medicare Physician Fee Schedule payment rate
|
||||||
|
for a given **year**, **locality**, and **HCPCS code**.
|
||||||
|
""")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _():
|
||||||
|
import duckdb
|
||||||
|
import polars as pl
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
_candidates = [
|
||||||
|
Path("/home/kert/notebooks/aco.duckdb"), # container
|
||||||
|
Path(__file__).parent / "aco.duckdb", # local
|
||||||
|
]
|
||||||
|
DB_PATH = str(next(p for p in _candidates if p.exists()))
|
||||||
|
con = duckdb.connect(DB_PATH, read_only=True)
|
||||||
|
|
||||||
|
def q(sql):
|
||||||
|
return con.execute(sql).pl()
|
||||||
|
|
||||||
|
return con, pl, q
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(con, mo):
|
||||||
|
_years = sorted(
|
||||||
|
r[0]
|
||||||
|
for r in con.execute(
|
||||||
|
"SELECT DISTINCT year FROM pfs.rvu ORDER BY year"
|
||||||
|
).fetchall()
|
||||||
|
)
|
||||||
|
_localities = con.execute(
|
||||||
|
"""
|
||||||
|
SELECT DISTINCT locality, locality_name
|
||||||
|
FROM pfs.gpci
|
||||||
|
ORDER BY locality
|
||||||
|
"""
|
||||||
|
).fetchall()
|
||||||
|
|
||||||
|
year_picker = mo.ui.dropdown(
|
||||||
|
options={str(y): y for y in _years},
|
||||||
|
value=str(_years[-1]),
|
||||||
|
label="Year",
|
||||||
|
)
|
||||||
|
locality_picker = mo.ui.dropdown(
|
||||||
|
options={f"{loc} - {name}": loc for loc, name in _localities},
|
||||||
|
value=f"{_localities[0][0]} - {_localities[0][1]}",
|
||||||
|
label="Locality",
|
||||||
|
)
|
||||||
|
hcpcs_input = mo.ui.text(value="99213", label="HCPCS Code")
|
||||||
|
|
||||||
|
mo.hstack([year_picker, locality_picker, hcpcs_input], justify="start", gap=1)
|
||||||
|
return hcpcs_input, locality_picker, year_picker
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(hcpcs_input, locality_picker, year_picker):
|
||||||
|
_year = year_picker.value
|
||||||
|
_locality = locality_picker.value
|
||||||
|
_hcpcs = hcpcs_input.value.strip()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(mo):
|
||||||
|
mo.md("""
|
||||||
|
## 1 - Carrier Locality Lookup
|
||||||
|
|
||||||
|
Pre-computed by CMS. The `pfs.carrier_locality` table has the
|
||||||
|
published fee for every year/locality/code combination.
|
||||||
|
This is the ground truth — it accounts for rounding, GPCI floors,
|
||||||
|
and carrier-priced edge cases.
|
||||||
|
""")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell
|
||||||
|
def _(hcpcs_input, locality_picker, q, year_picker):
|
||||||
|
carrier_result = q(f"""
|
||||||
|
SELECT year, locality, hcpcs, mod,
|
||||||
|
non_fac_fee, fac_fee,
|
||||||
|
non_fac_limiting_charge, fac_limiting_charge
|
||||||
|
FROM pfs.carrier_locality
|
||||||
|
WHERE year = {year_picker.value}
|
||||||
|
AND locality = '{locality_picker.value}'
|
||||||
|
AND hcpcs = '{hcpcs_input.value.strip()}'
|
||||||
|
ORDER BY mod
|
||||||
|
""")
|
||||||
|
carrier_result
|
||||||
|
return (carrier_result,)
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(mo):
|
||||||
|
mo.md("""
|
||||||
|
## 2 - Calculated from RVUs + GPCIs
|
||||||
|
|
||||||
|
Uses `pfs.calcs.payment` which implements:
|
||||||
|
|
||||||
|
```
|
||||||
|
Payment = (Work_RVU x Work_GPCI
|
||||||
|
+ PE_RVU x PE_GPCI
|
||||||
|
+ MP_RVU x MP_GPCI) x CF
|
||||||
|
```
|
||||||
|
""")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell
|
||||||
|
def _(hcpcs_input, locality_picker, pl, q, year_picker):
|
||||||
|
from pfs.calcs import payment
|
||||||
|
from pfs.rules import RULES
|
||||||
|
|
||||||
|
_year = int(year_picker.value)
|
||||||
|
_locality = locality_picker.value
|
||||||
|
_hcpcs = hcpcs_input.value.strip()
|
||||||
|
_cf = RULES[_year].conversion_factor
|
||||||
|
|
||||||
|
rvu_df = q(f"""
|
||||||
|
SELECT *, {_cf} as conv_factor, '{_locality}' as locality
|
||||||
|
FROM pfs.rvu
|
||||||
|
WHERE year = {_year} AND hcpcs = '{_hcpcs}'
|
||||||
|
""")
|
||||||
|
|
||||||
|
gpci_df = q(f"""
|
||||||
|
SELECT * FROM pfs.gpci
|
||||||
|
WHERE year = {_year} AND locality = '{_locality}'
|
||||||
|
""")
|
||||||
|
|
||||||
|
calc_nf = payment(rvu_df, gpci_df, facility=False).select(
|
||||||
|
"hcpcs", "mod", "work_rvu", "non_fac_pe_rvu", "mp_rvu",
|
||||||
|
"work_gpci", "pe_gpci", "mp_gpci", "conv_factor",
|
||||||
|
pl.col("payment_amount").round(2).alias("non_fac_payment"),
|
||||||
|
)
|
||||||
|
|
||||||
|
calc_f = payment(rvu_df, gpci_df, facility=True).select(
|
||||||
|
"hcpcs", "mod",
|
||||||
|
pl.col("payment_amount").round(2).alias("fac_payment"),
|
||||||
|
)
|
||||||
|
|
||||||
|
calc_result = calc_nf.join(calc_f, on=["hcpcs", "mod"], how="left")
|
||||||
|
calc_result
|
||||||
|
return (calc_result,)
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(mo):
|
||||||
|
mo.md("""
|
||||||
|
## 3 - Pure SQL
|
||||||
|
|
||||||
|
Same formula, single query. Good for ad-hoc analysis.
|
||||||
|
""")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell
|
||||||
|
def _(hcpcs_input, locality_picker, q, year_picker):
|
||||||
|
from pfs.rules import RULES as _RULES
|
||||||
|
|
||||||
|
_year = int(year_picker.value)
|
||||||
|
_cf = _RULES[_year].conversion_factor
|
||||||
|
|
||||||
|
sql_result = q(f"""
|
||||||
|
SELECT
|
||||||
|
r.hcpcs,
|
||||||
|
r.mod,
|
||||||
|
r.year,
|
||||||
|
g.locality,
|
||||||
|
g.locality_name,
|
||||||
|
r.work_rvu,
|
||||||
|
r.non_fac_pe_rvu,
|
||||||
|
r.fac_pe_rvu,
|
||||||
|
r.mp_rvu,
|
||||||
|
g.work_gpci,
|
||||||
|
g.pe_gpci,
|
||||||
|
g.mp_gpci,
|
||||||
|
round(
|
||||||
|
(r.work_rvu * g.work_gpci
|
||||||
|
+ r.non_fac_pe_rvu * g.pe_gpci
|
||||||
|
+ r.mp_rvu * g.mp_gpci)
|
||||||
|
* {_cf}, 2
|
||||||
|
) as non_fac_payment,
|
||||||
|
round(
|
||||||
|
(r.work_rvu * g.work_gpci
|
||||||
|
+ r.fac_pe_rvu * g.pe_gpci
|
||||||
|
+ r.mp_rvu * g.mp_gpci)
|
||||||
|
* {_cf}, 2
|
||||||
|
) as fac_payment
|
||||||
|
FROM pfs.rvu r
|
||||||
|
JOIN pfs.gpci g ON r.year = g.year
|
||||||
|
WHERE r.year = {_year}
|
||||||
|
AND r.hcpcs = '{hcpcs_input.value.strip()}'
|
||||||
|
AND g.locality = '{locality_picker.value}'
|
||||||
|
ORDER BY r.mod
|
||||||
|
""")
|
||||||
|
sql_result
|
||||||
|
return (sql_result,)
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(carrier_result, mo, pl, calc_result):
|
||||||
|
_has_carrier = carrier_result.height > 0
|
||||||
|
_has_calc = calc_result.height > 0
|
||||||
|
|
||||||
|
_comparison = ""
|
||||||
|
if _has_carrier and _has_calc:
|
||||||
|
_carrier_base = carrier_result.filter(
|
||||||
|
(pl.col("mod").is_null()) | (pl.col("mod") == "")
|
||||||
|
)
|
||||||
|
_calc_base = calc_result.filter(
|
||||||
|
(pl.col("mod").is_null()) | (pl.col("mod") == "")
|
||||||
|
)
|
||||||
|
_carrier_nf = _carrier_base.head(1).select("non_fac_fee").item()
|
||||||
|
_calc_nf = _calc_base.head(1).select("non_fac_payment").item()
|
||||||
|
_diff = round(abs(_carrier_nf - _calc_nf), 2)
|
||||||
|
_comparison = f"""
|
||||||
|
## Comparison
|
||||||
|
|
||||||
|
| Source | Non-Facility Fee |
|
||||||
|
|--------|-----------------|
|
||||||
|
| CMS Carrier File | **${_carrier_nf:.2f}** |
|
||||||
|
| Calculated (RVU x GPCI x CF) | **${_calc_nf:.2f}** |
|
||||||
|
| Difference | **${_diff:.2f}** |
|
||||||
|
|
||||||
|
Small differences are normal — CMS rounds intermediate values
|
||||||
|
and may apply adjustments not captured in the base formula.
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
_comparison = "*Select a valid year/locality/code combination to see comparison.*"
|
||||||
|
|
||||||
|
mo.md(_comparison)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run()
|
||||||
@@ -63,7 +63,7 @@ def _(mo):
|
|||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(mo):
|
def _(mo):
|
||||||
mo.md("""
|
mo.md(r"""
|
||||||
| Syntax | Description | Example |
|
| Syntax | Description | Example |
|
||||||
|-------------|-------------|-------------------|
|
|-------------|-------------|-------------------|
|
||||||
| **Header** | Row Title | Content Here |
|
| **Header** | Row Title | Content Here |
|
||||||
@@ -74,7 +74,7 @@ def _(mo):
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
def greet(name: str) -> str:
|
def greet(name: str) -> str:
|
||||||
"\""Return a greeting message."\""
|
"\"Return a greeting message."\"
|
||||||
return f"Hello, {name}!"
|
return f"Hello, {name}!"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -243,9 +243,11 @@ def _(mo, run_transpile):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
_sql, _n, _e = run_transpile(_cclf.pipeline, "cclf")
|
_sql, _n, _e = run_transpile(_cclf.pipeline, "cclf")
|
||||||
mo.md(f"**{_n} steps, {_e} errors**\n\n```sql\n{_sql}\n```")
|
_msg = f"**{_n} steps, {_e} errors**\n\n```sql\n{_sql}\n```"
|
||||||
except Exception as _ex:
|
except Exception as _ex:
|
||||||
mo.md(f"**CCLF pipeline requires CCLF data in DuckDB.**\n\nError: `{_ex}`")
|
_msg = f"**CCLF pipeline requires CCLF data in DuckDB.**\n\nError: `{_ex}`"
|
||||||
|
|
||||||
|
mo.md(_msg)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user