Skip to content

Feat green day#2843

Open
eldadfux wants to merge 6 commits intomainfrom
feat-green-day
Open

Feat green day#2843
eldadfux wants to merge 6 commits intomainfrom
feat-green-day

Conversation

@eldadfux
Copy link
Copy Markdown
Member

@eldadfux eldadfux commented Mar 31, 2026

What does this PR do?

(Provide a description of what this PR does.)

Test Plan

(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.)

Related PRs and Issues

(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)

Have you read the Contributing Guidelines on issues?

(Write your answer here.)

Summary by CodeRabbit

  • New Features

    • Brand theming: added dual brand themes (pink, green) with dynamic switching and theme-aware logos
    • New MongoDB icon available in the icon set
  • Improvements

    • Reworked gradients, buttons, cards, and image treatments to use theme variables instead of hard-coded colors
    • Theme-specific image and icon filters for consistent recoloring across pages and components
    • Several UI elements updated to respond to the active brand theme

…for PreFooter, introduce 'mongo' icon type, and update HeroBanner component with new title and icon options. Enhance Docs layout with dynamic logo sources based on brand theme.
…e to pink, adjust CSS variables for pink hues, and synchronize logo display based on theme changes.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 621330d2-1fa6-4207-bc91-5c5911f4ab13

📥 Commits

Reviewing files that changed from the base of the PR and between c619e4f and c737f66.

📒 Files selected for processing (1)
  • src/routes/(marketing)/(components)/pricing.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/(marketing)/(components)/pricing.svelte

Walkthrough

Adds a brand theming system supporting pink and green variants: new CSS variables and body.brand-* overrides (including image tint/filter and button color mappings), replaces hard-coded pink colors with theme-driven variables across many SCSS/Svelte files, introduces brand-aware logo/favicons and MutationObserver-based synchronization in multiple layouts/components, wraps pages/sections with brandable containers, adds a MongoDB SVG icon and updates icon types, and exposes a public BrandTheme type and env/localStorage-driven theme application logic.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Feat green day' is vague and does not clearly describe the main changes; it uses a casual, non-descriptive phrasing that obscures the actual intent of adding green branding/theming support. Consider using a more descriptive title such as 'Add green brand theme support' or 'Implement multi-brand theming (pink/green)' to clearly communicate the primary changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-green-day

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 31, 2026

Greptile Summary

This PR introduces a dual brand-theme system (pink / green) across the Appwrite website, enabling dynamic color switching via a PUBLIC_BRAND_THEME env var or localStorage. It replaces numerous hardcoded pink RGBA values with theme-aware CSS variables, adds green-variant logos and SVGs, implements image recoloring via CSS filter for the green theme, and surfaces a MongoDB partnership banner on the homepage.

Key changes:

  • New BrandTheme type and applyBrandTheme() in +layout.svelte, writing brand-pink / brand-green onto document.body and switching the favicon
  • Extensive global CSS selectors in +layout.svelte to apply hue-rotate filters to product/docs/pricing images in the green theme
  • --web-color-button-primary, --web-color-brand-rgb, and image-filter CSS variables introduced in _colors.scss / app.css and consumed throughout buttons, badges, cards, and gradients
  • MutationObserver in Main.svelte, Docs.svelte, FooterNav.svelte, and site-footer.svelte to react to brand-class changes on the body and swap logos accordingly
  • New mongo icon registered in the sprite and icon type union; HeroBanner updated to support a MongoDB icon variant

Issue found:

  • The syncBrandTheme / syncBrandLogo helper in four layout and footer components checks brand-pink presence and falls back to green when neither class exists. Because Svelte fires child onMount before parent onMount, these helpers run before the root layout has written the brand class to the body, causing a brief flash of the green theme/logo for default pink-theme users on every initial page load.

Confidence Score: 4/5

Safe to merge after fixing the inverted brand-theme fallback that causes a green-logo flash for default (pink) users on hydration.

A single P1 logic bug affects all four components that sync the brand logo/theme: the fallback when no brand class is present resolves to green instead of the correct default pink. The fix is a one-line change per file. All other changes are well-structured theme-variable refactors with no correctness issues.

src/lib/layouts/Main.svelte, src/lib/layouts/Docs.svelte, src/lib/components/FooterNav.svelte, src/lib/components/layout/site-footer.svelte — all share the same inverted syncBrandTheme/syncBrandLogo fallback.

Important Files Changed

Filename Overview
src/lib/layouts/Main.svelte Adds brand theme observer and dynamic logo switching; contains inverted fallback (brand-pink check instead of brand-green) that defaults to green when no class is present during hydration, causing a brief wrong-logo flash for default pink-theme users.
src/lib/layouts/Docs.svelte Same inverted fallback bug as Main.svelte: syncBrandTheme defaults to green when neither class is present during initial hydration.
src/lib/components/FooterNav.svelte Adds dynamic logo switching via MutationObserver, but syncBrandLogo has the same inverted fallback: defaults to the green logo when brand-pink isn't set, incorrectly showing appwrite-green.svg on initial load for pink users.
src/lib/components/layout/site-footer.svelte Same inverted fallback as FooterNav.svelte — defaults to green logo when neither brand class is on the body during initial hydration.
src/routes/+layout.svelte Core of the feature: adds BrandTheme type, getPreferredBrandTheme(), and applyBrandTheme() with favicon switching, plus extensive global CSS selectors for image recoloring in green theme. Logic is sound but child components' fallback handling is wrong.
src/scss/1-css-variables/_colors.scss Introduces brand-aware CSS variables and body.brand-green / body.brand-pink overrides. Clean and well-structured.
src/scss/6-elements/_button.scss Replaces all hard-coded pink RGBA values with theme-aware hsl(var(--web-color-button-primary) / alpha) — clean refactor that enables green theme support.
src/routes/(marketing)/(components)/hero-banner.svelte Adds mongo icon variant with a styled badge; removes the New text label that previously accompanied the sparkle icon. The mongo icon and type are properly registered.

Reviews (4): Last reviewed commit: "format" | Re-trigger Greptile

Comment on lines 37 to 40
<HeroBanner
title="Introducing Appwrite Arena"
title="Appwrite partners with the world's best database company"
href="/blog/post/announcing-appwrite-arena"
/>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Banner title/href mismatch

The banner title was updated to announce the MongoDB partnership, but the href still points to the old Appwrite Arena post (/blog/post/announcing-appwrite-arena). Users clicking the banner will land on the wrong article.

The href should be updated to point to the new MongoDB partnership announcement post:

Suggested change
<HeroBanner
title="Introducing Appwrite Arena"
title="Appwrite partners with the world's best database company"
href="/blog/post/announcing-appwrite-arena"
/>
<HeroBanner
title="Appwrite partners with the world's best database company"
href="/blog/post/announcing-appwrite-mongodb-atlas"
/>

(Update the path to whatever the actual slug of the MongoDB partnership post is.)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (5)
src/routes/(marketing)/(components)/hero.svelte (1)

63-65: Consider consolidating the filter rule with other brand-green selectors.

The .brand-dashboard wrapper and scoped filter work correctly for the green theme. However, similar filter rules exist in src/scss/1-css-variables/_colors.scss (which defines --web-color-image-accent-filter for body.brand-green). Consider using that CSS variable instead to maintain consistency:

 :global(body.brand-green .brand-dashboard) {
-    filter: hue-rotate(155deg) saturate(1.06) brightness(0.98);
+    filter: var(--web-color-image-accent-filter);
 }

