feat(theme): implement Falukant theme with updated styles and components

This commit is contained in:
Torsten Schulz (local)
2026-08-21 14:28:05 +02:00
parent bb27660f85
commit 846ba5b3c4
27 changed files with 329 additions and 104 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div id="app" class="app-shell">
<div id="app" class="app-shell" :class="{ 'app-shell--falukant': $route.path.startsWith('/falukant') }">
<AppHeader class="app-shell__header" />
<AppNavigation v-if="isLoggedIn && user.active" class="app-shell__nav" />
<AppContent class="app-shell__content" />

View File

@@ -0,0 +1,136 @@
/* Falukant is a self-contained light game-world theme. It is only enabled by
the route class on App.vue and intentionally leaves semantic state colors alone. */
.app-shell--falukant {
--falukant-parchment: #fffdf7;
--falukant-linen: #f7f3e9;
--falukant-copper: #9a7136;
--falukant-copper-soft: rgba(154, 113, 54, 0.12);
--falukant-ink: #29362e;
--falukant-line: rgba(75, 91, 75, 0.18);
}
.app-shell--falukant .app-content,
.app-shell--falukant .app-content__scroll {
background: #f7f5ed;
}
.app-shell--falukant .app-content__route--panel {
background: var(--falukant-parchment);
border-color: var(--falukant-line);
}
.app-shell--falukant .falukant-page,
.app-shell--falukant [class$="-view"] {
color: var(--falukant-ink);
}
.app-shell--falukant .surface-card,
.app-shell--falukant .course-card,
.app-shell--falukant .info-card,
.app-shell--falukant .section-card,
.app-shell--falukant .panel,
.app-shell--falukant .card,
.app-shell--falukant table {
border-color: var(--falukant-line) !important;
}
.app-shell--falukant .surface-card,
.app-shell--falukant .card,
.app-shell--falukant .panel,
.app-shell--falukant .section-card {
background: var(--falukant-parchment) !important;
}
.app-shell--falukant input:not([type="checkbox"]):not([type="radio"]),
.app-shell--falukant select,
.app-shell--falukant textarea {
background: #fffefa;
border-color: var(--falukant-line);
color: var(--falukant-ink);
}
.app-shell--falukant .falukant-primary-action,
.app-shell--falukant .repair-confirm-button,
.app-shell--falukant .select-heir-button,
.app-shell--falukant .set-heir-button,
.app-shell--falukant .btn-create-activity,
.app-shell--falukant .approve-button {
background: var(--color-primary) !important;
color: var(--color-text-on-accent) !important;
box-shadow: 0 5px 12px rgba(42, 90, 56, 0.16);
}
.app-shell--falukant .falukant-primary-action:not(:disabled):hover,
.app-shell--falukant .repair-confirm-button:not(:disabled):hover,
.app-shell--falukant .select-heir-button:not(:disabled):hover,
.app-shell--falukant .set-heir-button:not(:disabled):hover,
.app-shell--falukant .btn-create-activity:not(:disabled):hover,
.app-shell--falukant .approve-button:not(:disabled):hover {
background: var(--color-primary-hover) !important;
color: var(--color-text-on-accent) !important;
}
.app-shell--falukant .button-secondary,
.app-shell--falukant .button--secondary,
.app-shell--falukant .btn-back,
.app-shell--falukant .cancel-button {
background: #fffefa !important;
color: var(--falukant-ink) !important;
border-color: var(--falukant-line) !important;
box-shadow: none !important;
}
.app-shell--falukant .status-bar,
.app-shell--falukant .branch-selection,
.app-shell--falukant .director-info,
.app-shell--falukant .production-section,
.app-shell--falukant .sale-section,
.app-shell--falukant .revenue-section,
.app-shell--falukant .storage-section {
background: var(--falukant-parchment) !important;
border-color: var(--falukant-line) !important;
color: var(--falukant-ink) !important;
}
.app-shell--falukant .simple-tab {
transform: none;
box-shadow: none;
}
.app-shell--falukant .simple-tab.active {
background: var(--color-primary);
color: var(--color-text-on-accent);
}
.app-shell--falukant .falukant-kicker,
.app-shell--falukant .eyebrow,
.app-shell--falukant .section-label {
color: var(--falukant-copper);
background: var(--falukant-copper-soft);
}
.app-shell--falukant .dialog,
.app-shell--falukant .modal-content {
background: var(--falukant-parchment);
border-color: var(--falukant-line);
}
.app-shell--falukant .dialog-header,
.app-shell--falukant .modal-header,
.app-shell--falukant .dialog-footer,
.app-shell--falukant .modal-footer {
background: var(--falukant-linen);
border-color: var(--falukant-line);
}
@media (max-width: 760px) {
.app-shell--falukant .simple-tabs {
overflow-x: auto;
flex-wrap: nowrap;
padding-bottom: 2px;
}
.app-shell--falukant .simple-tab {
flex: 0 0 auto;
}
}

