diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1c0060c..d32ffe6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -41,6 +41,7 @@ diff --git a/img/goblinpay-badge-black.svg b/img/goblinpay-badge-black.svg new file mode 100644 index 0000000..bbef89a --- /dev/null +++ b/img/goblinpay-badge-black.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + Pay + diff --git a/img/goblinpay-wordmark.svg b/img/goblinpay-wordmark.svg new file mode 100644 index 0000000..2248bf2 --- /dev/null +++ b/img/goblinpay-wordmark.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + diff --git a/src/gui/views/camera.rs b/src/gui/views/camera.rs index 70879f8..5570bed 100644 --- a/src/gui/views/camera.rs +++ b/src/gui/views/camera.rs @@ -473,11 +473,11 @@ mod tests { use super::*; /// Render a QR the way the goblin receive card paints it (dark modules - /// on a white plate with ~5% padding, goblin mark covering the center) - /// and prove the camera scanner pipeline (rqrr) decodes it. Guards both - /// the scan path and the card's scannability by third-party apps. + /// on a white plate with ~5% padding, plain — no center mark) and prove + /// the camera scanner pipeline (rqrr) decodes it. Guards both the scan + /// path and the card's scannability by third-party apps. #[test] - fn goblin_receive_qr_decodes_with_center_mark() { + fn goblin_receive_qr_decodes() { let uri = "nostr:npub15l60z00nm4ptmnsj9lcp4husnaltytw85eu05dt7ksdmsje0p98su2f0ch"; let qr = qrcodegen::QrCode::encode_text(uri, qrcodegen::QrCodeEcc::High).unwrap(); let n = qr.size(); @@ -502,11 +502,6 @@ mod tests { } } } - // The goblin mark backing square over the center modules. - let backing = size * 0.19; - let c = dim as f32 / 2.0; - fill(c - backing / 2.0, c - backing / 2.0, backing, backing, 255); - let mut prepared = rqrr::PreparedImage::prepare(img); let grids = prepared.detect_grids(); assert_eq!(grids.len(), 1, "scanner should find exactly one QR"); diff --git a/src/gui/views/goblin/mod.rs b/src/gui/views/goblin/mod.rs index 67554ae..3c5edb6 100644 --- a/src/gui/views/goblin/mod.rs +++ b/src/gui/views/goblin/mod.rs @@ -1431,11 +1431,13 @@ impl GoblinWalletView { .unwrap_or_else(|| ("N".to_string(), String::new())); let header_tex = self.handle_tex(ui.ctx(), wallet, &header_handle); ui.horizontal(|ui| { - widgets_logo(ui); - ui.add_space(8.0); + // Owner-sized: +50% over the original 24px mark so the lockup + // carries the same visual weight as the 40-44px right cluster. + widgets_logo_sized(ui, 36.0); + ui.add_space(9.0); ui.label( RichText::new("goblin") - .font(FontId::new(18.0, fonts::bold())) + .font(FontId::new(26.0, fonts::bold())) .color(theme::tokens().text), ); ui.with_layout(Layout::right_to_left(Align::Center), |ui| { @@ -1663,12 +1665,23 @@ impl GoblinWalletView { .unwrap_or_else(|| ("N".to_string(), String::new())); let header_tex = self.handle_tex(ui.ctx(), wallet, &header_handle); ui.horizontal(|ui| { - // Goblin mark (left), sized to match the right-side controls. - ui.add( - egui::Image::new(egui::include_image!("../../../../img/goblin-logo2.svg")) - .tint(t.text) - .fit_to_exact_size(Vec2::splat(40.0)), - ); + // Official GoblinPay lockup (left): the black Apple-Pay-style badge on + // light surfaces, the white wordmark on dark. Owner-specified brand mark. + if t.dark_base { + ui.add( + egui::Image::new(egui::include_image!( + "../../../../img/goblinpay-wordmark.svg" + )) + .fit_to_exact_size(Vec2::new(84.0, 33.0)), + ); + } else { + ui.add( + egui::Image::new(egui::include_image!( + "../../../../img/goblinpay-badge-black.svg" + )) + .fit_to_exact_size(Vec2::new(98.0, 40.0)), + ); + } // Right cluster: scan QR (black, no background) then the profile // picture at the far right; all three controls about the same size. ui.with_layout(Layout::right_to_left(Align::Center), |ui| { diff --git a/src/gui/views/goblin/widgets.rs b/src/gui/views/goblin/widgets.rs index fb5996d..5119af0 100644 --- a/src/gui/views/goblin/widgets.rs +++ b/src/gui/views/goblin/widgets.rs @@ -402,7 +402,7 @@ pub fn chip(ui: &mut Ui, label: &str, active: bool) -> Response { pub fn qr_code(ui: &mut Ui, text: &str, size: f32) { let plate = Color32::WHITE; let ink = Color32::from_rgb(0x0E, 0x0E, 0x0C); - // High error correction tolerates the center mark covering modules. + // Plain QR (no center mark): High ECC retained for robust scanning. let Ok(qr) = qrcodegen::QrCode::encode_text(text, qrcodegen::QrCodeEcc::High) else { return; }; @@ -429,19 +429,6 @@ pub fn qr_code(ui: &mut Ui, text: &str, size: f32) { } } } - // Goblin mark on a yellow backing square in the center, 19% footprint (larger - // obscures too many modules for a reliable decode). Yellow reads as "light" to - // a scanner like white, so the covered center is recovered by the High ECC. - let t = theme::tokens(); - let backing = size * 0.19; - let b_rect = egui::Rect::from_center_size(rect.center(), Vec2::splat(backing)); - ui.painter() - .rect_filled(b_rect, CornerRadius::same((backing * 0.18) as u8), t.accent); - let m_rect = egui::Rect::from_center_size(rect.center(), Vec2::splat(backing * 0.72)); - egui::Image::new(egui::include_image!("../../../../img/goblin-logo2.svg")) - .tint(t.accent_ink) - .fit_to_exact_size(m_rect.size()) - .paint_at(ui, m_rect); } /// A filled input well for a text field sitting on a card, so the field