feat(about): rebuild the About box as a conversion surface

Creator: the About box was "shitty" — an unreadable logo, a version number nobody asked for, copy that
insulted the creator, and buttons that looked like text. Rebuilt around one job: convert.

- **820×860 modal** (was 650×700) with a scrollable hub, and the logo at **520 px wide** instead of
  125 — the asset is 2816×1536, so it was being drawn as a thumbnail, not an icon problem.
- **Pre-Release pill** replaces "Version 1.0.0" (the assembly version stays in log lines). The pill is a
  button: it opens llamacasty.com until a Steam store page exists, so the link changes in one place.
- Tagline: "1-2-3, and go live to the world on YouTube!" The old "simple enough that even the most
  right-brained person can intuit it" is gone, and a test asserts it stays gone.
- The offer in three short blocks (free 30 fps · paid 60 fps · one-time, lifetime, no account /
  subscription / tracking), then the launch price and **one primary CTA**: "Unlock 60 fps — $79".
- Price: $79 until **April 1, 2027**, then $99 locked for life. The numbers live once, in
  `MainViewModel.Overlays`, and are recorded in `docs/ai/commercial.md`.
- **A paying customer is never sold to**: ownership collapses the price/CTA block and shows
  "Licence: owned via Steam — thank you."
- Secondary destinations (channel, Mastodon, coffee, licences) are one quiet row; footer is
  `© Llama Chile Shop`; the "Made by gramps" line is removed.
- `YtButtonSecondary` now carries a higher surface, a hairline border and a keyboard focus ring — they
  were the same tone as the panel behind them, which is why they read as plain text.

Test: `AboutHubTests.About_ShowsTheOfferToFreeUsers_AndNothingToSellToOwners` — tagline, pill, price,
CTA text, copyright, the removed lines stay removed, and the CTA block collapses when owned.
FAST gate: 540 passed, 0 failed, 0 warnings.
This commit is contained in:
2026-11-05 13:00:57 -08:00
parent 3fde7fcfe6
commit 0de953ef66
7 changed files with 275 additions and 36 deletions
+58 -1
View File
@@ -48,8 +48,65 @@
</Setter>
</Style>
<!-- Secondary buttons used to be YtButton with the SAME tone as the panel behind them, so they
read as plain text (creator, 2026-11-05: "you can tell they're buttons b/c our styling hasn't
been applied"). They now sit on a higher surface with a hairline border, and show a focus ring
so a keyboard user can find the one that matters. -->
<Style x:Key="YtButtonSecondary" TargetType="Button" BasedOn="{StaticResource YtButton}">
<Setter Property="Background" Value="{StaticResource Brush.SurfaceContainer}"/>
<Setter Property="Background" Value="{StaticResource Brush.SurfaceContainerHigh}"/>
<Setter Property="Foreground" Value="{StaticResource Brush.OnSurface}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border x:Name="Bd" Background="{TemplateBinding Background}"
BorderBrush="{StaticResource Brush.Outline}" BorderThickness="1"
CornerRadius="{StaticResource Radius.Sm}"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Border x:Name="Glow" Background="White" CornerRadius="{StaticResource Radius.Sm}" Opacity="0"/>
<Border x:Name="Focus" BorderBrush="{StaticResource Brush.Primary}" BorderThickness="2"
CornerRadius="{StaticResource Radius.Sm}" Opacity="0" Margin="-2"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Glow" Property="Opacity" Value="0.08"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Glow" Property="Opacity" Value="0.16"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="Focus" Property="Opacity" Value="1"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.45"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- The release badge: a pill that is itself a button (it links to the product site until the
Steam store page exists). -->
<Style x:Key="PillBadgeButton" TargetType="Button">
<Setter Property="Foreground" Value="{StaticResource Brush.OnSurfaceVariant}"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Padding" Value="10,3"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{StaticResource Brush.SurfaceContainerHigh}"
BorderBrush="{StaticResource Brush.Outline}" BorderThickness="1"
CornerRadius="999" Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="IconButton" TargetType="Button">