Skip to content

feat(design): Quackback AI can design from a brand and change anything - #860

Closed
mortondev wants to merge 13 commits into
feat/portal-design-v2-phase5-design-layerfrom
feat/portal-design-v2-ai-any-update
Closed

mortondev wants to merge 13 commits into
feat/portal-design-v2-phase5-design-layerfrom
feat/portal-design-v2-ai-any-update

Conversation

@mortondev

@mortondev mortondev commented Oct 31, 2026 •

Copy link
Copy Markdown
Member

Quackback AI in Appearance becomes a designer that can start from a brand and change any part of the portal.

  • Any change. One general tool writes any field in the design, through the same schema, contrast and page checks as a person's edit, and names what it could not do and why.
  • Starts that read the brand. A website, a screenshot or logo, a few words, or a website with a screenshot of it. The website reader asks honestly as a named agent, tries the host with and without www., reports a site that blocks automated visits rather than getting past it, and reads colours from a site's own CSS: its button fill first, its brand variables, its manifest, never its dark mode.
  • A whole first look. Each of the three looks is a complete portal: brand, layout, Home, the words and the composer's wording. A look that does not fit the schema is asked for once more, and long text is trimmed at a word.
  • CSS only where allowed. Behind PORTAL_DESIGN_AI_CSS, the AI may write CSS that passes the lint, and is told what it is for.
  • Fixes along the way. A brand colour is its solid shade, Home fills its rows, a centred header fits a phone, and Home, wording and dark colours land as asked.

Each change is tested, with the tests checked by breaking the code they cover.

…ds websites well

Quackback AI had a list of fields it could set: the brand, the header, the
band, the welcome message and the feed. It could not build Home, change the
menu or the words, or write own wording. It now has one tool: set any field
of the design document by its path, to any value it takes, each change
checked by the schema and the contrast solver as a person's would be. Plain
text stands for rich text and for a translated field's English, a font id
for a bundled font, and a Home block can be written as its type and width.
What it refuses comes back with why, in its reply.

Its output is untrusted, so it may not bring in a stored file or a link the
person did not give, or a Home block for a page that is off. It writes CSS
only where PORTAL_DESIGN_AI_CSS is on, which it is not by default, and only
CSS the check passes on a plan with custom CSS. Home is a section a person
can pick in the preview.

Reading a website for its brand now reads its CSS and manifest as well as
its head: brand colours weighed by where the site uses them, its page
background, dark or light, and its fonts. It says who it is, tries the
address with and without www, follows a meta refresh once, and reports a
site that answers with a bot check or a refusal as blocked, offering a
screenshot instead, rather than reading the block page as the site. On 80
real sites it read 72 (before: 31 of 48) and found a brand colour on 63
(before: 5).
Three things the first AI-only designs showed. A Home layout with one block
whose page is off was refused whole; the block is now left out and the
layout kept. Own wording written as plain text was refused when the
language had none yet. A dark colour was refused while the design had no
dark colours at all.
…s, and Home has no holes

What the first AI-only designs showed.

A screenshot start reached the model only as colours, and the brand colour
was the brightest one: a deep green or a navy never counted, so a forest-
green brand came back sage with its copper accent leading. A brand colour is
now judged by its saturation, fading only toward black, and the largest
group of such pixels leads the palette. The image itself, downscaled, goes
to the model too, so it can read the type and the shapes; a model that does
not take images still has the colours. The website reader uses the same
rule, so a deep brand colour on a site counts as well.

A Home block left its row short when the next block would not fit beside
it, or when a block beside it had its page off: a status block on a
workspace with no status page left a hole. The row's last block now grows
to fill it. Quackback AI is told to pair blocks of a like height, as a
short composer beside a long list leaves white space below it.
…fits a phone

A brand colour read from an image was the mean of its hue's pixels, so the
edges anti-aliasing blends into a dark page pulled an electric lime down to
olive. It is now the hue's most common shade, which a solid fill wins.

On a phone the centred header's menu, wider than the screen, was cut off at
its start where it could not be scrolled to, and the centred logo ran into
the buttons at the end. The menu now centres only while it fits, and the
logo leads on small screens.
A starting look set a preset, three colours, two fonts and a headline; Home,
the words and the wording waited for later requests. Each look is now a
complete design: mode and dark colours, fonts and heading weight, corners,
header, menu, band, cards, density and width, both headlines, the words,
the composer's prompt and button, and Home with its blocks for the pages the
workspace has. The prompt is a short design system: how a brand becomes
each choice. Each look goes through the same checks as any change from the
model. The directions move to their own module.
…d brands keep their character

Measured on twelve brands, the first look's weakest marks were for brand:
every company showed a letter for a logo, monochrome brands came back with
an accent picked from the edges of their CSS, and brands that fill their
pages with colour came back softened.

A website start now takes the site's logo as the workspace's when it has
none and the person may change the workspace's settings, and only a logo
the lookup is sure of. The website reader also notes the colour its buttons
are filled with, neutrals included, and whether it fills large areas with
its brand colour, and the design system keeps a monochrome brand
monochrome and gives a bold one its full-colour band. The example look
moves to a brand unlike any of those measured.
Measured with a smaller model, a quarter of starts came back with no looks:
the complete looks are a long answer, and one that did not fit the schema
ended the start. It is now asked for once more before the start fails.
…d button, and names a monochrome brand

From the judges' notes on round two. A white site read as dark when its CSS
painted the body black for dark mode, so dark-mode blocks and dark-theme
rules are no longer read. A brand whose buttons are a colour now leads with
that colour, over an accent used elsewhere. A brand whose buttons are black
is named monochrome in the brief, so its first look stays monochrome.
Every start that failed in the eval was cut off mid-answer at 4000 tokens:
three complete looks are long, and some models reason first.
Reading a site's CSS cannot see the page: generated class names hide its
buttons, and dark-mode rules can read as its look. A screenshot shows the
model the page as it is. With a website typed, adding a screenshot reads
both together, and the website field says so. A look's text that runs past
its field is trimmed at a word rather than refusing the start.
@mortondev
mortondev added this pull request to stack #833 October 31, 2026 13:50
@mortondev mortondev changed the title feat/portal design v2 ai any update feat(design): Quackback AI can design from a brand and change anything Oct 31, 2026
…decoded once

The portal's Home and Appearance both imported home.ts once Home filled
its rows, which split it into a chunk of its own and cost Appearance a
request. Row filling now lives in home-spans.ts, which only the portal
imports.

The website reader decoded a page's entities one after another, so an
escaped one, such as <, was decoded twice. It now decodes in one
pass.
@mortondev

Copy link
Copy Markdown
Member Author

Condensed into #880. The stack is now five PRs, #878 to #882; this branch is kept as it was.

@mortondev mortondev closed this Nov 1, 2026
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