From f67b138d956e03511453c1a8b2d96a3699301139 Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sun, 17 Aug 2025 17:25:04 +0100 Subject: [PATCH] refactor: replace Wizard with CoopBuilder in navigation, enhance budget store structure, and streamline template components for improved user experience --- app.vue | 90 +- assets/css/main.css | 362 ++++--- components/BudgetCategorySelector.vue | 67 ++ components/CoopBuilderSubnav.vue | 56 ++ components/ExportOptions.vue | 10 +- components/WizardRevenueStep.vue | 247 ++--- components/WizardReviewStep.vue | 46 +- components/WizardSubnav.vue | 57 +- composables/useFixtures.ts | 10 +- composables/useOfferSuggestor.ts | 256 +++++ data/offerTemplates.ts | 178 ++++ data/skillsProblems.ts | 157 ++++ pages/budget.vue | 652 ++++++------- pages/coach/skills-to-offers.vue | 684 ++++++++++++++ pages/coop-builder.vue | 468 ++++++++++ pages/coop-planner.vue | 6 +- pages/scenarios.vue | 4 +- .../conflict-resolution-framework.vue | 565 ++++++----- pages/templates/decision-framework.vue | 883 ++++++++++-------- pages/templates/index.vue | 92 +- pages/templates/membership-agreement.vue | 332 +++---- pages/templates/tech-charter.vue | 434 ++++----- pages/wizard.vue | 372 -------- pages/wizards.vue | 100 +- sample/skillsToOffersSamples.ts | 40 + stores/budget.ts | 542 ++++++++++- stores/{wizard.ts => coop-builder.ts} | 4 +- stores/plan.ts | 22 + stores/streams.ts | 27 + tailwind.config.ts | 15 +- tests/coach-integration.spec.ts | 431 +++++++++ types/coaching.ts | 29 + utils/offerToStream.ts | 183 ++++ 33 files changed, 4970 insertions(+), 2451 deletions(-) create mode 100644 components/BudgetCategorySelector.vue create mode 100644 components/CoopBuilderSubnav.vue create mode 100644 composables/useOfferSuggestor.ts create mode 100644 data/offerTemplates.ts create mode 100644 data/skillsProblems.ts create mode 100644 pages/coach/skills-to-offers.vue create mode 100644 pages/coop-builder.vue delete mode 100644 pages/wizard.vue create mode 100644 sample/skillsToOffersSamples.ts rename stores/{wizard.ts => coop-builder.ts} (86%) create mode 100644 stores/plan.ts create mode 100644 tests/coach-integration.spec.ts create mode 100644 types/coaching.ts create mode 100644 utils/offerToStream.ts diff --git a/app.vue b/app.vue index e4394a3..6aade1c 100644 --- a/app.vue +++ b/app.vue @@ -9,12 +9,11 @@
- + class="flex items-center gap-2 hover:opacity-80 transition-opacity" + >

+ class="text-black dark:text-white text-center text-2xl font-mono uppercase font-bold" + > Urgent Tools