Also applies to: 87-91

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/`(marketing)/(components)/hero.svelte around lines 63 - 65, The
.brand-dashboard wrapper around the Dashboard component currently applies a
scoped filter for the green theme; instead, remove the hardcoded filter and use
the existing CSS variable --web-color-image-accent-filter (defined for
body.brand-green in _colors.scss) so theme rules are consolidated and
consistent; update styles surrounding .brand-dashboard (and the similar rules at
the other occurrence around lines 87-91) to reference that variable rather than
duplicating filter values.
src/app.css (1)

482-512: Variable naming inconsistency and duplication with SCSS.

  1. Naming inconsistency: --brand-accent-rgb is defined here, while src/scss/1-css-variables/_colors.scss defines --web-color-brand-rgb for the same purpose. Both contain identical values (e.g., 253 54 110 for pink, 15 166 95 for green). Consider consolidating to a single variable name.

  2. Duplication within selectors: The body.brand-green and body.brand-green .light blocks are nearly identical—same for body.brand-pink blocks. This could be simplified:

Simplified approach using :is()
-body.brand-green {
-    --color-pink-hue: 151;
-    --color-secondary-hue: 165;
-    --color-pink-500: hsl(151 72% 38%);
-    --color-pink-600: hsl(151 66% 32%);
-    --color-accent: var(--color-pink-500);
-    --color-accent-darker: var(--color-pink-600);
-    --brand-accent-rgb: 15 166 95;
-}
-
-body.brand-green .light {
-    --color-pink-hue: 151;
-    --color-secondary-hue: 165;
-    --color-pink-500: hsl(151 72% 38%);
-    --color-pink-600: hsl(151 66% 32%);
-    --color-accent: var(--color-pink-500);
-    --color-accent-darker: var(--color-pink-600);
-    --brand-accent-rgb: 15 166 95;
-}
+body.brand-green,
+body.brand-green .light {
+    --color-pink-hue: 151;
+    --color-secondary-hue: 165;
+    --color-pink-500: hsl(151 72% 38%);
+    --color-pink-600: hsl(151 66% 32%);
+    --color-accent: var(--color-pink-500);
+    --color-accent-darker: var(--color-pink-600);
+    --brand-accent-rgb: 15 166 95;
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app.css` around lines 482 - 512, Consolidate duplicate CSS variables and
selectors: unify the RGB variable names by replacing/aliasing --brand-accent-rgb
with the SCSS variable --web-color-brand-rgb (or vice versa) so both systems use
the same semantic name, and remove duplicated blocks for body.brand-green /
body.brand-green .light and body.brand-pink / body.brand-pink .light by merging
them into a single rule (use a combined selector such as :is(body.brand-green,
body.brand-green .light) and :is(body.brand-pink, body.brand-pink .light) or add
fallback alias variables) while preserving the exact hsl/RGB values for
--color-pink-hue, --color-secondary-hue, --color-pink-500, --color-pink-600,
--color-accent, --color-accent-darker and the unified RGB variable
(--brand-accent-rgb / --web-color-brand-rgb) referenced in those selectors.
src/lib/components/layout/site-footer.svelte (1)

97-112: Duplicated brand logo sync logic across components.

This syncBrandLogo() and MutationObserver pattern is duplicated verbatim in src/lib/components/FooterNav.svelte. Consider extracting this into a shared utility or Svelte store to reduce duplication and ensure consistent behavior.

Additionally, this has the same timing issue noted in FooterNav—defaulting to green when brand-pink is absent, which may cause a brief flash before the root layout applies the theme class.

Example: Extract to a shared store
// src/lib/stores/brand-theme.ts
import { writable } from 'svelte/store';
import { browser } from '$app/environment';

function createBrandLogoStore() {
    const { subscribe, set } = writable('/images/logos/appwrite.svg');

    if (browser) {
        const sync = () => {
            set(document.body.classList.contains('brand-green')
                ? '/images/logos/appwrite-green.svg'
                : '/images/logos/appwrite.svg');
        };
        
        const observer = new MutationObserver(sync);
        observer.observe(document.body, { attributes: true, attributeFilter: ['class'] });
        sync();
    }

    return { subscribe };
}

export const brandLogoSrc = createBrandLogoStore();

Then in components: import { brandLogoSrc } from '$lib/stores/brand-theme'; <img src={$brandLogoSrc} />

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/components/layout/site-footer.svelte` around lines 97 - 112, The
syncBrandLogo function and brandObserver logic in site-footer.svelte
(syncBrandLogo, brandObserver) is duplicated in FooterNav.svelte and causes a
flash because the default logo is set before the root class is applied; extract
this into a shared Svelte store (e.g., createBrandLogoStore / brandLogoSrc) that
runs only in the browser, performs an immediate sync of
document.body.classList.contains('brand-pink'/'brand-green') to set the initial
value, installs a MutationObserver to update the store when body class changes,
and export a subscribe-only store; then replace the per-component
syncBrandLogo/brandObserver with an import of the store (use $brandLogoSrc or
subscribe) in site-footer.svelte and FooterNav.svelte to remove duplication and
avoid the timing flash.
src/routes/+layout.svelte (1)

97-119: Consider exporting a brandTheme store to reduce observer duplication.

Currently, child components (Main.svelte, site-footer.svelte) poll the body class via MutationObserver to detect brand changes. Since +layout.svelte already exports currentTheme as a store for light/dark mode, consider a similar pattern for brand theme:

export const currentBrandTheme = writable<BrandTheme>(getPreferredBrandTheme());

This would allow children to subscribe reactively instead of duplicating the observer pattern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/`+layout.svelte around lines 97 - 119, Add an exported writable
store for the brand theme in +layout.svelte (e.g., export const
currentBrandTheme = writable<BrandTheme>(getPreferredBrandTheme())) and update
applyBrandTheme(…) to call currentBrandTheme.set(theme) whenever it changes;
keep the existing DOM class/fav icon logic but use the store as the single
source of truth so child components (Main.svelte, site-footer.svelte) can
subscribe reactively instead of using MutationObserver. Ensure the store is
exported at top-level (alongside currentTheme) and imported in children where
you replace their observers with subscriptions to currentBrandTheme.
src/scss/1-css-variables/_colors.scss (1)

127-141: Consider semantic naming for long-term maintainability.

The approach of overriding --web-color-pink-* variables with green values is pragmatic and minimizes changes, but may cause confusion when debugging ("why is pink-500 showing green?"). Consider introducing semantically neutral names (e.g., --web-color-brand-500) in a future refactor.

