Skip to content

Themes: part colours, palettes, genre looks and striped rows - #32

Merged
HarryCordewener merged 6 commits into
mainfrom
claude/markupstring-themes-dp2m7a
Oct 7, 2026
Merged

HarryCordewener merged 6 commits into
mainfrom
claude/markupstring-themes-dp2m7a

Conversation

@HarryCordewener

@HarryCordewener HarryCordewener commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Requested by Grave · project thread

Before: a LayoutTheme set only characters (border style, guides, bullet, gauge pieces). The only way to colour a whole layout was Colored or Shaded, which paint every part the same way.

After: a theme colours each part of a layout on its own, can bring its own shapes (border, title ornaments, bullet, gauge), and can stripe every second row of a table or field list. A palette gives a full set of colours in one step: a preset, one of nine genre themes, any base16 scheme, JSON, or one seed colour.

How:

  • Part colours. LayoutTheme gains BorderColor, TitleColor, HeadingColor, LabelColor, SeparatorColor, BulletColor, GuideColor, HeaderRuleColor, GaugeFilledColor, GaugeEmptyColor and StripeColor, each an IMarkup. Each block paints its own pieces; colour a piece sets itself still wins. The codec keeps them through the serializer and relayout.
  • ThemePalette. Eleven roles (background, surface, foreground, primary, secondary, tertiary, muted, success, warning, error, info), mapped onto the parts by ToTheme(paint), which asks for each colour as text, bold or background (ThemePaint). AnsiTheme.ToLayoutTheme() paints in ANSI.
  • Generate(seed, harmony, mode, contrast). Accent hues from the seed by harmony; each accent's OKLCH lightness is moved until its WCAG contrast reaches 3:1 for lines and 4.5:1 for text (7:1 at contrast 1). A generated palette keeps its seed, so InMode makes it again for a light or dark background, and {"preset":"fantasy","mode":"light"} does the same from JSON.
  • Genre themes and ThemeLook. A look sets a border preset, ornaments either side of a title, the tree guide, bullet, gauge pieces, field separator and header rule (look in JSON). ThemePalette.Genres has one theme per MSSP genre: adult, fantasy, historical, horror, modern, mystery, romance, science-fiction, spiritual. An ASCII-only reader gets the ASCII form of each piece.
  • Striped rows. Table.Striped and Fields.Striped lay every second row, all its lines and the full width, on StripeColor; a cell's own background wins. HTML: ms-striped and --ms-stripe.
  • Sixteen-colour clients. Every colour carries a standard colour picked by hue family (ColorMath.StandardSlot), sent as StandardForeground. ThemePalette.Terminal uses standard colours only.
  • Themed.Fallback / .ThemedUnder(). A theme that fills in only what the surrounding one leaves unset, so a game's default sits under a reader's theme.
  • HTML. Themed blocks write --ms-border, --ms-title, ... (-default for a fallback), which LayoutCss reads. IColorMarkup.Background reports a layer's background.
  • ColorMath. Contrast, WithContrast, OKLCH conversion, hue rotation, hex parsing.

Docs: "Themes and palettes" and "Striped rows" in docs/layout.md; changelog entries. Tests: ThemeTests (contrast in both modes for every harmony, base16, JSON round trips and errors, genre looks in Unicode and ASCII, stripes, mode regeneration, ANSI at full and 16-colour depth, fallback order, serializer and relayout, HTML). Full suite passes (964 tests), including after merging main.

Design notes are in the project's markup-themes/plan.md.

🤖 Generated with Claude Code

https://claude.ai/code/session_014FuCWyo4QX6dza8MxQQoZM

LayoutTheme colours borders, titles, headings, labels, separators,
bullets, guides, the header rule and gauge parts. ThemePalette names ten
colours by role and maps them onto those parts; palettes come from
presets, base16 schemes, JSON, or one seed colour with a harmony, each
accent moved in lightness until it meets a WCAG contrast ratio. Every
colour keeps a standard colour, picked by hue, for sixteen-colour
clients. Themed.Fallback puts a game's default under a reader's theme.
HTML writes the colours as --ms-* custom properties that LayoutCss reads.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FuCWyo4QX6dza8MxQQoZM
@HarryCordewener HarryCordewener self-assigned this Oct 7, 2026
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Warning

Review paused — included plan limit reached

Keep your review moving with free on-demand reviews.

  • Run this review for free

On-demand reviews are free for the next 3 days.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Promotion and pricing details

On-demand reviews are free for the next 3 days. After that, they cost $0.25 per reviewed file.

Review limit details

Or wait 12 minutes for your next included review.

Check out review usage here.

Limit details: You’ve used the included review currently available. Your 78 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Essentials
  • Run ID: 06018051-694a-41a1-b68a-f598c91d9a7a
📥 Commits

Reviewing files that changed from the base of the PR and between 1423fd9 and cc1fe92.

📒 Files selected for processing (23)
  • CHANGELOG.md
  • MarkupString.Ansi/AnsiMarkup.cs
  • MarkupString.Ansi/AnsiTheme.cs
  • MarkupString.Ansi/PublicAPI.Unshipped.txt
  • MarkupString.Html/Emitters/LayoutHtml.cs
  • MarkupString.Html/LayoutCss.cs
  • MarkupString.Tests/Layout/ThemeTests.cs
  • MarkupString/ColorGradient.cs
  • MarkupString/ColorMath.cs
  • MarkupString/Layout/Blocks/Block.cs
  • MarkupString/Layout/Blocks/BlockCodec.cs
  • MarkupString/Layout/Blocks/Bullets.cs
  • MarkupString/Layout/Blocks/Fields.cs
  • MarkupString/Layout/Blocks/Frame.cs
  • MarkupString/Layout/Blocks/Gauge.cs
  • MarkupString/Layout/Blocks/LayoutJson.cs
  • MarkupString/Layout/Blocks/Modifiers.cs
  • MarkupString/Layout/Blocks/Table.cs
  • MarkupString/Layout/Blocks/Tree.cs
  • MarkupString/PublicAPI.Unshipped.txt
  • MarkupString/ThemeLook.cs
  • MarkupString/ThemePalette.cs
  • docs/layout.md
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

A standard colour looks however the reader's client makes it, so a ratio
against the VGA value says nothing about what the reader sees.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FuCWyo4QX6dza8MxQQoZM
claude added 3 commits October 7, 2026 05:35
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FuCWyo4QX6dza8MxQQoZM
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FuCWyo4QX6dza8MxQQoZM
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FuCWyo4QX6dza8MxQQoZM
@HarryCordewener
HarryCordewener marked this pull request as ready for review October 7, 2026 06:00
@coderabbitai

coderabbitai Bot commented Oct 7, 2026

Copy link
Copy Markdown

Add Carrot credits or activate Agent usage billing to use Autopilot

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FuCWyo4QX6dza8MxQQoZM
@HarryCordewener HarryCordewener changed the title Themes that colour a layout's parts, and palettes to make them from Themes: part colours, palettes, genre looks and striped rows Oct 7, 2026
@HarryCordewener
HarryCordewener merged commit 023d597 into main Oct 7, 2026
7 checks passed
@HarryCordewener
HarryCordewener deleted the claude/markupstring-themes-dp2m7a branch October 7, 2026 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants