diff --git a/README.md b/README.md index 2eca1c7..96afcb0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# STEP 3 Arcade +# RanaZe: Step 3 Trainer -Godot study game with a bundled ASP.NET Core Questions API. +Godot-based USMLE Step 3 study trainer with a bundled ASP.NET Core Questions API. ## Local API diff --git a/api/QuestionsApi/Services/StripeDonationGateway.cs b/api/QuestionsApi/Services/StripeDonationGateway.cs index 4caf229..9b9f8b0 100644 --- a/api/QuestionsApi/Services/StripeDonationGateway.cs +++ b/api/QuestionsApi/Services/StripeDonationGateway.cs @@ -43,8 +43,8 @@ public sealed class StripeDonationGateway(IConfiguration configuration) : IStrip UnitAmount = amountCents, ProductData = new SessionLineItemPriceDataProductDataOptions { - Name = "Support MedMind", - Description = "One-time contribution supporting MedMind development and medical education content." + Name = "Support RanaZe: Step 3 Trainer", + Description = "One-time contribution supporting RanaZe development and medical education content." } } } diff --git a/assets/branding/ranaze-app-icon.png b/assets/branding/ranaze-app-icon.png new file mode 100644 index 0000000..40ed501 Binary files /dev/null and b/assets/branding/ranaze-app-icon.png differ diff --git a/assets/branding/ranaze-app-icon.png.import b/assets/branding/ranaze-app-icon.png.import new file mode 100644 index 0000000..2df5bce --- /dev/null +++ b/assets/branding/ranaze-app-icon.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vbg5y0aqkray" +path="res://.godot/imported/ranaze-app-icon.png-a240a5596e5240a654bcbed9e8cd6d33.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/branding/ranaze-app-icon.png" +dest_files=["res://.godot/imported/ranaze-app-icon.png-a240a5596e5240a654bcbed9e8cd6d33.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/branding/ranaze-mark.png b/assets/branding/ranaze-mark.png new file mode 100644 index 0000000..5798d9d Binary files /dev/null and b/assets/branding/ranaze-mark.png differ diff --git a/assets/branding/ranaze-mark.png.import b/assets/branding/ranaze-mark.png.import new file mode 100644 index 0000000..36e0427 --- /dev/null +++ b/assets/branding/ranaze-mark.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://r26p83m2qj1l" +path="res://.godot/imported/ranaze-mark.png-f1c512eea015b3fe17fffb1aff9edd53.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/branding/ranaze-mark.png" +dest_files=["res://.godot/imported/ranaze-mark.png-f1c512eea015b3fe17fffb1aff9edd53.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/docs/STRIPE_DONATIONS.md b/docs/STRIPE_DONATIONS.md index 2b8140a..d41757f 100644 --- a/docs/STRIPE_DONATIONS.md +++ b/docs/STRIPE_DONATIONS.md @@ -1,6 +1,6 @@ # Stripe Donations -MedMind accepts authenticated, one-time USD contributions through Stripe-hosted Checkout. The API enforces a minimum contribution of $5 and a maximum of $10,000. Payment card data never passes through or is stored by MedMind. +RanaZe: Step 3 Trainer accepts authenticated, one-time USD contributions through Stripe-hosted Checkout. The API enforces a minimum contribution of $5 and a maximum of $10,000. Payment card data never passes through or is stored by RanaZe. Contributions are not tax-deductible. @@ -29,17 +29,17 @@ The deployment workflow writes these values to the Kubernetes secret `medmind-st ## Stripe account settings -Configure MedMind branding in Stripe Checkout and enable successful-payment email receipts in Stripe customer email settings. Stripe Checkout collects the contributor's email address. +Configure RanaZe branding in Stripe Checkout and enable successful-payment email receipts in Stripe customer email settings. Stripe Checkout collects the contributor's email address. ## Verification After deployment: -1. Sign in to MedMind and open **Support MedMind** from the sidebar. +1. Sign in to RanaZe and open **Support RanaZe** from the sidebar. 2. Confirm that amounts below $5 and above $10,000 are rejected. 3. Start a $5 test contribution. 4. Complete Checkout using Stripe's standard test card `4242 4242 4242 4242`, any future expiration date, and any CVC. -5. Return to MedMind and confirm the contribution changes from pending to confirmed. +5. Return to RanaZe and confirm the contribution changes from pending to confirmed. 6. In Stripe, confirm the Checkout Session and webhook delivery both succeeded. 7. In MongoDB, confirm the corresponding `Donations` document has `Status: "paid"` and a populated `PaidUtc` value. diff --git a/export_presets.cfg b/export_presets.cfg index 88d49d7..ae0446b 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -22,7 +22,7 @@ vram_texture_compression/for_desktop=true vram_texture_compression/for_mobile=true html/export_icon=true html/custom_html_shell="res://web/medmind_shell.html" -html/head_include="" +html/head_include="" html/canvas_resize_policy=2 html/focus_canvas_on_start=true html/experimental_virtual_keyboard=false diff --git a/project.godot b/project.godot index 9fd353a..2c25cd2 100644 --- a/project.godot +++ b/project.godot @@ -10,11 +10,13 @@ config_version=5 [application] -config/name="MedMind" +config/name="RanaZe: Step 3 Trainer" config/version="pre-alpha" run/main_scene="res://scenes/main.tscn" config/features=PackedStringArray("4.6", "GL Compatibility") -config/icon="res://assets/branding/medmind-icon.png" +config/icon="res://assets/branding/ranaze-app-icon.png" +config/use_custom_user_dir=true +config/custom_user_dir_name="MedMind" [autoload] diff --git a/scripts/autoload/account_profile_service.gd b/scripts/autoload/account_profile_service.gd index 6a5f455..fa91768 100644 --- a/scripts/autoload/account_profile_service.gd +++ b/scripts/autoload/account_profile_service.gd @@ -163,7 +163,7 @@ func _on_profile_completed(result: int, response_code: int, _headers: PackedStri func _save_archive(content: String) -> void: - var filename := "medmind-account-export-%s.json" % Time.get_date_string_from_system() + var filename := "ranaze-account-export-%s.json" % Time.get_date_string_from_system() if OS.has_feature("web"): var encoded := Marshalls.raw_to_base64(content.to_utf8_buffer()) JavaScriptBridge.eval("(function(){const a=document.createElement('a');a.href='data:application/json;base64,%s';a.download=%s;document.body.appendChild(a);a.click();a.remove();})();" % [encoded, JSON.stringify(filename)], true) diff --git a/scripts/autoload/donation_service.gd b/scripts/autoload/donation_service.gd index c5f463e..bcc7c39 100644 --- a/scripts/autoload/donation_service.gd +++ b/scripts/autoload/donation_service.gd @@ -140,7 +140,7 @@ func _on_status_completed(result: int, response_code: int, _headers: PackedStrin func _prepare_browser_window() -> void: if OS.has_feature("web"): JavaScriptBridge.eval( - "window.localStorage.removeItem('%s'); window.medmindDonationWindow = window.open('about:blank', 'medmind_donation_checkout'); if (window.medmindDonationWindow) { var medmindWaitingWindow = window.medmindDonationWindow; medmindWaitingWindow.document.title = 'MedMind secure checkout'; medmindWaitingWindow.document.body.innerHTML = '
Opening secure checkout...