Also note that _hero-banner-button.scss (lines 24-34) still references --web-color-pink-500 directly rather than --web-color-button-primary. This works because you're overriding --web-color-pink-500 here, but creates an incomplete abstraction layer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/scss/1-css-variables/_colors.scss` around lines 127 - 141, The SCSS uses
theme-specific green values to override pink variables (e.g.,
--web-color-pink-500) which is confusing and leaves an incomplete abstraction
because _hero-banner-button.scss still references --web-color-pink-500 directly;
fix by introducing and using semantic variables (for example add
--web-color-brand-500 and/or ensure --web-color-button-primary is set and used):
update the body.brand-green block to set --web-color-brand-500 (or set
--web-color-button-primary) alongside existing overrides, then change usages in
_hero-banner-button.scss from --web-color-pink-500 to the semantic variable
(--web-color-button-primary or --web-color-brand-500) so components consume
semantic names instead of color-specific ones.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/components/FooterNav.svelte`:
- Around line 113-128: The syncBrandLogo logic can flash the wrong logo because
the layout sets body classes after child mounts; update syncBrandLogo to
explicitly check for both 'brand-pink' and 'brand-green' (rather than defaulting
to green when 'brand-pink' is absent) and set logoSrc only when the theme is
determined — e.g., prefer '/images/logos/appwrite.svg' if
document.body.classList.contains('brand-pink'), else if contains('brand-green')
use '/images/logos/appwrite-green.svg', otherwise leave the current logo or
default to the pink asset; keep the MutationObserver and onMount cleanup
(brandObserver.disconnect) as-is and only change the branch logic in
syncBrandLogo and where logoSrc is initially set.

In `@src/lib/components/PromptBanner.svelte`:
- Line 86: The prompt icon's class ai-banner-prompt-icon is matching the generic
selector .ai-banner [class*='icon'] and getting forced white; rename the class
on the AiPromptIcon usage (and the other occurrences around lines 317-319) to a
more specific name (e.g., ai-banner-prompt-icon--unique or
ai-banner__prompt-icon) and update any corresponding CSS if present so it no
longer matches [class*='icon']; keep the utility class text-primary (or
brand-green) on the element so color rules apply correctly after renaming.

In `@src/lib/layouts/Docs.svelte`:
- Around line 89-91: syncBrandTheme currently uses a ternary that defaults to
'green' when no brand class exists, causing a flash; update syncBrandTheme to
prefer 'pink' as the fallback by checking for the explicit green class first
(e.g., test document.body.classList.contains('brand-green') and set brandTheme =
'green' only if present, otherwise set brandTheme = 'pink') so the docs logo
stays pink until the parent layout sets a brand.

In `@src/lib/layouts/Main.svelte`:
- Around line 102-104: The syncBrandTheme function currently sets brandTheme =
document.body.classList.contains('brand-pink') ? 'pink' : 'green', which
defaults to green before the parent layout adds any class; change the logic so
the absence of a class falls back to 'pink' instead. Update syncBrandTheme to
explicitly check for the green class (e.g.,
document.body.classList.contains('brand-green') ? 'green' : 'pink') so
brandTheme and the main header logo default to 'pink' on first mount; keep the
same function name syncBrandTheme and the brandTheme variable.

In `@src/routes/`(marketing)/(components)/hero-banner.svelte:
- Around line 9-12: Props type declares an unused "class" field which ESLint
flags; either remove "class?: string" from the Props definition or apply it to
the component's root anchor element by passing the class value (from $props() /
the destructured Props) into the anchor's class attribute; update the
destructuring const { title, href, icon = 'mongo' }: Props = $props() to include
class (const { title, href, icon = 'mongo', class: className }: Props =
$props()) if you choose to apply it, and ensure the anchor element in this
Svelte component uses that className.

---

Nitpick comments:
In `@src/app.css`:
- Around line 482-512: Consolidate duplicate CSS variables and selectors: unify
the RGB variable names by replacing/aliasing --brand-accent-rgb with the SCSS
variable --web-color-brand-rgb (or vice versa) so both systems use the same
semantic name, and remove duplicated blocks for body.brand-green /
body.brand-green .light and body.brand-pink / body.brand-pink .light by merging
them into a single rule (use a combined selector such as :is(body.brand-green,
body.brand-green .light) and :is(body.brand-pink, body.brand-pink .light) or add
fallback alias variables) while preserving the exact hsl/RGB values for
--color-pink-hue, --color-secondary-hue, --color-pink-500, --color-pink-600,
--color-accent, --color-accent-darker and the unified RGB variable
(--brand-accent-rgb / --web-color-brand-rgb) referenced in those selectors.

In `@src/lib/components/layout/site-footer.svelte`:
- Around line 97-112: The syncBrandLogo function and brandObserver logic in
site-footer.svelte (syncBrandLogo, brandObserver) is duplicated in
FooterNav.svelte and causes a flash because the default logo is set before the
root class is applied; extract this into a shared Svelte store (e.g.,
createBrandLogoStore / brandLogoSrc) that runs only in the browser, performs an
immediate sync of document.body.classList.contains('brand-pink'/'brand-green')
to set the initial value, installs a MutationObserver to update the store when
body class changes, and export a subscribe-only store; then replace the
per-component syncBrandLogo/brandObserver with an import of the store (use
$brandLogoSrc or subscribe) in site-footer.svelte and FooterNav.svelte to remove
duplication and avoid the timing flash.

In `@src/routes/`(marketing)/(components)/hero.svelte:
- Around line 63-65: The .brand-dashboard wrapper around the Dashboard component
currently applies a scoped filter for the green theme; instead, remove the
hardcoded filter and use the existing CSS variable
--web-color-image-accent-filter (defined for body.brand-green in _colors.scss)
so theme rules are consolidated and consistent; update styles surrounding
.brand-dashboard (and the similar rules at the other occurrence around lines
87-91) to reference that variable rather than duplicating filter values.

In `@src/routes/`+layout.svelte:
- Around line 97-119: Add an exported writable store for the brand theme in
+layout.svelte (e.g., export const currentBrandTheme =
writable<BrandTheme>(getPreferredBrandTheme())) and update applyBrandTheme(…) to
call currentBrandTheme.set(theme) whenever it changes; keep the existing DOM
class/fav icon logic but use the store as the single source of truth so child
components (Main.svelte, site-footer.svelte) can subscribe reactively instead of
using MutationObserver. Ensure the store is exported at top-level (alongside
currentTheme) and imported in children where you replace their observers with
subscriptions to currentBrandTheme.

In `@src/scss/1-css-variables/_colors.scss`:
- Around line 127-141: The SCSS uses theme-specific green values to override
pink variables (e.g., --web-color-pink-500) which is confusing and leaves an
incomplete abstraction because _hero-banner-button.scss still references
--web-color-pink-500 directly; fix by introducing and using semantic variables
(for example add --web-color-brand-500 and/or ensure --web-color-button-primary
is set and used): update the body.brand-green block to set --web-color-brand-500
(or set --web-color-button-primary) alongside existing overrides, then change
usages in _hero-banner-button.scss from --web-color-pink-500 to the semantic
variable (--web-color-button-primary or --web-color-brand-500) so components
consume semantic names instead of color-specific ones.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9e11560f-c9d4-4e89-83ed-deece096bb9b

📥 Commits

Reviewing files that changed from the base of the PR and between fdbba01 and c619e4f.

⛔ Files ignored due to path filters (3)
  • static/images/logos/appwrite-green.svg is excluded by !**/*.svg
  • static/images/logos/appwrite-light-green.svg is excluded by !**/*.svg
  • static/images/logos/logo-green.svg is excluded by !**/*.svg
📒 Files selected for processing (28)
  • src/app.css
  • src/lib/components/BlogCta.svelte
  • src/lib/components/FooterNav.svelte
  • src/lib/components/PreFooter.svelte
  • src/lib/components/PromptBanner.svelte
  • src/lib/components/fancy/gradient-text.svelte
  • src/lib/components/layout/site-footer.svelte
  • src/lib/components/ui/icon/sprite/sprite.svelte
  • src/lib/components/ui/icon/types.ts
  • src/lib/layouts/Docs.svelte
  • src/lib/layouts/Main.svelte
  • src/markdoc/layouts/Post.svelte
  • src/routes/(marketing)/(components)/hero-banner.svelte
  • src/routes/(marketing)/(components)/hero.svelte
  • src/routes/(marketing)/(components)/map.svelte
  • src/routes/(marketing)/(components)/pricing.svelte
  • src/routes/(marketing)/+page.svelte
  • src/routes/+layout.svelte
  • src/routes/blog/[[page]]/+page.svelte
  • src/routes/docs/+layout.svelte
  • src/routes/docs/+page.svelte
  • src/routes/pricing/+page.svelte
  • src/scss/1-css-variables/_colors.scss
  • src/scss/6-elements/_button.scss
  • src/scss/6-elements/_card.scss
  • src/scss/6-elements/_hero-banner-button.scss
  • src/scss/7-components/_side-nav.scss
  • src/scss/abstract/mixins/_checked-badge.scss

Comment on lines +113 to +128
const syncBrandLogo = () => {
logoSrc = document.body.classList.contains('brand-pink')
? '/images/logos/appwrite.svg'
: '/images/logos/appwrite-green.svg';
};

onMount(() => {
syncBrandLogo();

const brandObserver = new MutationObserver(syncBrandLogo);
brandObserver.observe(document.body, { attributes: true, attributeFilter: ['class'] });

return () => {
brandObserver.disconnect();
};
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Initial logo may flash before theme class is applied.

The syncBrandLogo() function defaults to the green logo when brand-pink is absent. However, per src/routes/+layout.svelte (lines 109-117), the root layout applies brand-pink/brand-green to document.body in its own onMount, which runs after child components mount. This means on initial render, neither class exists, causing the logo to briefly show green before the MutationObserver corrects it.

Consider checking for both classes explicitly and only switching when the theme is definitively determined:

Proposed fix
 const syncBrandLogo = () => {
-    logoSrc = document.body.classList.contains('brand-pink')
-        ? '/images/logos/appwrite.svg'
-        : '/images/logos/appwrite-green.svg';
+    if (document.body.classList.contains('brand-green')) {
+        logoSrc = '/images/logos/appwrite-green.svg';
+    } else {
+        logoSrc = '/images/logos/appwrite.svg';
+    }
 };

This ensures pink is the default until brand-green is explicitly set.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const syncBrandLogo = () => {
logoSrc = document.body.classList.contains('brand-pink')
? '/images/logos/appwrite.svg'
: '/images/logos/appwrite-green.svg';
};
onMount(() => {
syncBrandLogo();
const brandObserver = new MutationObserver(syncBrandLogo);
brandObserver.observe(document.body, { attributes: true, attributeFilter: ['class'] });
return () => {
brandObserver.disconnect();
};
});
const syncBrandLogo = () => {
if (document.body.classList.contains('brand-green')) {
logoSrc = '/images/logos/appwrite-green.svg';
} else {
logoSrc = '/images/logos/appwrite.svg';
}
};
onMount(() => {
syncBrandLogo();
const brandObserver = new MutationObserver(syncBrandLogo);
brandObserver.observe(document.body, { attributes: true, attributeFilter: ['class'] });
return () => {
brandObserver.disconnect();
};
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/components/FooterNav.svelte` around lines 113 - 128, The
syncBrandLogo logic can flash the wrong logo because the layout sets body
classes after child mounts; update syncBrandLogo to explicitly check for both
'brand-pink' and 'brand-green' (rather than defaulting to green when
'brand-pink' is absent) and set logoSrc only when the theme is determined —
e.g., prefer '/images/logos/appwrite.svg' if
document.body.classList.contains('brand-pink'), else if contains('brand-green')
use '/images/logos/appwrite-green.svg', otherwise leave the current logo or
default to the pink asset; keep the MutationObserver and onMount cleanup
(brandObserver.disconnect) as-is and only change the branch logic in
syncBrandLogo and where logoSrc is initially set.

