style: enhance CSS for improved layout and responsiveness, integrate Ubuntu font, and streamline export options across templates

This commit is contained in:
Jennie Robinson Faber 2025-08-17 08:17:28 +01:00
parent 3b33ff3819
commit eede87a273
6 changed files with 1130 additions and 1745 deletions

View file

@ -4,34 +4,39 @@
<WizardSubnav />
<!-- Export Options at Top -->
<div class="flex justify-center py-6">
<ExportOptions
:export-data="exportData"
filename="decision-framework"
title="Decision Framework Helper" />
</div>
<ExportOptions
:export-data="exportData"
filename="decision-framework"
title="Decision Framework Helper"
/>
<div
class="template-wrapper bg-white dark:bg-neutral-950 text-neutral-900 dark:text-neutral-100"
style="font-family: 'Ubuntu', monospace">
style="font-family: 'Ubuntu', monospace"
>
<!-- Spacer for consistency -->
<div class="py-4"></div>
<div class="max-w-4xl mx-auto relative px-4">
<div
class="bg-white dark:bg-neutral-950 border-2 border-neutral-900 dark:border-neutral-100 decision-framework-container">
class="bg-white dark:bg-neutral-950 border-2 border-neutral-900 dark:border-neutral-100 decision-framework-container"
>
<!-- Header -->
<div
class="bg-black dark:bg-white text-white dark:text-black px-8 py-12 text-center header-section">
class="bg-black dark:bg-white text-white dark:text-black px-8 py-12 text-center header-section"
>
<!-- Dithered shadow background -->
<div
class="absolute top-4 left-4 right-0 bottom-0 dither-shadow-header"></div>
class="absolute top-4 left-4 right-0 bottom-0 dither-shadow-header"
></div>
<div
class="relative bg-black dark:bg-white text-white dark:text-black px-4 py-4 border-2 border-neutral-100 dark:border-neutral-900">
class="relative bg-black dark:bg-white text-white dark:text-black px-4 py-4 border-2 border-neutral-100 dark:border-neutral-900"
>
<h1
class="text-3xl font-bold mb-2 uppercase"
style="font-family: 'Ubuntu', monospace">
style="font-family: 'Ubuntu', monospace"
>
Decision Framework Helper
</h1>
<p class="text-lg" style="font-family: 'Ubuntu', monospace">
@ -41,24 +46,22 @@
<!-- Progress Bar -->
<div v-if="!showResult" class="mt-8">
<div class="flex justify-between items-center mb-2">
<span
class="text-sm"
style="font-family: 'Ubuntu Mono', monospace"
<span class="text-sm" style="font-family: 'Ubuntu Mono', monospace"
>Step {{ currentStep }} of {{ totalSteps }}</span
>
<span
class="text-sm"
style="font-family: 'Ubuntu Mono', monospace"
<span class="text-sm" style="font-family: 'Ubuntu Mono', monospace"
>{{ Math.round((currentStep / totalSteps) * 100) }}%</span
>
</div>
<div
class="w-full bg-white dark:bg-black h-2 border-2 border-neutral-100 dark:border-neutral-900">
class="w-full bg-white dark:bg-black h-2 border-2 border-neutral-100 dark:border-neutral-900"
>
<div
class="bg-black dark:bg-white h-full transition-all duration-300 progress-dither"
:style="{
width: (currentStep / totalSteps) * 100 + '%',
}"></div>
}"
></div>
</div>
</div>
</div>
@ -72,14 +75,15 @@
<div v-if="currentStep === 1">
<div
class="font-semibold text-black dark:text-white mb-6 text-2xl"
style="font-family: 'Ubuntu', monospace">
style="font-family: 'Ubuntu', monospace"
>
How urgent is this decision?
</div>
<div
class="bg-white dark:bg-neutral-950 p-8 border-2 border-neutral-900 dark:border-neutral-100 relative">
class="bg-white dark:bg-neutral-950 p-8 border-2 border-neutral-900 dark:border-neutral-100 relative"
>
<!-- Dithered shadow background -->
<div
class="absolute top-2 left-2 right-0 bottom-0 dither-shadow"></div>
<div class="absolute top-2 left-2 right-0 bottom-0 dither-shadow"></div>
<div class="relative">
<div class="flex justify-between mb-6 text-sm">
@ -101,10 +105,12 @@
min="1"
max="5"
step="1"
class="w-full h-2 bg-white dark:bg-black appearance-none cursor-pointer slider" />
class="w-full h-2 bg-white dark:bg-black appearance-none cursor-pointer slider"
/>
<div
class="flex justify-between mt-4 text-sm text-black dark:text-white"
style="font-family: 'Ubuntu Mono', monospace">
style="font-family: 'Ubuntu Mono', monospace"
>
<span>1</span>
<span>2</span>
<span>3</span>
@ -120,7 +126,8 @@
<div v-if="currentStep === 2">
<div
class="font-semibold text-black mb-6 text-2xl"
style="font-family: 'Ubuntu', monospace">
style="font-family: 'Ubuntu', monospace"
>
Can we change our minds later?
</div>
<div class="grid gap-4">
@ -133,7 +140,8 @@
? 'border-violet-700 bg-violet-700 text-white'
: 'border-neutral-200 hover:border-violet-700 hover:bg-violet-50',
]"
@click="selectOption('reversible', option.value)">
@click="selectOption('reversible', option.value)"
>
<div class="font-semibold mb-1">{{ option.title }}</div>
<div class="text-sm opacity-85">
{{ option.description }}
@ -157,7 +165,8 @@
? 'border-violet-700 bg-violet-700 text-white'
: 'border-neutral-200 hover:border-violet-700 hover:bg-violet-50',
]"
@click="selectOption('expertise', option.value)">
@click="selectOption('expertise', option.value)"
>
<div class="font-semibold mb-1">{{ option.title }}</div>
<div class="text-sm opacity-85">
{{ option.description }}
@ -181,7 +190,8 @@
? 'border-violet-700 bg-violet-700 text-white'
: 'border-neutral-200 hover:border-violet-700 hover:bg-violet-50',
]"
@click="selectOption('impact', option.value)">
@click="selectOption('impact', option.value)"
>
<div class="font-semibold mb-1">{{ option.title }}</div>
<div class="text-sm opacity-85">
{{ option.description }}
@ -205,7 +215,8 @@
? 'border-violet-700 bg-violet-700 text-white'
: 'border-neutral-200 hover:border-violet-700 hover:bg-violet-50',
]"
@click="selectOption('options', option.value)">
@click="selectOption('options', option.value)"
>
<div class="font-semibold mb-1">{{ option.title }}</div>
<div class="text-sm opacity-85">
{{ option.description }}
@ -229,7 +240,8 @@
? 'border-violet-700 bg-violet-700 text-white'
: 'border-neutral-200 hover:border-violet-700 hover:bg-violet-50',
]"
@click="selectOption('investment', option.value)">
@click="selectOption('investment', option.value)"
>
<div class="font-semibold mb-1">{{ option.title }}</div>
<div class="text-sm opacity-85">
{{ option.description }}
@ -253,7 +265,8 @@
? 'bg-violet-700 text-white border-violet-700'
: 'bg-white text-neutral-700 border-neutral-200 hover:border-violet-700 hover:bg-violet-50',
]"
@click="selectOption('teamSize', size)">
@click="selectOption('teamSize', size)"
>
{{ size }}
</button>
</div>
@ -261,11 +274,13 @@
<!-- Navigation -->
<div
class="flex justify-between items-center mt-12 pt-8 border-t-2 border-neutral-200">
class="flex justify-between items-center mt-12 pt-8 border-t-2 border-neutral-200"
>
<button
v-if="currentStep > 1"
@click="previousStep"
class="px-6 py-3 text-violet-700 border-2 border-violet-700 rounded-md hover:bg-violet-50 transition-all duration-200">
class="px-6 py-3 text-violet-700 border-2 border-violet-700 rounded-md hover:bg-violet-50 transition-all duration-200"
>
Previous
</button>
<div v-else></div>
@ -273,13 +288,15 @@
<button
v-if="canProceed && currentStep < totalSteps"
@click="nextStep"
class="px-6 py-3 bg-violet-700 text-white rounded-md hover:bg-violet-800 transition-all duration-200">
class="px-6 py-3 bg-violet-700 text-white rounded-md hover:bg-violet-800 transition-all duration-200"
>
Next
</button>
<button
v-else-if="canProceed && currentStep === totalSteps"
@click="showRecommendation"
class="px-6 py-3 bg-violet-700 text-white rounded-md hover:bg-violet-800 transition-all duration-200">
class="px-6 py-3 bg-violet-700 text-white rounded-md hover:bg-violet-800 transition-all duration-200"
>
Get Recommendation
</button>
</div>
@ -289,7 +306,8 @@
<div
v-if="showResult"
data-results
class="border-t-2 border-neutral-200 pt-12">
class="border-t-2 border-neutral-200 pt-12"
>
<UCard class="bg-neutral-50">
<div class="mb-8">
<h2 class="text-2xl font-semibold text-violet-700 mb-2">
@ -317,10 +335,9 @@
<li
v-for="step in result.steps"
:key="step"
class="flex items-start">
<span class="text-violet-700 font-bold mr-3 mt-1"
></span
>
class="flex items-start"
>
<span class="text-violet-700 font-bold mr-3 mt-1"></span>
<span class="text-neutral-700">{{ step }}</span>
</li>
</ul>
@ -334,10 +351,9 @@
<li
v-for="tip in result.tips"
:key="tip"
class="flex items-start">
<span class="text-violet-700 font-bold mr-3 mt-1"
></span
>
class="flex items-start"
>
<span class="text-violet-700 font-bold mr-3 mt-1"></span>
<span class="text-neutral-700">{{ tip }}</span>
</li>
</ul>
@ -351,7 +367,8 @@
variant="soft"
:title="'Watch out for:'"
:description="result.warning"
class="mb-6" />
class="mb-6"
/>
<UAlert
v-if="result.success"
@ -359,7 +376,8 @@
variant="soft"
:title="'Success looks like:'"
:description="result.success"
class="mb-6" />
class="mb-6"
/>
<UCard v-if="result.alternatives" class="bg-neutral-50">
<h3 class="font-semibold text-neutral-900 mb-4 text-lg">
@ -369,7 +387,8 @@
<UCard
v-for="alt in result.alternatives"
:key="alt.method"
class="bg-white">
class="bg-white"
>
<span class="font-semibold">{{ alt.method }}:</span>
{{ alt.when }}
</UCard>
@ -380,10 +399,7 @@
<UButton @click="resetForm" color="violet">
Try Another Decision
</UButton>
<UButton
@click="printResult"
variant="outline"
color="violet">
<UButton @click="printResult" variant="outline" color="violet">
Print Recommendation
</UButton>
</div>
@ -395,17 +411,16 @@
</div>
<!-- Export Options at Bottom -->
<div class="flex justify-center py-6">
<ExportOptions
:export-data="exportData"
filename="decision-framework"
title="Decision Framework Helper" />
</div>
title="Decision Framework Helper"
/>
</div>
</template>
<script setup>
import ExportOptions from '~/components/ExportOptions.vue'
import ExportOptions from "~/components/ExportOptions.vue";
const state = reactive({
urgency: 3,
@ -584,8 +599,7 @@ function determineFramework() {
"Execute without delay",
"Debrief when crisis passes",
],
warning:
"Only use in true emergencies. Follow up with team discussion afterward.",
warning: "Only use in true emergencies. Follow up with team discussion afterward.",
success:
"Crisis averted through quick action. Team understands why autocratic mode was necessary.",
};
@ -621,11 +635,7 @@ function determineFramework() {
}
// AVOIDANT - non-urgent + undefined + low investment
if (
state.urgency <= 2 &&
state.options === "undefined" &&
state.investment === "low"
) {
if (state.urgency <= 2 && state.options === "undefined" && state.investment === "low") {
return {
method: "Strategic Delay",
tagline: "Wait for clarity to emerge",
@ -638,10 +648,8 @@ function determineFramework() {
"Revisit when conditions change",
"Document why you're waiting",
],
warning:
"Don't let avoidance become paralysis. Set a deadline for revisiting.",
success:
"By waiting, better options emerged or the decision became unnecessary.",
warning: "Don't let avoidance become paralysis. Set a deadline for revisiting.",
success: "By waiting, better options emerged or the decision became unnecessary.",
alternatives: [
{
method: "Time-boxed exploration",
@ -752,8 +760,7 @@ function determineFramework() {
"Document all input received",
"Explain how input influenced the decision",
],
success:
"Decision informed by diverse perspectives with clear accountability.",
success: "Decision informed by diverse perspectives with clear accountability.",
};
}
@ -815,10 +822,7 @@ function determineFramework() {
}
// DEMOCRATIC VOTE - larger group, time pressure
if (
(state.teamSize === "6-8" || state.teamSize === "9+") &&
state.urgency >= 4
) {
if ((state.teamSize === "6-8" || state.teamSize === "9+") && state.urgency >= 4) {
return {
method: "Democratic Vote",
tagline: "Majority decides, move forward together",
@ -838,8 +842,7 @@ function determineFramework() {
],
warning:
"Don't vote on everything! Reserve it for when other methods are too slow.",
success:
"Clear decision made efficiently with everyone having equal say.",
success: "Clear decision made efficiently with everyone having equal say.",
};
}
@ -940,7 +943,7 @@ const exportData = computed(() => ({
state: state,
currentStep: currentStep.value,
showResult: showResult.value,
result: result.value
result: result.value,
},
surveyResponses: {
urgency: state.urgency,
@ -949,19 +952,19 @@ const exportData = computed(() => ({
impact: state.impact,
options: state.options,
investment: state.investment,
teamSize: state.teamSize
teamSize: state.teamSize,
},
recommendedFramework: result.value || null,
metadata: {
completedAt: showResult.value ? new Date().toISOString() : null,
totalSteps: totalSteps,
progressPercentage: Math.round((currentStep.value / totalSteps) * 100)
progressPercentage: Math.round((currentStep.value / totalSteps) * 100),
},
exportedAt: new Date().toISOString(),
section: "decision-framework",
title: "Decision Framework Helper",
description: "Interactive wizard to find the right way to decide together"
}))
description: "Interactive wizard to find the right way to decide together",
}));
// Keyboard navigation
onMounted(() => {