This window will continue to Stripe.

'; medmindWaitingWindow.setInterval(function () { var checkoutUrl = medmindWaitingWindow.localStorage.getItem('%s'); if (checkoutUrl) { var checkout = medmindWaitingWindow.document.getElementById('medmind-checkout'); checkout.innerHTML = 'Secure checkout is ready.

Continue to Stripe

'; medmindWaitingWindow.document.getElementById('medmind-checkout-link').href = checkoutUrl; medmindWaitingWindow.localStorage.removeItem('%s'); medmindWaitingWindow.location.replace(checkoutUrl); } }, 150); }" % [CHECKOUT_STORAGE_KEY, CHECKOUT_STORAGE_KEY, CHECKOUT_STORAGE_KEY], + "window.localStorage.removeItem('%s'); window.medmindDonationWindow = window.open('about:blank', 'medmind_donation_checkout'); if (window.medmindDonationWindow) { var medmindWaitingWindow = window.medmindDonationWindow; medmindWaitingWindow.document.title = 'RanaZe secure checkout'; medmindWaitingWindow.document.body.innerHTML = '
Opening secure checkout...

This window will continue to Stripe.

'; medmindWaitingWindow.setInterval(function () { var checkoutUrl = medmindWaitingWindow.localStorage.getItem('%s'); if (checkoutUrl) { var checkout = medmindWaitingWindow.document.getElementById('medmind-checkout'); checkout.innerHTML = 'Secure checkout is ready.

Continue to Stripe

