fix(store,audit,workspace): usertest low-findings tail (0.72.1)
Some checks failed
Security / Security check (push) Failing after 1s

- Store hero: 'TODAY' badge only for an operator-accepted story; the
  rotating compiled-in fallback deck now says 'FEATURED' (no false
  freshness claim). Policy as a top-level function with unit tests.
- Audit filter chips: standard label typography instead of mono —
  mono stays reserved for paths and identifiers.
- DE chain wording: 'Hash-Kette geprüft' as the one confirmation term
  (audit header now matches the doctor pill); 'intakt' stays the
  state headline. EN was already consistent.
- Workspace switcher: contrast bump for the sealed-area 'stopped'
  label.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-07-18 01:08:09 +02:00
parent 6152c80c84
commit ae8fdcc762
12 changed files with 69 additions and 9 deletions

View file

@ -4,7 +4,7 @@
/// Studio's own build version. Bump on every UI release so the
/// running app self-identifies.
const String kStudioVersion = '0.72.0';
const String kStudioVersion = '0.72.1';
const String kProductName = 'Ch∆In Studio';
const String kVendorName = 'Flemming.AI (F∆I)';

View file

@ -374,6 +374,7 @@
"storesManagerNotAvailableHint": "Der Anbieter hat diesen Store-Index noch nicht veröffentlicht. Sobald er das tut, ist er installierbar.",
"storesSuggestedReclaimDesc": "Recl∆Im — Module für Rechts- und Pflichten-Reform-Mapping",
"storeTodayBadge": "HEUTE",
"storeFeaturedBadge": "EMPFOHLEN",
"storeTodayDeck": "Von der Ch∆In-Redaktion",
"storeTodayDismissTooltip": "Für diese Sitzung ausblenden",
"storePillInstalled": "installiert",
@ -629,7 +630,7 @@
}
}
},
"auditHashChainVerified": "Hash-Kette verifiziert",
"auditHashChainVerified": "Hash-Kette geprüft",
"auditDetailHeader": "DETAIL",
"auditAskingFull": "Frage an die konfigurierte System-AI läuft…",
"auditFixLabel": "FIX",

View file

@ -392,6 +392,7 @@
"storesManagerNotAvailableHint": "The provider hasn't published this store index yet. It will become installable once they do.",
"storesSuggestedReclaimDesc": "Recl∆Im — modules for law & duty reform-mapping",
"storeTodayBadge": "TODAY",
"storeFeaturedBadge": "FEATURED",
"storeTodayDeck": "From the Ch∆In editor",
"storeTodayDismissTooltip": "Hide for this session",
"storePillInstalled": "installed",

View file

@ -1766,6 +1766,12 @@ abstract class AppLocalizations {
/// **'TODAY'**
String get storeTodayBadge;
/// No description provided for @storeFeaturedBadge.
///
/// In en, this message translates to:
/// **'FEATURED'**
String get storeFeaturedBadge;
/// No description provided for @storeTodayDeck.
///
/// In en, this message translates to:

View file

@ -957,6 +957,9 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get storeTodayBadge => 'HEUTE';
@override
String get storeFeaturedBadge => 'EMPFOHLEN';
@override
String get storeTodayDeck => 'Von der Ch∆In-Redaktion';
@ -1275,7 +1278,7 @@ class AppLocalizationsDe extends AppLocalizations {
}
@override
String get auditHashChainVerified => 'Hash-Kette verifiziert';
String get auditHashChainVerified => 'Hash-Kette geprüft';
@override
String get auditDetailHeader => 'DETAIL';

View file

@ -974,6 +974,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get storeTodayBadge => 'TODAY';
@override
String get storeFeaturedBadge => 'FEATURED';
@override
String get storeTodayDeck => 'From the Ch∆In editor';

View file

@ -620,9 +620,11 @@ class _ChipButtonState extends State<_ChipButton> {
),
child: Text(
widget.label,
style: ChainTheme.mono(
size: 11,
weight: widget.selected ? FontWeight.w500 : FontWeight.w400,
// UI label, not a value mono is reserved for
// paths/identifiers (usertest finding: the chips
// read as foreign bodies in the header).
style: theme.textTheme.labelMedium?.copyWith(
fontWeight: widget.selected ? FontWeight.w600 : FontWeight.w400,
color: fg,
),
),

View file

@ -3207,6 +3207,13 @@ class _ScreenshotPlaceholder extends StatelessWidget {
/// not abstract platform philosophy. Architecture education
/// (sandbox model, hash-chained audit, air-gap posture) lives
/// on the dedicated Welcome page, not in the store carousel.
/// Whether the hero deck may wear the date-bound "TODAY" badge.
/// Only a single, operator-accepted story qualifies the
/// compiled-in fallback deck rotates unchanged across sessions
/// and must not claim freshness ("FEATURED" instead). Top-level
/// so the policy stays unit-testable.
bool storeDeckIsAcceptedToday(int totalCount) => totalCount == 1;
const List<TodayStoryData> _kFallbackTodayStories = <TodayStoryData>[
TodayStoryData(
badgeEn: 'MCP',
@ -3433,7 +3440,12 @@ class _StoreTodayHero extends StatelessWidget {
runSpacing: 4,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
ChainPill(label: l.storeTodayBadge, tone: ChainPillTone.accent),
ChainPill(
label: storeDeckIsAcceptedToday(totalCount)
? l.storeTodayBadge
: l.storeFeaturedBadge,
tone: ChainPillTone.accent,
),
Text(
badge,
style: theme.textTheme.labelSmall?.copyWith(

View file

@ -149,9 +149,12 @@ class ChainWorkspaceSwitcher extends StatelessWidget {
? l.workspaceSealedRunning
: l.workspaceSealedStopped,
style: theme.textTheme.labelSmall?.copyWith(
// Secondary but readable onSurfaceVariant
// fell below comfortable contrast at this
// size (usertest finding).
color: a.running
? ChainColors.success
: theme.colorScheme.onSurfaceVariant,
: theme.colorScheme.onSurface.withValues(alpha: 0.8),
),
),
),