View File

@@ -132,17 +132,17 @@ span.button {
border-color var(--transition-fast);
}
button:hover,
.button:hover,
span.button:hover {
button:hover:not(:disabled),
.button:hover:not(:disabled):not([disabled]):not(.disabled):not([aria-disabled="true"]),
span.button:hover:not([disabled]):not(.disabled):not([aria-disabled="true"]) {
transform: translateY(-1px);
background: var(--color-primary-hover);
box-shadow: 0 8px 16px rgba(38, 91, 56, 0.22);
}
button:active,
.button:active,
span.button:active {
button:active:not(:disabled),
.button:active:not(:disabled):not([disabled]):not(.disabled):not([aria-disabled="true"]),
span.button:active:not([disabled]):not(.disabled):not([aria-disabled="true"]) {
transform: translateY(0);
}

View File

@@ -292,8 +292,10 @@ export default {
min-height: 38px;
}
.dialog-button:hover {
color: var(--color-primary-hover);
.dialog-button:hover:not(:disabled),
.dialog-button:active:not(:disabled),
.dialog-button:focus-visible:not(:disabled) {
color: var(--color-text-on-accent);
}
.is-active {

View File

@@ -184,7 +184,9 @@ export default {
min-height: 38px;
}
.dialog-button:hover {
color: var(--color-primary-hover);
.dialog-button:hover:not(:disabled),
.dialog-button:active:not(:disabled),
.dialog-button:focus-visible:not(:disabled) {
color: var(--color-text-on-accent);
}
</style>

View File

@@ -45,19 +45,45 @@ export default {
<style scoped>
.simple-tabs {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 1rem;
}
.simple-tab {
min-height: 38px;
padding: 0.5rem 1rem;
background: #fff;
border: none;
background: var(--color-surface-strong);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: none;
color: var(--color-text-primary);
cursor: pointer;
transition: background 0.2s;
transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.simple-tab:hover:not(:disabled) {
transform: none;
background: var(--color-primary-soft);
border-color: var(--color-primary);
box-shadow: none;
}
.simple-tab:focus-visible {
outline: 3px solid rgba(120, 195, 138, 0.42);
outline-offset: 2px;
}
.simple-tab:disabled {
background: var(--color-bg-muted);
color: var(--color-text-muted);
cursor: not-allowed;
}
.simple-tab.active {
background: var(--color-primary-orange);
color: #000;
background: var(--color-primary);
border-color: var(--color-primary);
color: var(--color-text-on-accent);
box-shadow: none;
}
</style>

View File

@@ -124,7 +124,7 @@ button {
.weather-info {
padding: 8px 12px;
background-color: #f0f0f0;
background-color: var(--color-bg-muted);
border-radius: 4px;
font-size: 0.9em;
white-space: nowrap;

View File

@@ -543,7 +543,7 @@ export default {
}
.link {
color: #007bff;
color: var(--color-primary);
cursor: pointer;
margin-left: 0.5rem;
}
@@ -560,14 +560,14 @@ export default {
.knowledge-table th,
.knowledge-table td {
border: 1px solid #ddd;
border: 1px solid var(--color-border);
padding: 4px 6px;
}
.director-transport-section {
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid #ddd;
border-top: 1px solid var(--color-border);
}
.transport-description {
@@ -601,7 +601,7 @@ export default {
.transport-route {
padding: 0.75rem;
background-color: #f5f5f5;
background-color: var(--color-bg-muted);
border-radius: 4px;
font-size: 0.9em;
}

View File

@@ -617,7 +617,7 @@ export default {
.messages > li .body { display: flex; flex-direction: column; gap: 0.25em; }
.messages > li .notification-title { font-weight: bold; font-size: 1.05em; }
.messages > li .notification-description { color: #555; }
.messages > li .footer { color: #f9a22c; font-size: .8em; margin-top: .3em; display: flex; }
.messages > li .footer { color: #80612f; font-size: .8em; margin-top: .3em; display: flex; }
.messages > li .footer span:first-child { flex: 1; }
.empty { text-align: center; color: #777; padding: 1em; }
.pagination {

View File

@@ -182,16 +182,16 @@
</script>
<style scoped>
.revenue-section {
border: 1px solid #ccc;
.revenue-section {
border: 1px solid var(--color-border);
margin: 10px 0;
border-radius: 4px;
padding: 10px;
}
.revenue-section button {
.revenue-section button {
background: none;
border: none;
color: #007bff;
color: var(--color-primary);
cursor: pointer;
font-size: 1em;
text-decoration: underline;
@@ -204,9 +204,9 @@
width: 100%;
border-collapse: collapse;
}
th, td {
th, td {
padding: 8px;
border: 1px solid #ddd;
border: 1px solid var(--color-border);
}
.highlight {
background-color: #dfffd6;
@@ -239,9 +239,9 @@
font-size: 0.9em;
opacity: 0.9;
}
.city-price-green {
background-color: var(--color-primary-green);
color: #000;
.city-price-green {
background-color: var(--color-secondary);
color: var(--color-text-primary);
}
.city-price-orange {
background-color: var(--color-primary-orange);

View File

@@ -324,8 +324,7 @@ export default {
<style scoped>
.statusbar {
background:
linear-gradient(180deg, rgba(255, 251, 246, 0.96) 0%, rgba(247, 238, 224, 0.98) 100%);
background: #fffdf7;
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
box-sizing: border-box;
@@ -398,8 +397,8 @@ export default {
min-height: 34px;
padding: 0 10px;
border-radius: 999px;
background: rgba(255,255,255,0.68);
border: 1px solid rgba(93, 64, 55, 0.08);
background: rgba(255,255,255,0.82);
border: 1px solid rgba(75, 91, 75, 0.14);
}
.status-item.messages {
@@ -413,8 +412,8 @@ export default {
min-height: 34px;
padding: 0.2rem 0.8rem;
border-radius: var(--radius-md);
background: linear-gradient(180deg, rgba(255,255,255,0.94) 0%, rgba(248, 241, 231, 0.98) 100%);
border: 1px solid rgba(126, 71, 27, 0.16);
background: #fffefa;
border: 1px solid rgba(154, 113, 54, 0.2);
box-shadow: inset 0 1px 0 rgba(255,255,255,0.65);
min-width: 0;
flex: 0 1 auto;
@@ -424,7 +423,7 @@ export default {
.status-identity__name {
font-size: 0.98rem;
line-height: 1.2;
color: #5f3617;
color: var(--color-text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

View File

@@ -3,6 +3,7 @@ import App from './App.vue';
import store from './store';
import router from './router';
import './assets/styles.scss';
import './assets/falukant-theme.scss';
import i18n from './i18n';
import { setSeoI18nAccessor, applyRouteSeo } from './utils/seo';
import { SUPPORTED_UI_LOCALES } from './i18n/supportedLocales.js';

View File

@@ -49,7 +49,7 @@ export default {
.all-characters-test { padding: 16px }
.controls { margin-bottom: 12px }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px }
.card { border: 1px solid #e0e0e0; padding: 8px; border-radius: 6px; background: #fff }
.card { border: 1px solid var(--color-border); padding: 8px; border-radius: 6px; background: var(--color-surface) }
.label { font-weight: 600; margin-bottom: 6px }
.row { display: flex; gap: 8px }
.cell { flex: 1; text-align: center }

View File

@@ -1308,9 +1308,8 @@ export default {
.branch-hero {
padding: 24px 26px;
margin-bottom: 16px;
background:
radial-gradient(circle at top right, rgba(248, 162, 43, 0.16), transparent 28%),
linear-gradient(180deg, rgba(255, 250, 243, 0.98) 0%, rgba(247, 238, 224, 0.98) 100%);
background: #fffdf7;
border-left: 3px solid #b18445;
}
.branch-kicker {
@@ -1318,8 +1317,8 @@ export default {
margin-bottom: 10px;
padding: 4px 10px;
border-radius: 999px;
background: rgba(248, 162, 43, 0.14);
color: #8a5411;
background: rgba(154, 113, 54, 0.12);
color: #80612f;
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
@@ -1431,17 +1430,17 @@ export default {
.send-all-buttons button {
padding: 0.5rem 1rem;
background-color: #F9A22C;
color: #000000;
border: 1px solid #F9A22C;
background-color: var(--color-primary);
color: var(--color-text-on-accent);
border: 1px solid var(--color-primary);
border-radius: 4px;
cursor: pointer;
}
.send-all-buttons button:hover {
background-color: #fdf1db;
color: #7E471B;
border: 1px solid #7E471B;
background-color: var(--color-primary-hover);
color: var(--color-text-on-accent);
border: 1px solid var(--color-primary-hover);
}
.no-action {

View File

@@ -631,20 +631,20 @@ th {
.church-table thead th {
position: sticky;
top: 0;
background: #FFF;
background: var(--color-surface-strong);
z-index: 1;
padding: 8px;
border: 1px solid #ddd;
border: 1px solid var(--color-border);
text-align: left;
}
.church-table tbody td {
padding: 8px;
border: 1px solid #ddd;
border: 1px solid var(--color-border);
}
.church-table tbody tr.own-position {
background-color: #e0e0e0;
background-color: var(--color-surface-accent);
font-weight: bold;
}

View File

@@ -77,7 +77,7 @@ form {
row-gap: 15px;
width: fit-content;
margin: 0 auto;
border: 1px solid #ccc;
border: 1px solid var(--color-border);
padding: 20px;
border-radius: 4px;
}

View File

@@ -206,7 +206,7 @@ export default {
}
.selected {
background-color: #f0f8ff;
background-color: var(--color-surface-accent);
}
.actions {
@@ -269,4 +269,4 @@ h2 {
.director-row {
cursor: pointer;
}
</style>
</style>

View File

@@ -295,19 +295,25 @@ h2 {
.simple-tabs {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 1rem;
}
.simple-tab {
padding: 0.5rem 1rem;
background: #fff;
border: none;
background: var(--color-surface-strong);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-primary);
box-shadow: none;
cursor: pointer;
transition: background 0.2s;
}
.simple-tab.active {
background: #F9A22C;
color: #000;
background: var(--color-primary);
border-color: var(--color-primary);
color: var(--color-text-on-accent);
}
.tab-content {
margin-top: 1rem;

View File

@@ -1268,9 +1268,8 @@ export default {
.family-hero {
padding: 24px 26px;
margin-bottom: 16px;
background:
radial-gradient(circle at top right, rgba(248, 162, 43, 0.16), transparent 28%),
linear-gradient(180deg, rgba(255, 250, 243, 0.98) 0%, rgba(247, 238, 224, 0.98) 100%);
background: #fffdf7;
border-left: 3px solid #b18445;
}
.family-kicker {
@@ -1278,8 +1277,8 @@ export default {
margin-bottom: 10px;
padding: 4px 10px;
border-radius: 999px;
background: rgba(248, 162, 43, 0.14);
color: #8a5411;
background: rgba(154, 113, 54, 0.12);
color: #80612f;
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
@@ -1723,9 +1722,9 @@ export default {
.self-character-3d {
width: 250px;
height: 350px;
border: 1px solid #ccc;
border: 1px solid var(--color-border);
border-radius: 4px;
background-color: #fdf1db;
background-color: var(--color-surface-accent);
flex-shrink: 0;
}
@@ -1796,7 +1795,7 @@ export default {
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background-repeat: no-repeat;
background-color: #fdf1db;
background-color: var(--color-surface-accent);
box-shadow: var(--shadow-soft);
flex: 0 0 auto;
}
@@ -1808,7 +1807,7 @@ export default {
.character-3d-frame {
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background-color: #fdf1db;
background-color: var(--color-surface-accent);
flex-shrink: 0;
}

View File

@@ -194,7 +194,7 @@ h2 {
.measures-panel {
flex: 2;
padding: 10px;
border-left: 1px solid #ccc;
border-left: 1px solid var(--color-border);
}
.measures-table {
@@ -205,7 +205,7 @@ h2 {
.measures-table th,
.measures-table td {
border: 1px solid #ddd;
border: 1px solid var(--color-border);
padding: 8px;
text-align: left;
}

View File

@@ -458,7 +458,7 @@ h2 {
height: 341px;
background-repeat: no-repeat;
image-rendering: crisp-edges;
border: 1px solid #ccc;
border: 1px solid var(--color-border);
border-radius: 4px;
}
@@ -599,7 +599,7 @@ h2 {
height: 100px;
background-repeat: no-repeat;
image-rendering: crisp-edges;
border: 1px solid #ccc;
border: 1px solid var(--color-border);
border-radius: 4px;
background-size: contain;
/* scale image to container */

View File

@@ -191,7 +191,7 @@ table {
th,
td {
border: 1px solid #ccc;
border: 1px solid var(--color-border);
padding: 8px;
text-align: left;
}

View File

@@ -284,7 +284,7 @@
h2 { padding-top: 20px; }
.nobility-section,
.advance-section {
border: 1px solid #ccc;
border: 1px solid var(--color-border);
border-radius: 4px;
margin: 10px 0;
padding: 10px;

View File

@@ -915,9 +915,8 @@ export default {
.falukant-hero {
padding: 24px 26px;
margin-bottom: 16px;
background:
radial-gradient(circle at top right, rgba(248, 162, 43, 0.16), transparent 28%),
linear-gradient(180deg, rgba(255, 250, 243, 0.98) 0%, rgba(247, 238, 224, 0.98) 100%);
background: #fffdf7;
border-left: 3px solid #b18445;
}
.falukant-kicker {
@@ -925,8 +924,8 @@ export default {
margin-bottom: 10px;
padding: 4px 10px;
border-radius: 999px;
background: rgba(248, 162, 43, 0.14);
color: #8a5411;
background: rgba(154, 113, 54, 0.12);
color: #80612f;
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;

View File

@@ -365,20 +365,48 @@ h2 {
.simple-tabs {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 1rem;
}
.simple-tab {
min-height: 38px;
padding: 0.5rem 1rem;
background: #fff;
border: none;
background: var(--color-surface-strong);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: none;
color: var(--color-text-primary);
cursor: pointer;
transition: background 0.2s;
transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.simple-tab:hover:not(:disabled) {
transform: none;
background: var(--color-primary-soft);
border-color: var(--color-primary);
box-shadow: none;
}
.simple-tab:focus-visible {
outline: 3px solid rgba(120, 195, 138, 0.42);
outline-offset: 2px;
}
.simple-tab:disabled {
background: var(--color-bg-muted);
border-color: var(--color-border);
color: var(--color-text-muted);
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.simple-tab.active {
background: #F9A22C;
color: #000;
background: var(--color-primary);
border-color: var(--color-primary);
color: var(--color-text-on-accent);
}
.tab-content {
@@ -424,4 +452,4 @@ table th {
margin: -0.5rem 0 1rem;
font-weight: bold;
}
</style>
</style>

View File

@@ -597,10 +597,10 @@ h2 {
}
.create-activity {
border: 1px solid #ccc;
border: 1px solid var(--color-border);
padding: 1rem;
margin-bottom: 1rem;
background: #fafafa;
background: var(--color-surface);
border-radius: 4px;
}
@@ -615,7 +615,7 @@ h2 {
width: 100%;
padding: 0.4rem;
margin-bottom: 1rem;
border: 1px solid #ccc;
border: 1px solid var(--color-border);
border-radius: 4px;
}
@@ -644,15 +644,15 @@ h2 {
.attacks-list th,
.attacks-list td {
padding: 8px;
border: 1px solid #ddd;
border: 1px solid var(--color-border);
text-align: left;
vertical-align: top;
}
.suggestions {
position: absolute;
background: #fff;
border: 1px solid #ccc;
background: var(--color-surface-strong);
border: 1px solid var(--color-border);
z-index: 10;
max-height: 200px;
overflow-y: auto;
@@ -670,7 +670,7 @@ h2 {
}
.suggestions li:hover {
background: #eee;
background: var(--color-primary-soft);
}
.activity-status__badge {
@@ -680,8 +680,8 @@ h2 {
border-radius: 999px;
font-size: 0.88rem;
font-weight: 600;
background: #ececec;
color: #333;
background: var(--color-bg-muted);
color: var(--color-text-primary);
}
.activity-status__badge.is-pending {

View File

@@ -32,14 +32,17 @@
max-width: 1100px;
margin: 0 auto;
padding: 48px 20px 72px;
color: #40261a;
color: var(--color-text-primary);
}
.hero {
min-width: 0;
padding: 32px;
border-radius: var(--radius-lg);
background: linear-gradient(135deg, #f7e0bb 0%, #f6c27d 45%, #e8924d 100%);
box-shadow: 0 20px 60px rgba(106, 56, 20, 0.18);
background: #fffdf7;
border: 1px solid rgba(154, 113, 54, 0.24);
border-left: 4px solid #b18445;
box-shadow: 0 16px 36px rgba(76, 61, 36, 0.08);
}
.eyebrow {
@@ -48,12 +51,16 @@
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
color: #80612f;
}
.hero h1 {
margin: 0;
font-size: clamp(2rem, 4vw, 3.6rem);
line-height: 1.08;
overflow-wrap: break-word;
hyphens: auto;
word-break: normal;
}
.lead {
@@ -67,13 +74,18 @@
display: inline-block;
margin-top: 24px;
padding: 12px 20px;
border-radius: 999px;
background: #40261a;
color: #fff;
border-radius: var(--radius-md);
background: var(--color-primary);
color: var(--color-text-on-accent);
text-decoration: none;
font-weight: 700;
}
.cta:hover {
background: var(--color-primary-hover);
color: var(--color-text-on-accent);
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
@@ -84,8 +96,8 @@
.grid article {
padding: 24px;
border-radius: var(--radius-lg);
background: #fff7ef;
border: 1px solid rgba(64, 38, 26, 0.08);
background: #fffefa;
border: 1px solid rgba(75, 91, 75, 0.16);
}
.grid h2 {
@@ -97,4 +109,20 @@
margin: 0;
line-height: 1.65;
}
@media (max-width: 480px) {
.marketing-page {
padding: 24px 12px 44px;
}
.hero,
.grid article {
padding: 22px 18px;
}
.hero h1 {
font-size: clamp(1.58rem, 8.2vw, 2.15rem);
line-height: 1.12;
}
}
</style>