'; medmindWaitingWindow.document.getElementById('medmind-checkout-link').href = checkoutUrl; medmindWaitingWindow.localStorage.removeItem('%s'); medmindWaitingWindow.location.replace(checkoutUrl); } }, 150); }" % [CHECKOUT_STORAGE_KEY, CHECKOUT_STORAGE_KEY, CHECKOUT_STORAGE_KEY], true) diff --git a/scripts/ui/donation_screen.gd b/scripts/ui/donation_screen.gd index 34d1af5..50f30af 100644 --- a/scripts/ui/donation_screen.gd +++ b/scripts/ui/donation_screen.gd @@ -51,7 +51,7 @@ func _build_ui() -> void: scroll.add_child(page) var title := Label.new() - title.text = "Support MedMind" + title.text = "Support RanaZe" title.add_theme_font_override("font", Brand.font) title.add_theme_font_size_override("font_size", 36) page.add_child(title) @@ -79,7 +79,7 @@ func _build_ui() -> void: mission.add_theme_constant_override("separation", 18) mission_panel.add_child(mission) mission.add_child(_heading("Our mission", 26)) - mission.add_child(_body("MedMind exists to make rigorous, clinically grounded medical education more accessible. We are building an independent Step 3 study experience that helps learners develop clinical judgment through original questions, realistic CCS cases, transparent explanations, and continuous improvement driven by learner feedback.")) + mission.add_child(_body("RanaZe exists to make rigorous, clinically grounded medical education more accessible. We are building an independent Step 3 study experience that helps learners develop clinical judgment through original questions, realistic CCS cases, transparent explanations, and continuous improvement driven by learner feedback.")) mission.add_child(HSeparator.new()) mission.add_child(_heading("What your support makes possible", 20)) for item_text in [ @@ -215,7 +215,7 @@ func _on_checkout_started(_donation_id: String, _checkout_url: String) -> void: func _on_donation_status_changed(status: String, _donation: Dictionary) -> void: match status: - "paid": _set_validation_state("Thank you for supporting MedMind. Your contribution has been confirmed.", false, Brand.SUCCESS) + "paid": _set_validation_state("Thank you for supporting RanaZe. Your contribution has been confirmed.", false, Brand.SUCCESS) "failed": _set_validation_state("Stripe could not complete the contribution. No payment was confirmed.", true) "expired": _set_validation_state("The checkout session expired. Start a new checkout when you are ready.", true) diff --git a/scripts/ui/login_screen.gd b/scripts/ui/login_screen.gd index bb3da6b..79ec3cd 100644 --- a/scripts/ui/login_screen.gd +++ b/scripts/ui/login_screen.gd @@ -126,27 +126,37 @@ func _build_ui() -> void: brand_row.add_theme_constant_override("separation", 24) left_brand.add_child(brand_row) var large_icon := TextureRect.new() - large_icon.texture = preload("res://assets/branding/medmind-icon.png") + large_icon.texture = Brand.ranaze_mark_texture() large_icon.custom_minimum_size = Vector2(190, 190) large_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE large_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED - large_icon.material = Brand.logo_cutout_material() brand_row.add_child(large_icon) - var wordmark := HBoxContainer.new() - wordmark.add_theme_constant_override("separation", 0) + var wordmark := VBoxContainer.new() + wordmark.add_theme_constant_override("separation", 4) brand_row.add_child(wordmark) - var med_wordmark := Label.new() - med_wordmark.text = "Med" - med_wordmark.add_theme_font_size_override("font_size", 76) - med_wordmark.add_theme_font_override("font", Brand.font) - wordmark.add_child(med_wordmark) - var mind_wordmark := Label.new() - mind_wordmark.text = "Mind" - mind_wordmark.add_theme_font_size_override("font_size", 76) - mind_wordmark.add_theme_font_override("font", Brand.font) - mind_wordmark.add_theme_color_override("font_color", Brand.PURPLE) - mind_wordmark.set_meta("brand_accent", true) - wordmark.add_child(mind_wordmark) + var name_row := HBoxContainer.new() + name_row.add_theme_constant_override("separation", 0) + wordmark.add_child(name_row) + var rana_wordmark := Label.new() + rana_wordmark.text = "Rana" + rana_wordmark.add_theme_font_size_override("font_size", 76) + rana_wordmark.add_theme_font_override("font", Brand.font) + name_row.add_child(rana_wordmark) + var ze_wordmark := Label.new() + ze_wordmark.text = "Ze" + ze_wordmark.add_theme_font_size_override("font_size", 76) + ze_wordmark.add_theme_font_override("font", Brand.font) + ze_wordmark.add_theme_color_override("font_color", Brand.SKY_BLUE) + ze_wordmark.set_meta("brand_accent", true) + name_row.add_child(ze_wordmark) + var trainer_wordmark := Label.new() + trainer_wordmark.text = "STEP 3 TRAINER" + trainer_wordmark.add_theme_font_size_override("font_size", 22) + trainer_wordmark.add_theme_font_override("font", Brand.font) + trainer_wordmark.add_theme_color_override("font_color", Brand.muted_color(true)) + trainer_wordmark.set_meta("brand_subtitle", true) + trainer_wordmark.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + wordmark.add_child(trainer_wordmark) brand_tagline = RichTextLabel.new() brand_tagline.bbcode_enabled = true brand_tagline.fit_content = true @@ -177,11 +187,10 @@ func _build_ui() -> void: panel_header.add_theme_constant_override("separation", 18) panel_content.add_child(panel_header) var small_icon := TextureRect.new() - small_icon.texture = preload("res://assets/branding/medmind-icon.png") + small_icon.texture = Brand.ranaze_mark_texture() small_icon.custom_minimum_size = Vector2(72, 72) small_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE small_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED - small_icon.material = Brand.logo_cutout_material() panel_header.add_child(small_icon) var titles := VBoxContainer.new() titles.size_flags_horizontal = Control.SIZE_EXPAND_FILL @@ -231,7 +240,7 @@ func _build_login_view() -> VBoxContainer: view.add_child(steam) submit_buttons.append(steam) var create := Button.new() - create.text = "New to MedMind? Create an account" + create.text = "New to RanaZe? Create an account" create.flat = true create.pressed.connect(func(): _set_mode("register")) view.add_child(create) @@ -272,12 +281,12 @@ func _build_reset_view() -> VBoxContainer: func _build_steam_view() -> VBoxContainer: var view := _new_form() var help := Label.new() - help.text = "Steam was verified. Create a MedMind account or link an existing one." + help.text = "Steam was verified. Create a RanaZe account or link an existing one." help.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART view.add_child(help) steam_action = OptionButton.new() - steam_action.add_item("Create a new MedMind account") - steam_action.add_item("Link an existing MedMind account") + steam_action.add_item("Create a new RanaZe account") + steam_action.add_item("Link an existing RanaZe account") steam_action.item_selected.connect(_on_steam_action_changed) view.add_child(steam_action) steam_username_input = _add_field(view, "Username or email", "Choose a username") @@ -405,9 +414,9 @@ func _set_mode(next_mode: String) -> void: reset_view.visible = mode == "reset" steam_view.visible = mode == "steam" match mode: - "register": heading.text = "Create your account"; subheading.text = "Start studying with MedMind" + "register": heading.text = "Create your account"; subheading.text = "Start studying with RanaZe" "reset": heading.text = "Reset your password"; subheading.text = "We will email you a verification code" - "steam": heading.text = "Finish Steam sign in"; subheading.text = "Connect Steam to MedMind" + "steam": heading.text = "Finish Steam sign in"; subheading.text = "Connect Steam to RanaZe" _: heading.text = "Welcome back"; subheading.text = "Sign in to continue" _clear_message() _update_responsive_layout() @@ -467,7 +476,9 @@ func _apply_theme() -> void: for node in find_children("*", "Label", true, false): var label := node as Label if label.has_meta("brand_accent"): - label.add_theme_color_override("font_color", Brand.PURPLE if dark else Brand.ROYAL_BLUE) + label.add_theme_color_override("font_color", Brand.SKY_BLUE if dark else Brand.ROYAL_BLUE) + elif label.has_meta("brand_subtitle"): + label.add_theme_color_override("font_color", Brand.muted_color(dark)) else: label.add_theme_color_override("font_color", Brand.text_color(dark)) for input in fields: diff --git a/scripts/ui/main.gd b/scripts/ui/main.gd index 2ddff82..581c1fd 100644 --- a/scripts/ui/main.gd +++ b/scripts/ui/main.gd @@ -358,8 +358,7 @@ func _populate_navigation(container: VBoxContainer, include_brand: bool) -> void brand_row.add_theme_constant_override("separation", 10) container.add_child(brand_row) var mark := TextureRect.new() - mark.texture = preload("res://assets/branding/medmind-icon.png") - mark.material = Brand.logo_cutout_material() + mark.texture = Brand.ranaze_mark_texture() mark.custom_minimum_size = Vector2(46, 46) mark.expand_mode = TextureRect.EXPAND_IGNORE_SIZE mark.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED @@ -367,17 +366,17 @@ func _populate_navigation(container: VBoxContainer, include_brand: bool) -> void var wordmark := HBoxContainer.new() wordmark.add_theme_constant_override("separation", 0) brand_row.add_child(wordmark) - var med := Label.new() - med.text = "Med" - med.add_theme_font_override("font", Brand.font) - med.add_theme_font_size_override("font_size", 27) - wordmark.add_child(med) - var mind := Label.new() - mind.text = "Mind" - mind.add_theme_font_override("font", Brand.font) - mind.add_theme_font_size_override("font_size", 27) - mind.add_theme_color_override("font_color", Brand.PURPLE) - wordmark.add_child(mind) + var rana := Label.new() + rana.text = "Rana" + rana.add_theme_font_override("font", Brand.font) + rana.add_theme_font_size_override("font_size", 27) + wordmark.add_child(rana) + var ze := Label.new() + ze.text = "Ze" + ze.add_theme_font_override("font", Brand.font) + ze.add_theme_font_size_override("font_size", 27) + ze.add_theme_color_override("font_color", Brand.SKY_BLUE) + wordmark.add_child(ze) container.add_child(HSeparator.new()) _add_nav_button(container, "home", "Dashboard", "chart-no-axes-column-increasing", true) @@ -391,7 +390,7 @@ func _populate_navigation(container: VBoxContainer, include_brand: bool) -> void spacer.size_flags_vertical = Control.SIZE_EXPAND_FILL container.add_child(spacer) container.add_child(HSeparator.new()) - _add_nav_button(container, "donations", "Support MedMind", "heart-pulse", true) + _add_nav_button(container, "donations", "Support RanaZe", "heart-pulse", true) _add_nav_button(container, "performance", "Profile", "user-round", true) _add_nav_button(container, "settings", "Settings", "settings", true) _add_nav_button(container, "logout", "Log out", "log-out", true) @@ -448,7 +447,7 @@ func _update_header_title(screen_name: String) -> void: "settings": "Settings", "notes": "Notes", "bookmarks": "Bookmarks", - "donations": "Support MedMind" + "donations": "Support RanaZe" } header_title.text = str(titles.get(screen_name, "")) diff --git a/scripts/ui/medmind_style.gd b/scripts/ui/medmind_style.gd index 2957486..69c86fc 100644 --- a/scripts/ui/medmind_style.gd +++ b/scripts/ui/medmind_style.gd @@ -3,9 +3,9 @@ extends RefCounted const DEEP_NAVY := Color("0b1324") const ROYAL_BLUE := Color("2563eb") const SKY_BLUE := Color("38bdf8") -const PURPLE := Color("7c3aed") -const MAGENTA := Color("d946ef") -const TEAL := Color("14b8a6") +const PURPLE := Color("1d4ed8") +const MAGENTA := Color("ef4444") +const TEAL := Color("38bdf8") const SUCCESS := Color("22c55e") const AMBER := Color("f59e0b") const SUN_ICON := preload("res://assets/icons/lucide/sun.svg") @@ -22,6 +22,13 @@ const LIGHT_MUTED := Color("64748b") static var font: Font = preload("res://assets/fonts/Inter-Variable.ttf") +static func ranaze_mark_texture() -> AtlasTexture: + var texture := AtlasTexture.new() + texture.atlas = preload("res://assets/branding/ranaze-mark.png") + texture.region = Rect2(400, 150, 736, 736) + return texture + + static func text_color(dark: bool) -> Color: return DARK_TEXT if dark else LIGHT_TEXT @@ -45,8 +52,8 @@ void fragment() { vec3 base = dark_mode ? vec3(0.018, 0.043, 0.090) : vec3(0.965, 0.975, 0.990); float left_glow = 1.0 - smoothstep(0.0, 0.58, distance(uv, vec2(-0.02, 0.12))); float right_glow = 1.0 - smoothstep(0.0, 0.58, distance(uv, vec2(1.02, 0.92))); - vec3 blue = dark_mode ? vec3(0.075, 0.055, 0.35) : vec3(0.70, 0.80, 1.0); - vec3 purple = dark_mode ? vec3(0.18, 0.035, 0.52) : vec3(0.86, 0.78, 1.0); + vec3 blue = dark_mode ? vec3(0.035, 0.16, 0.42) : vec3(0.70, 0.84, 1.0); + vec3 purple = dark_mode ? vec3(0.02, 0.28, 0.55) : vec3(0.76, 0.90, 1.0); vec3 color = base + blue * left_glow * (dark_mode ? 0.55 : 0.28); color += purple * right_glow * (dark_mode ? 0.62 : 0.12); COLOR = vec4(color, 1.0); @@ -155,7 +162,7 @@ static func badge_box(dark: bool, accent: Color) -> StyleBoxFlat: static func gradient_button_box() -> StyleBoxTexture: var gradient := Gradient.new() - gradient.colors = PackedColorArray([Color("1677ff"), Color("8f3ff4")]) + gradient.colors = PackedColorArray([ROYAL_BLUE, SKY_BLUE]) var texture := GradientTexture2D.new() texture.gradient = gradient texture.width = 512 diff --git a/scripts/ui/progress_profile.gd b/scripts/ui/progress_profile.gd index 5ad3dd2..c95b5e9 100644 --- a/scripts/ui/progress_profile.gd +++ b/scripts/ui/progress_profile.gd @@ -90,7 +90,7 @@ func _build() -> void: func _profile_summary_card() -> PanelContainer: var body := VBoxContainer.new() body.add_theme_constant_override("separation", 14) - body.add_child(_section_header("Profile Summary", "Your MedMind account")) + body.add_child(_section_header("Profile Summary", "Your RanaZe account")) var row := HBoxContainer.new() row.add_theme_constant_override("separation", 18) var avatar := PanelContainer.new() @@ -147,7 +147,7 @@ func _study_identity_card() -> PanelContainer: func _performance_card() -> PanelContainer: var body := VBoxContainer.new() body.add_theme_constant_override("separation", 12) - body.add_child(_section_header("Performance Summary", "Your cumulative MedMind activity")) + body.add_child(_section_header("Performance Summary", "Your cumulative RanaZe activity")) var grid := GridContainer.new() grid.columns = 3 grid.add_theme_constant_override("h_separation", 10) @@ -361,7 +361,7 @@ func _open_password_dialog() -> void: func _open_delete_dialog() -> void: var dialog := _dialog("Permanently delete account") - var warning := _label("This permanently removes your account and all MedMind study data. This cannot be undone.", 13, Brand.MAGENTA) + var warning := _label("This permanently removes your account and all RanaZe study data. This cannot be undone.", 13, Brand.MAGENTA) warning.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART dialog.add_field(warning) var password := _password_field("Current password") diff --git a/scripts/ui/settings_screen.gd b/scripts/ui/settings_screen.gd index c225dc7..ddde742 100644 --- a/scripts/ui/settings_screen.gd +++ b/scripts/ui/settings_screen.gd @@ -25,7 +25,7 @@ func _ready() -> void: add_child(title) var subtitle := Label.new() - subtitle.text = "Adjust MedMind's appearance and interface sounds." + subtitle.text = "Adjust RanaZe's appearance and interface sounds." subtitle.add_theme_font_override("font", Brand.font) subtitle.add_theme_font_size_override("font_size", 17) subtitle.add_theme_color_override("font_color", Brand.SLATE) diff --git a/tests/shell_navigation_test.gd b/tests/shell_navigation_test.gd index 8ca8a57..f2fd4ce 100644 --- a/tests/shell_navigation_test.gd +++ b/tests/shell_navigation_test.gd @@ -19,7 +19,7 @@ func _initialize() -> void: _assert(NavigationRoutes.key_for_screen("settings") == "settings", "settings should activate Settings") _assert(NavigationRoutes.key_for_screen("notes") == "notes", "notes should activate Notes") _assert(NavigationRoutes.key_for_screen("bookmarks") == "bookmarks", "bookmarks should activate Bookmarks") - _assert(NavigationRoutes.key_for_screen("donations") == "donations", "donations should activate Support MedMind") + _assert(NavigationRoutes.key_for_screen("donations") == "donations", "donations should activate Support RanaZe") quit(1 if failures > 0 else 0) diff --git a/tests/ui_theme_test.gd b/tests/ui_theme_test.gd index 8512237..4a069ca 100644 --- a/tests/ui_theme_test.gd +++ b/tests/ui_theme_test.gd @@ -7,6 +7,9 @@ var failures := 0 func _initialize() -> void: + _assert(ProjectSettings.get_setting("application/config/name") == "RanaZe: Step 3 Trainer", "the public application name should use the RanaZe brand") + _assert(bool(ProjectSettings.get_setting("application/config/use_custom_user_dir")), "the rebrand should preserve a stable custom user-data directory") + _assert(ProjectSettings.get_setting("application/config/custom_user_dir_name") == "MedMind", "existing standalone user data should remain discoverable after the rebrand") Style.set_dark_mode(true) var root := Control.new() var background := ColorRect.new() @@ -22,9 +25,9 @@ func _initialize() -> void: _assert(root.theme.get_color("default_color", "RichTextLabel").is_equal_approx(Style.TEXT), "rich text should use the light text color") var light_box := panel.get_theme_stylebox("panel") as StyleBoxFlat _assert(light_box.bg_color.is_equal_approx(Color("fffffe")), "custom panel surface should switch to light mode") - _assert(Brand.background_color(false).is_equal_approx(Color("f1f5f9")), "MedMind light background should match the style guide") + _assert(Brand.background_color(false).is_equal_approx(Color("f1f5f9")), "RanaZe light background should match the style guide") var light_card := Brand.content_card_box(false, true, Brand.ROYAL_BLUE) - _assert(light_card.bg_color.is_equal_approx(Color.WHITE), "MedMind light cards should use white surfaces") + _assert(light_card.bg_color.is_equal_approx(Color.WHITE), "RanaZe light cards should use white surfaces") _assert(light_card.border_color.is_equal_approx(Brand.ROYAL_BLUE), "active light cards should use the primary blue border") var light_field := Brand.field_box(false) _assert(light_field.border_color.is_equal_approx(Brand.LIGHT_BORDER), "light fields should use the semantic cool-gray border") diff --git a/tests/web_responsive_test.gd b/tests/web_responsive_test.gd index e091b46..e7a46b1 100644 --- a/tests/web_responsive_test.gd +++ b/tests/web_responsive_test.gd @@ -75,7 +75,7 @@ func _run() -> void: var profile_nav := main_screen.sidebar.find_child("NavPerformance", true, false) as Button var settings_nav := main_screen.sidebar.find_child("NavSettings", true, false) as Button var donation_nav := main_screen.sidebar.find_child("NavDonations", true, false) as Button - _assert(donation_nav != null and donation_nav.text == "Support MedMind", "the shell should expose donation navigation") + _assert(donation_nav != null and donation_nav.text == "Support RanaZe", "the shell should expose donation navigation") _assert(profile_nav != null and settings_nav != null and profile_nav.get_index() + 1 == settings_nav.get_index(), "Profile should sit directly above Settings in the lower navigation group") var theme_service = root.get_node("UIThemeService") var prior_dark_mode: bool = theme_service.is_dark_mode() diff --git a/web/Dockerfile b/web/Dockerfile index ff9e6c3..2a9fa26 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -33,12 +33,12 @@ RUN mkdir -p /build \ && sed -i "s|custom_template/release=\"\"|custom_template/release=\"/root/.local/share/godot/export_templates/${GODOT_TEMPLATE_DIR}/web_nothreads_release.zip\"|" export_presets.cfg \ && godot --headless --editor --path /src --quit \ && godot --verbose --headless --path /src --export-release Web /build/index.html \ - && cp /src/assets/branding/medmind-loader-mark.png /build/medmind-loader-icon.png \ + && cp /src/assets/branding/ranaze-mark.png /build/ranaze-loader-icon.png \ && cp /src/assets/fonts/Inter-Variable.ttf /build/medmind-inter.ttf \ && cp /src/web/donation-complete.html /build/donation-complete.html \ && cp /src/web/donation-canceled.html /build/donation-canceled.html \ && test -s /build/index.html \ - && test -s /build/medmind-loader-icon.png \ + && test -s /build/ranaze-loader-icon.png \ && test -s /build/medmind-inter.ttf \ && test -s /build/donation-complete.html \ && test -s /build/donation-canceled.html \ diff --git a/web/donation-canceled.html b/web/donation-canceled.html index 7a75d7e..29a96cb 100644 --- a/web/donation-canceled.html +++ b/web/donation-canceled.html @@ -3,7 +3,7 @@ - Checkout canceled | MedMind + Checkout canceled | RanaZe -
MedMind