<div class="ai-banner_content">
<div class="ai-banner_title">
<AiPromptIcon class="text-primary" aria-hidden="true" />
<AiPromptIcon class="ai-banner-prompt-icon text-primary" aria-hidden="true" />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Rename this styling hook so it doesn't match the generic icon override.

ai-banner-prompt-icon matches .ai-banner [class*='icon'] on Line 272, so the prompt icon gets pulled into the existing color: white rule. That makes text-primary and the new brand-green tinting unreliable.

🔧 Minimal fix
-                <AiPromptIcon class="ai-banner-prompt-icon text-primary" aria-hidden="true" />
+                <AiPromptIcon class="ai-banner-prompt-mark text-primary" aria-hidden="true" />
-    :global(body.brand-green .ai-banner .ai-banner-prompt-icon) {
+    :global(body.brand-green .ai-banner .ai-banner-prompt-mark) {
         filter: var(--web-color-image-accent-filter);
     }

Also applies to: 317-319

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/components/PromptBanner.svelte` at line 86, The prompt icon's class
ai-banner-prompt-icon is matching the generic selector .ai-banner
[class*='icon'] and getting forced white; rename the class on the AiPromptIcon
usage (and the other occurrences around lines 317-319) to a more specific name
(e.g., ai-banner-prompt-icon--unique or ai-banner__prompt-icon) and update any
corresponding CSS if present so it no longer matches [class*='icon']; keep the
utility class text-primary (or brand-green) on the element so color rules apply
correctly after renaming.

Comment on lines +89 to +91
const syncBrandTheme = () => {
brandTheme = document.body.classList.contains('brand-pink') ? 'pink' : 'green';
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Keep pink as the fallback when no brand class is present.

The parent layout adds brand-pink/brand-green in its own onMount, so this component can run before either class exists. With the current ternary, that transient state resolves to green, which can flash the docs logo to the wrong brand on first paint.

🔧 Minimal fix
     const syncBrandTheme = () => {
-        brandTheme = document.body.classList.contains('brand-pink') ? 'pink' : 'green';
+        brandTheme = document.body.classList.contains('brand-green') ? 'green' : 'pink';
     };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const syncBrandTheme = () => {
brandTheme = document.body.classList.contains('brand-pink') ? 'pink' : 'green';
};
const syncBrandTheme = () => {
brandTheme = document.body.classList.contains('brand-green') ? 'green' : 'pink';
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/layouts/Docs.svelte` around lines 89 - 91, syncBrandTheme currently
uses a ternary that defaults to 'green' when no brand class exists, causing a
flash; update syncBrandTheme to prefer 'pink' as the fallback by checking for
the explicit green class first (e.g., test
document.body.classList.contains('brand-green') and set brandTheme = 'green'
only if present, otherwise set brandTheme = 'pink') so the docs logo stays pink
until the parent layout sets a brand.

Comment on lines +102 to +104
function syncBrandTheme() {
brandTheme = document.body.classList.contains('brand-pink') ? 'pink' : 'green';
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use pink as the no-class fallback here too.

This has the same first-mount timing problem as the docs layout: before the parent +layout.svelte adds a brand-* class, the current ternary resolves to green. That can briefly render the main header logo with the wrong brand.

🔧 Minimal fix
     function syncBrandTheme() {
-        brandTheme = document.body.classList.contains('brand-pink') ? 'pink' : 'green';
+        brandTheme = document.body.classList.contains('brand-green') ? 'green' : 'pink';
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function syncBrandTheme() {
brandTheme = document.body.classList.contains('brand-pink') ? 'pink' : 'green';
}
function syncBrandTheme() {
brandTheme = document.body.classList.contains('brand-green') ? 'green' : 'pink';
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/layouts/Main.svelte` around lines 102 - 104, The syncBrandTheme
function currently sets brandTheme =
document.body.classList.contains('brand-pink') ? 'pink' : 'green', which
defaults to green before the parent layout adds any class; change the logic so
the absence of a class falls back to 'pink' instead. Update syncBrandTheme to
explicitly check for the green class (e.g.,
document.body.classList.contains('brand-green') ? 'green' : 'pink') so
brandTheme and the main header logo default to 'pink' on first mount; keep the
same function name syncBrandTheme and the brandTheme variable.

Comment on lines 9 to +12
class?: string;
};

const { title, href }: Props = $props();
const { title, href, icon = 'mongo' }: Props = $props();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove unused class prop or apply it to the component.

The class prop is declared in Props but never used in the template. ESLint correctly flags this.

Option 1: Remove unused prop
 type Props = {
     title: string;
     href: string;
     icon?: Extract<IconType, 'mongo' | 'sparkle'>;
-    class?: string;
 };

-const { title, href, icon = 'mongo' }: Props = $props();
+const { title, href, icon = 'mongo' }: Props = $props();
Option 2: Apply class to the anchor element
-const { title, href, icon = 'mongo' }: Props = $props();
+const { title, href, icon = 'mongo', class: className }: Props = $props();

-<a {href} class="web-hero-banner-button relative mb-4 flex items-center!">
+<a {href} class={cn("web-hero-banner-button relative mb-4 flex items-center!", className)}>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class?: string;
};
const { title, href }: Props = $props();
const { title, href, icon = 'mongo' }: Props = $props();
icon?: Extract<IconType, 'mongo' | 'sparkle'>;
};
const { title, href, icon = 'mongo' }: Props = $props();
🧰 Tools
🪛 ESLint

[error] 12-12: 'class' is an unused Props property.

(svelte/no-unused-props)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/`(marketing)/(components)/hero-banner.svelte around lines 9 - 12,
Props type declares an unused "class" field which ESLint flags; either remove
"class?: string" from the Props definition or apply it to the component's root
anchor element by passing the class value (from $props() / the destructured
Props) into the anchor's class attribute; update the destructuring const {
title, href, icon = 'mongo' }: Props = $props() to include class (const { title,
href, icon = 'mongo', class: className }: Props = $props()) if you choose to
apply it, and ensure the anchor element in this Svelte component uses that
className.

…for brand consistency. Update image classes to apply brand-specific filters, refactor background styles for hero sections, and improve layout responsiveness across various product pages.
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.

1 participant