@@ -25,49 +24,41 @@ - +
+ + +
@@ -82,17 +73,20 @@ diff --git a/assets/css/main.css b/assets/css/main.css index 0575114..546c443 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1,29 +1,25 @@ - +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=Ubuntu:wght@300;400;500;700&family=Ubuntu+Mono:wght@400;700&display=swap"); @import "tailwindcss"; @import "@nuxt/ui"; -/* Ubuntu font import */ -@import url("https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&family=Ubuntu+Mono:wght@400;700&display=swap"); - -[data-theme="dark"] { - html { @apply bg-white text-neutral-900; } - html.dark { @apply bg-neutral-950 text-neutral-100; } +@theme { + --font-body: "Ubuntu", "Inter", sans-serif; + --font-mono: "Ubuntu Mono", monospace; } -/* Disable all animations, transitions, and smooth scrolling app-wide */ html, body { - scroll-behavior: auto !important; + @apply font-body bg-white text-neutral-900 dark:bg-neutral-950 dark:text-neutral-100; } -*, -*::before, -*::after { - animation: none !important; - transition: none !important; +/* All headers use Inter font */ +h1, h2, h3, h4, h5, h6 { + font-family: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; } + + /* ========================= TEMPLATE DOCUMENT LAYOUT ========================= */ @@ -47,7 +43,7 @@ body { ========================= */ .section-card { - @apply border border-neutral-200 dark:border-neutral-800 rounded-lg p-5 mb-8; + @apply border border-neutral-200 dark:border-neutral-800 rounded-lg p-5 mb-8 relative; } .section-card::before { @@ -57,27 +53,24 @@ body { left: 4px; right: -4px; bottom: -4px; - background: black; + @apply bg-black dark:bg-white; background-image: radial-gradient(white 1px, transparent 1px); background-size: 2px 2px; z-index: -1; } +html.dark .section-card::before { + background-image: radial-gradient(black 1px, transparent 1px); +} + .section-title { - font-size: 1.75rem; - font-weight: 800; - color: inherit; - margin: 0 0 1rem 0; + @apply text-3xl font-extrabold text-neutral-900 dark:text-neutral-100 mb-4; + font-family: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; } .subsection-title { - font-size: 1.25rem; - font-weight: 600; - color: #374151; - margin: 0 0 0.75rem 0; - text-decoration: none; - border-bottom: 1px solid #e5e7eb; - padding-bottom: 0.25rem; + @apply text-xl font-semibold text-neutral-700 dark:text-neutral-300 mb-3 no-underline border-b border-neutral-200 dark:border-neutral-700 pb-1; + font-family: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; } /* ========================= @@ -121,55 +114,36 @@ body { } .form-group-large .large-field { - @apply block w-full mt-2 text-lg rounded-md border-none transition-colors duration-150 ease-in-out; + @apply block w-full mt-2 text-lg rounded-md border-none transition-colors duration-150 ease-in-out bg-neutral-50 dark:bg-neutral-800 text-neutral-900 dark:text-neutral-100; } .form-group-large .large-field:focus { - background: #f3f4f6; + @apply bg-neutral-100 dark:bg-neutral-700 outline-2 outline-blue-500 -outline-offset-2; box-shadow: none; - outline: 2px solid #3b82f6; - outline-offset: -2px; } .inline-field { - display: inline-block; - margin: 0 0.25rem; - min-width: 120px; - border: none; - background: #f9fafb; - padding: 0.25rem 0.5rem; - border-radius: 0.25rem; + @apply inline-block mx-1 min-w-[120px] border-none bg-neutral-50 dark:bg-neutral-800 text-neutral-900 dark:text-neutral-100 px-2 py-1 rounded; } .inline-field:focus { - background: #f3f4f6; - outline: 1px solid #3b82f6; - outline-offset: -1px; + @apply bg-neutral-100 dark:bg-neutral-700 outline-1 outline-blue-500 -outline-offset-1; } .number-field { - min-width: 80px !important; - text-align: center; + @apply min-w-[80px] text-center; } .wide-field { - min-width: 250px !important; + @apply min-w-[250px]; } .form-group-block .block-field { - display: block; - width: 100%; - margin-top: 0.25rem; - border: none; - background: #f9fafb; - padding: 0.5rem; - border-radius: 0.25rem; + @apply block w-full mt-1 border-none bg-neutral-50 dark:bg-neutral-800 text-neutral-900 dark:text-neutral-100 p-2 rounded; } .form-group-block .block-field:focus { - background: #f3f4f6; - outline: 1px solid #3b82f6; - outline-offset: -1px; + @apply bg-neutral-100 dark:bg-neutral-700 outline-1 outline-blue-500 -outline-offset-1; } /* ========================= @@ -263,16 +237,75 @@ body { ========================= */ .dither-shadow { - background: black; + @apply bg-black dark:bg-white; background-image: radial-gradient(white 1px, transparent 1px); background-size: 2px 2px; } html.dark .dither-shadow { - background: white; background-image: radial-gradient(black 1px, transparent 1px); } +/* ========================= + SELECTED ITEM PATTERN + ========================= */ + +/* Pattern for selected items with dithered shadow and patterned background */ +.item-selected { + @apply relative bg-white dark:bg-neutral-950; +} + +.item-selected::after { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: repeating-linear-gradient( + 45deg, + transparent 0px, + transparent 1px, + black 1px, + black 2px + ); + opacity: 0.1; + pointer-events: none; + z-index: 0; +} + +html.dark .item-selected::after { + background-image: repeating-linear-gradient( + 45deg, + transparent 0px, + transparent 1px, + white 1px, + white 2px + ); +} + +.item-selected > * { + position: relative; + z-index: 1; +} + +/* Text background for better readability on selected items */ +.item-label-bg { + @apply bg-white/85 dark:bg-neutral-950/85 rounded; +} + +.item-label-bg.selected { + @apply bg-white/95 dark:bg-neutral-950/95; +} + +.item-text-bg { + @apply bg-white/90 dark:bg-neutral-950/90; +} + +.item-text-bg.selected { + @apply bg-white/95 dark:bg-neutral-950/95; +} + /* ========================= BUTTON STYLING ========================= */ @@ -330,123 +363,71 @@ html.dark .export-btn.primary:hover { @apply bg-white text-black; } -/* General buttons with bitmap styling */ -button:not(.export-btn) { - background: white !important; - border: 1px solid black !important; - color: black !important; - font-family: "Ubuntu Mono", monospace !important; - text-transform: uppercase !important; - font-weight: bold !important; - letter-spacing: 0.5px !important; - cursor: pointer !important; +/* Bitmap button base styling - more targeted approach */ +.bitmap-style { + @apply bg-white dark:bg-neutral-950 border border-black dark:border-white text-black dark:text-white font-mono uppercase font-bold tracking-wide cursor-pointer; } -button:not(.export-btn):hover { - background: black !important; - color: white !important; - transform: translateY(-1px) translateX(-1px) !important; +.bitmap-style:hover { + @apply bg-black dark:bg-white text-white dark:text-black; + transform: translateY(-1px) translateX(-1px); } -/* Dark mode buttons */ -html.dark button:not(.export-btn) { - background: #0a0a0a !important; - border: 1px solid white !important; - color: white !important; +/* Bitmap button styling for template cards */ +.bitmap-button { + @apply font-mono uppercase font-bold tracking-wider relative; } -html.dark button:not(.export-btn):hover { - background: white !important; - color: black !important; +.bitmap-button:hover { + transform: translateY(-1px) translateX(-1px); + transition: transform 0.1s ease; +} + +.bitmap-button:hover::after { + content: ""; + position: absolute; + top: 1px; + left: 1px; + right: -1px; + bottom: -1px; + @apply border border-black dark:border-white bg-white dark:bg-neutral-950; + z-index: -1; +} + +/* Constraint button selected styling */ +.constraint-selected { + @apply bg-black dark:bg-white text-white dark:text-black; +} + +.constraint-selected:hover { + @apply bg-black dark:bg-white text-white dark:text-black; } /* ========================= BITMAP AESTHETIC OVERRIDES ========================= */ -/* Remove all rounded corners */ -* { - border-radius: 0 !important; - font-family: "Ubuntu", monospace !important; + +/* Bitmap form field styling - applied selectively */ +.bitmap-input { + @apply border border-black dark:border-white bg-white dark:bg-neutral-950 text-black dark:text-white font-mono; } -/* Form fields with bitmap styling */ -input, -textarea, -select { - border: 1px solid black !important; - background: white !important; - color: black !important; - font-family: "Ubuntu Mono", monospace !important; +.bitmap-input:focus { + @apply outline-2 outline-black dark:outline-white -outline-offset-2 bg-white dark:bg-neutral-950; } -input:focus, -textarea:focus, -select:focus { - outline: 2px solid black !important; - outline-offset: -2px !important; - background: white !important; +/* Checkbox and radio button styling for bitmap theme */ +.bitmap-checkbox { + @apply border-2 border-black dark:border-white bg-white dark:bg-neutral-950; } -/* Dark mode form fields */ -html.dark input, -html.dark textarea, -html.dark select { - border: 1px solid white !important; - background: #0a0a0a !important; - color: white !important; +.bitmap-checkbox:checked { + @apply bg-black dark:bg-white text-white dark:text-black; } -html.dark input:focus, -html.dark textarea:focus, -html.dark select:focus { - outline: 2px solid white !important; - background: #0a0a0a !important; -} -/* Checkbox and radio button styling */ -input[type="checkbox"], -input[type="radio"] { - border: 2px solid black !important; - background: white !important; -} -input[type="checkbox"]:checked, -input[type="radio"]:checked { - background: black !important; - color: white !important; -} - -html.dark input[type="checkbox"], -html.dark input[type="radio"] { - border: 2px solid white !important; - background: #0a0a0a !important; -} - -html.dark input[type="checkbox"]:checked, -html.dark input[type="radio"]:checked { - background: white !important; - color: black !important; -} - -/* Document titles */ -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Ubuntu", monospace !important; - color: inherit !important; -} - -/* All text */ -p, -span, -div { - color: inherit !important; - font-family: "Ubuntu", monospace !important; -} /* ========================= HIDE ELEMENTS FROM PRINT @@ -523,6 +504,85 @@ div { } } +/* ========================= + VALIDATION STYLES + ========================= */ + +.validation-error { + @apply text-red-500 dark:text-red-400 text-sm font-medium mt-2 flex items-center gap-1; +} + +/* ========================= + TEMPLATE CARD STYLES + ========================= */ + +.template-card { + @apply relative font-mono; +} + +.help-section { + @apply relative; +} + +.coming-soon { + @apply opacity-70; +} + +.dither-tag { + @apply relative bg-white dark:bg-neutral-950; +} + +.dither-tag::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: repeating-linear-gradient( + 45deg, + transparent 0px, + transparent 1px, + black 1px, + black 2px + ); + opacity: 0.1; + pointer-events: none; +} + +html.dark .dither-tag::before { + background-image: repeating-linear-gradient( + 45deg, + transparent 0px, + transparent 1px, + white 1px, + white 2px + ); +} + +.disabled-button { + @apply opacity-60 cursor-not-allowed; +} + +/* ========================= + ANIMATIONS + ========================= */ + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.animate-fadeIn { + animation: fadeIn 0.5s ease-out; +} + /* ========================= MOBILE RESPONSIVENESS ========================= */ diff --git a/components/BudgetCategorySelector.vue b/components/BudgetCategorySelector.vue new file mode 100644 index 0000000..e1a68be --- /dev/null +++ b/components/BudgetCategorySelector.vue @@ -0,0 +1,67 @@ + + + \ No newline at end of file diff --git a/components/CoopBuilderSubnav.vue b/components/CoopBuilderSubnav.vue new file mode 100644 index 0000000..c6c0d69 --- /dev/null +++ b/components/CoopBuilderSubnav.vue @@ -0,0 +1,56 @@ + + + + + \ No newline at end of file diff --git a/components/ExportOptions.vue b/components/ExportOptions.vue index b4860e9..abd25a6 100644 --- a/components/ExportOptions.vue +++ b/components/ExportOptions.vue @@ -2,9 +2,8 @@
-

Export Options:

- + - +
@@ -582,6 +581,7 @@ const downloadFile = (content: string, filename: string, type: string) => { } .export-buttons { + @apply font-mono; display: flex; flex-wrap: wrap; gap: 0.75rem; diff --git a/components/WizardRevenueStep.vue b/components/WizardRevenueStep.vue index 8dd4f2c..d645993 100644 --- a/components/WizardRevenueStep.vue +++ b/components/WizardRevenueStep.vue @@ -1,132 +1,137 @@ diff --git a/components/WizardReviewStep.vue b/components/WizardReviewStep.vue index 2f8014d..758657e 100644 --- a/components/WizardReviewStep.vue +++ b/components/WizardReviewStep.vue @@ -1,20 +1,12 @@