Checkout canceled

No contribution was completed. You can close this tab and return to MedMind.

+
RanaZe

Checkout canceled

No contribution was completed. You can close this tab and return to RanaZe.

diff --git a/web/donation-complete.html b/web/donation-complete.html index 93bcf6e..f694d55 100644 --- a/web/donation-complete.html +++ b/web/donation-complete.html @@ -3,7 +3,7 @@ - Contribution received | MedMind + Contribution received | RanaZe -
MedMind

Thank you for supporting MedMind

Your checkout is complete.

You can close this tab and return to MedMind. Stripe will send your receipt by email.

+
RanaZe

Thank you for supporting RanaZe

Your checkout is complete.

You can close this tab and return to RanaZe. Stripe will send your receipt by email.

diff --git a/web/medmind_shell.html b/web/medmind_shell.html index 4679122..8bdcbec 100644 --- a/web/medmind_shell.html +++ b/web/medmind_shell.html @@ -32,7 +32,7 @@ :root { color-scheme: light; --background: #f8faff; - --background-accent: rgba(124, 58, 237, 0.12); + --background-accent: rgba(56, 189, 248, 0.12); --background-accent-secondary: rgba(37, 99, 235, 0.08); --dot: rgba(99, 102, 241, 0.26); --brand-dark: #0b1324; @@ -46,7 +46,7 @@ :root[data-theme="dark"] { color-scheme: dark; --background: #020b1d; - --background-accent: rgba(124, 58, 237, 0.3); + --background-accent: rgba(37, 99, 235, 0.3); --background-accent-secondary: rgba(37, 99, 235, 0.18); --dot: rgba(61, 91, 210, 0.68); --brand-dark: #f8fafc; @@ -141,19 +141,19 @@ } .corner-accent--top { - background: radial-gradient(circle at 35% 65%, rgba(124, 58, 237, 0.04), rgba(99, 102, 241, 0.13)); + background: radial-gradient(circle at 35% 65%, rgba(56, 189, 248, 0.04), rgba(37, 99, 235, 0.13)); right: max(-150px, -10vw); top: max(-180px, -13vw); } .corner-accent--bottom { - background: radial-gradient(circle at 65% 35%, rgba(124, 58, 237, 0.02), rgba(99, 102, 241, 0.1)); + background: radial-gradient(circle at 65% 35%, rgba(56, 189, 248, 0.02), rgba(37, 99, 235, 0.1)); bottom: max(-210px, -16vw); left: max(-180px, -13vw); } :root[data-theme="dark"] .corner-accent--top { - background: radial-gradient(circle at 30% 70%, rgba(124, 58, 237, 0.18), rgba(49, 46, 129, 0.72)); + background: radial-gradient(circle at 30% 70%, rgba(56, 189, 248, 0.18), rgba(30, 64, 175, 0.72)); } :root[data-theme="dark"] .corner-accent--bottom { @@ -162,6 +162,7 @@ .loader-logo-wrap { height: clamp(112px, 16vw, 154px); + overflow: hidden; position: relative; width: clamp(112px, 16vw, 154px); } @@ -170,6 +171,7 @@ display: block; height: 100%; object-fit: contain; + transform: scale(2.1); width: 100%; } @@ -181,17 +183,26 @@ margin: 12px 0 0; } - .wordmark-med { + .wordmark-rana { color: var(--brand-dark); } - .wordmark-mind { - background: linear-gradient(90deg, #2563eb 0%, #7c3aed 58%, #d946ef 100%); + .wordmark-ze { + background: linear-gradient(90deg, #2563eb 0%, #38bdf8 100%); background-clip: text; color: transparent; -webkit-background-clip: text; } + .wordmark-trainer { + color: var(--muted); + display: block; + font-size: 0.27em; + font-weight: 650; + letter-spacing: 0.12em; + margin-top: 14px; + } + .loader-tagline { color: var(--muted); font-size: clamp(20px, 2.3vw, 28px); @@ -216,7 +227,7 @@ } .progress-value { - background: linear-gradient(90deg, #2563eb 0%, #7c3aed 60%, #a855f7 100%); + background: linear-gradient(90deg, #2563eb 0%, #38bdf8 100%); border-radius: inherit; height: 100%; transform-origin: left center; @@ -309,13 +320,14 @@
- +
-
- MedMind +
+ RanaZe + STEP 3 TRAINER
-

Think like a physician.

-
+

Focused practice. Better clinical decisions.

+
0%
@@ -357,7 +369,7 @@ ? error.message : (typeof error === 'string' ? error : 'An unknown error occurred.'); statusProgress.style.display = 'none'; - statusMessage.textContent = 'MedMind could not finish loading.'; + statusMessage.textContent = 'RanaZe could not finish loading.'; statusNotice.textContent = message; statusNotice.style.display = 'block'; initializing = false; diff --git a/web/nginx.conf b/web/nginx.conf index 4fb2983..61ae1fe 100644 --- a/web/nginx.conf +++ b/web/nginx.conf @@ -43,7 +43,7 @@ server { # Godot exports reuse these filenames across releases. Revalidate them so a # newly deployed index never boots an older cached project package. - location ~ ^/(index\.(js|pck|wasm)|medmind-loader-icon\.png|medmind-inter\.ttf)$ { + location ~ ^/(index\.(js|pck|wasm)|ranaze-loader-icon\.png|medmind-inter\.ttf)$ { add_header Cache-Control "no-cache, no-store, must-revalidate" always; add_header X-Content-Type-Options "nosniff" always; try_files $uri =404;