Rebrand app as RanaZe Step 3 Trainer
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 972 KiB |
@@ -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
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
@@ -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
|
||||
@@ -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.
|
||||
|
||||
|
||||
+1
-1
@@ -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="<meta name=\"description\" content=\"MedMind pre-alpha - Think like a physician.\">"
|
||||
html/head_include="<meta name=\"description\" content=\"RanaZe: Step 3 Trainer pre-alpha - Focused practice for better clinical decisions.\">"
|
||||
html/canvas_resize_policy=2
|
||||
html/focus_canvas_on_start=true
|
||||
html/experimental_virtual_keyboard=false
|
||||
|
||||
+4
-2
@@ -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]
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = '<main id=\"medmind-checkout\" style=\"font:16px system-ui;padding:48px;color:#172033\"><strong>Opening secure checkout...</strong><p>This window will continue to Stripe.</p></main>'; medmindWaitingWindow.setInterval(function () { var checkoutUrl = medmindWaitingWindow.localStorage.getItem('%s'); if (checkoutUrl) { var checkout = medmindWaitingWindow.document.getElementById('medmind-checkout'); checkout.innerHTML = '<strong>Secure checkout is ready.</strong><p><a id=\"medmind-checkout-link\" style=\"color:#2563eb;font-weight:600\">Continue to Stripe</a></p>'; 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 = '<main id=\"medmind-checkout\" style=\"font:16px system-ui;padding:48px;color:#172033\"><strong>Opening secure checkout...</strong><p>This window will continue to Stripe.</p></main>'; medmindWaitingWindow.setInterval(function () { var checkoutUrl = medmindWaitingWindow.localStorage.getItem('%s'); if (checkoutUrl) { var checkout = medmindWaitingWindow.document.getElementById('medmind-checkout'); checkout.innerHTML = '<strong>Secure checkout is ready.</strong><p><a id=\"medmind-checkout-link\" style=\"color:#2563eb;font-weight:600\">Continue to Stripe</a></p>'; 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)
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
+36
-25
@@ -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:
|
||||
|
||||
+14
-15
@@ -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, ""))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
+2
-2
@@ -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 \
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Checkout canceled | MedMind</title>
|
||||
<title>Checkout canceled | RanaZe</title>
|
||||
<style>
|
||||
@font-face{font-family:Inter;src:url('/medmind-inter.ttf') format('truetype');font-display:swap}
|
||||
:root{color-scheme:dark light;--bg:#071224;--surface:#0b1427;--border:#33415d;--text:#f8fafc;--muted:#a9b5ca;--accent:#38bdf8}
|
||||
@@ -15,5 +15,5 @@
|
||||
</style>
|
||||
</head>
|
||||
<script>try{document.documentElement.dataset.theme=localStorage.getItem('medmind-color-scheme')||''}catch(e){}</script>
|
||||
<body><main><img src="/medmind-loader-icon.png" alt="MedMind"><h1>Checkout canceled</h1><p>No contribution was completed. You can close this tab and return to MedMind.</p></main></body>
|
||||
<body><main><img src="/ranaze-loader-icon.png" alt="RanaZe"><h1>Checkout canceled</h1><p>No contribution was completed. You can close this tab and return to RanaZe.</p></main></body>
|
||||
</html>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Contribution received | MedMind</title>
|
||||
<title>Contribution received | RanaZe</title>
|
||||
<style>
|
||||
@font-face{font-family:Inter;src:url('/medmind-inter.ttf') format('truetype');font-display:swap}
|
||||
:root{color-scheme:dark light;--bg:#071224;--surface:#0b1427;--border:#33415d;--text:#f8fafc;--muted:#a9b5ca;--accent:#38bdf8;--success:#22c55e}
|
||||
@@ -15,5 +15,5 @@
|
||||
</style>
|
||||
</head>
|
||||
<script>try{document.documentElement.dataset.theme=localStorage.getItem('medmind-color-scheme')||''}catch(e){}</script>
|
||||
<body><main><img src="/medmind-loader-icon.png" alt="MedMind"><h1>Thank you for supporting MedMind</h1><p class="status">Your checkout is complete.</p><p>You can close this tab and return to MedMind. Stripe will send your receipt by email.</p></main></body>
|
||||
<body><main><img src="/ranaze-loader-icon.png" alt="RanaZe"><h1>Thank you for supporting RanaZe</h1><p class="status">Your checkout is complete.</p><p>You can close this tab and return to RanaZe. Stripe will send your receipt by email.</p></main></body>
|
||||
</html>
|
||||
|
||||
+27
-15
@@ -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 @@
|
||||
<div class="corner-accent corner-accent--bottom"></div>
|
||||
<div class="loader">
|
||||
<div class="loader-logo-wrap">
|
||||
<img class="loader-logo" src="medmind-loader-icon.png" alt="MedMind">
|
||||
<img class="loader-logo" src="ranaze-loader-icon.png" alt="RanaZe">
|
||||
</div>
|
||||
<div class="loader-wordmark" aria-label="MedMind">
|
||||
<span class="wordmark-med">Med</span><span class="wordmark-mind">Mind</span>
|
||||
<div class="loader-wordmark" aria-label="RanaZe: Step 3 Trainer">
|
||||
<span class="wordmark-rana">Rana</span><span class="wordmark-ze">Ze</span>
|
||||
<span class="wordmark-trainer">STEP 3 TRAINER</span>
|
||||
</div>
|
||||
<p class="loader-tagline">Think like a physician.</p>
|
||||
<div id="status-progress" class="progress-row" role="progressbar" aria-label="Loading MedMind" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
|
||||
<p class="loader-tagline">Focused practice. Better clinical decisions.</p>
|
||||
<div id="status-progress" class="progress-row" role="progressbar" aria-label="Loading RanaZe" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
|
||||
<div class="progress-track"><div id="status-progress-value" class="progress-value"></div></div>
|
||||
<span id="status-progress-percent" class="progress-percent">0%</span>
|
||||
</div>
|
||||
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user