Feat: Login Screen design
This commit is contained in:
parent
e5ab751a74
commit
fa6690165d
BIN
assets/fonts/Rubik-Bold.ttf
Normal file
BIN
assets/fonts/Rubik-Bold.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/Rubik-Italic.ttf
Normal file
BIN
assets/fonts/Rubik-Italic.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/Rubik-Medium.ttf
Normal file
BIN
assets/fonts/Rubik-Medium.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/Rubik-Regular.ttf
Normal file
BIN
assets/fonts/Rubik-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/Rubik-SemiBold.ttf
Normal file
BIN
assets/fonts/Rubik-SemiBold.ttf
Normal file
Binary file not shown.
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:kmobile/features/auth/screens/mpin_screen.dart';
|
||||||
import '../features/auth/screens/login_screen.dart';
|
import '../features/auth/screens/login_screen.dart';
|
||||||
// import '../features/auth/screens/forgot_password_screen.dart';
|
// import '../features/auth/screens/forgot_password_screen.dart';
|
||||||
// import '../features/auth/screens/register_screen.dart';
|
// import '../features/auth/screens/register_screen.dart';
|
||||||
@ -15,6 +16,7 @@ class AppRoutes {
|
|||||||
// Route names
|
// Route names
|
||||||
static const String splash = '/';
|
static const String splash = '/';
|
||||||
static const String login = '/login';
|
static const String login = '/login';
|
||||||
|
static const String mPin = '/mPin';
|
||||||
static const String register = '/register';
|
static const String register = '/register';
|
||||||
static const String forgotPassword = '/forgot-password';
|
static const String forgotPassword = '/forgot-password';
|
||||||
static const String dashboard = '/dashboard';
|
static const String dashboard = '/dashboard';
|
||||||
@ -28,6 +30,9 @@ class AppRoutes {
|
|||||||
case login:
|
case login:
|
||||||
return MaterialPageRoute(builder: (_) => const LoginScreen());
|
return MaterialPageRoute(builder: (_) => const LoginScreen());
|
||||||
|
|
||||||
|
case mPin:
|
||||||
|
return MaterialPageRoute(builder: (_) => const MPinScreen());
|
||||||
|
|
||||||
case register:
|
case register:
|
||||||
// Placeholder - create the RegisterScreen class and uncomment
|
// Placeholder - create the RegisterScreen class and uncomment
|
||||||
// return MaterialPageRoute(builder: (_) => const RegisterScreen());
|
// return MaterialPageRoute(builder: (_) => const RegisterScreen());
|
||||||
|
@ -22,51 +22,61 @@ class AppThemes {
|
|||||||
fontSize: 96,
|
fontSize: 96,
|
||||||
fontWeight: FontWeight.w300,
|
fontWeight: FontWeight.w300,
|
||||||
color: Color(0xFF212121),
|
color: Color(0xFF212121),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
displayMedium: TextStyle(
|
displayMedium: TextStyle(
|
||||||
fontSize: 60,
|
fontSize: 60,
|
||||||
fontWeight: FontWeight.w300,
|
fontWeight: FontWeight.w300,
|
||||||
color: Color(0xFF212121),
|
color: Color(0xFF212121),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
displaySmall: TextStyle(
|
displaySmall: TextStyle(
|
||||||
fontSize: 48,
|
fontSize: 48,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Color(0xFF212121),
|
color: Color(0xFF212121),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
headlineMedium: TextStyle(
|
headlineMedium: TextStyle(
|
||||||
fontSize: 34,
|
fontSize: 34,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Color(0xFF212121),
|
color: Color(0xFF212121),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
headlineSmall: TextStyle(
|
headlineSmall: TextStyle(
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Color(0xFF212121),
|
color: Color(0xFF212121),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
titleLarge: TextStyle(
|
titleLarge: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Color(0xFF212121),
|
color: Color(0xFF212121),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
bodyLarge: TextStyle(
|
bodyLarge: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Color(0xFF212121),
|
color: Color(0xFF212121),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
bodyMedium: TextStyle(
|
bodyMedium: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Color(0xFF212121),
|
color: Color(0xFF212121),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
bodySmall: TextStyle(
|
bodySmall: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Color(0xFF757575),
|
color: Color(0xFF757575),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
labelLarge: TextStyle(
|
labelLarge: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Color(0xFF212121),
|
color: Color(0xFF212121),
|
||||||
|
fontFamily: 'Rubik',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -86,6 +96,7 @@ class AppThemes {
|
|||||||
// Light theme
|
// Light theme
|
||||||
static final ThemeData lightTheme = ThemeData(
|
static final ThemeData lightTheme = ThemeData(
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
|
fontFamily: 'Rubik',
|
||||||
colorScheme: const ColorScheme.light(
|
colorScheme: const ColorScheme.light(
|
||||||
primary: _primaryColorLight,
|
primary: _primaryColorLight,
|
||||||
secondary: _secondaryColorLight,
|
secondary: _secondaryColorLight,
|
||||||
@ -167,6 +178,7 @@ class AppThemes {
|
|||||||
|
|
||||||
// Dark theme
|
// Dark theme
|
||||||
static final ThemeData darkTheme = ThemeData(
|
static final ThemeData darkTheme = ThemeData(
|
||||||
|
fontFamily: 'Rubik',
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
colorScheme: const ColorScheme.dark(
|
colorScheme: const ColorScheme.dark(
|
||||||
primary: _primaryColorDark,
|
primary: _primaryColorDark,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:kmobile/features/auth/screens/mpin_screen.dart';
|
||||||
import '../controllers/auth_cubit.dart';
|
import '../controllers/auth_cubit.dart';
|
||||||
import '../controllers/auth_state.dart';
|
import '../controllers/auth_state.dart';
|
||||||
import '../../dashboard/screens/dashboard_screen.dart';
|
import '../../dashboard/screens/dashboard_screen.dart';
|
||||||
@ -13,30 +14,34 @@ class LoginScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class LoginScreenState extends State<LoginScreen> {
|
class LoginScreenState extends State<LoginScreen> {
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final _usernameController = TextEditingController();
|
final _customerNumberController = TextEditingController();
|
||||||
final _passwordController = TextEditingController();
|
final _passwordController = TextEditingController();
|
||||||
bool _obscurePassword = true;
|
bool _obscurePassword = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_usernameController.dispose();
|
_customerNumberController.dispose();
|
||||||
_passwordController.dispose();
|
_passwordController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _submitForm() {
|
void _submitForm() {
|
||||||
if (_formKey.currentState!.validate()) {
|
// if (_formKey.currentState!.validate()) {
|
||||||
context.read<AuthCubit>().login(
|
// context.read<AuthCubit>().login(
|
||||||
_usernameController.text.trim(),
|
// _customerNumberController.text.trim(),
|
||||||
_passwordController.text,
|
// _passwordController.text,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
Navigator.of(context).pushReplacement(
|
||||||
|
MaterialPageRoute(builder: (context) => const MPinScreen()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: const Text('Login')),
|
// appBar: AppBar(title: const Text('Login')),
|
||||||
body: BlocConsumer<AuthCubit, AuthState>(
|
body: BlocConsumer<AuthCubit, AuthState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is Authenticated) {
|
if (state is Authenticated) {
|
||||||
@ -56,19 +61,35 @@ class LoginScreenState extends State<LoginScreen> {
|
|||||||
key: _formKey,
|
key: _formKey,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
// crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
// Bank logo or app branding
|
// Bank logo or app branding
|
||||||
const FlutterLogo(size: 80),
|
const FlutterLogo(size: 100),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
// Title
|
||||||
|
const Text(
|
||||||
|
'KCCB',
|
||||||
|
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold, color: Colors.blue),
|
||||||
|
),
|
||||||
const SizedBox(height: 48),
|
const SizedBox(height: 48),
|
||||||
|
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _usernameController,
|
controller: _customerNumberController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Username',
|
labelText: 'Customer Number',
|
||||||
prefixIcon: Icon(Icons.person),
|
// prefixIcon: Icon(Icons.person),
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
),
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
textInputAction: TextInputAction.next,
|
textInputAction: TextInputAction.next,
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
@ -83,8 +104,17 @@ class LoginScreenState extends State<LoginScreen> {
|
|||||||
controller: _passwordController,
|
controller: _passwordController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Password',
|
labelText: 'Password',
|
||||||
prefixIcon: const Icon(Icons.lock),
|
// prefixIcon: const Icon(Icons.lock),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: const OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: const OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
_obscurePassword
|
_obscurePassword
|
||||||
@ -107,43 +137,72 @@ class LoginScreenState extends State<LoginScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
Align(
|
// Align(
|
||||||
alignment: Alignment.centerRight,
|
// alignment: Alignment.centerRight,
|
||||||
child: TextButton(
|
// child: TextButton(
|
||||||
onPressed: () {
|
// onPressed: () {
|
||||||
// Navigate to forgot password screen
|
// // Navigate to forgot password screen
|
||||||
},
|
// },
|
||||||
child: const Text('Forgot Password?'),
|
// child: const Text('Forgot Password?'),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
|
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
ElevatedButton(
|
SizedBox(
|
||||||
|
width: 250,
|
||||||
|
child: ElevatedButton(
|
||||||
onPressed: state is AuthLoading ? null : _submitForm,
|
onPressed: state is AuthLoading ? null : _submitForm,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const StadiumBorder(),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
foregroundColor: Colors.blueAccent,
|
||||||
|
side: const BorderSide(color: Colors.black, width: 1),
|
||||||
|
elevation: 0
|
||||||
),
|
),
|
||||||
child: state is AuthLoading
|
child: state is AuthLoading
|
||||||
? const CircularProgressIndicator()
|
? const CircularProgressIndicator()
|
||||||
: const Text('LOGIN', style: TextStyle(fontSize: 16)),
|
: const Text('Login', style: TextStyle(fontSize: 16),),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 15),
|
||||||
|
|
||||||
// Registration option
|
// OR Divider
|
||||||
Row(
|
const Padding(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
const Text("Don't have an account?"),
|
Expanded(child: Divider()),
|
||||||
TextButton(
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
child: Text('OR'),
|
||||||
|
),
|
||||||
|
Expanded(child: Divider()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
|
||||||
|
// Register Button
|
||||||
|
SizedBox(
|
||||||
|
width: 250,
|
||||||
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// Navigate to registration screen
|
// Handle register
|
||||||
},
|
},
|
||||||
|
style: OutlinedButton.styleFrom(
|
||||||
|
shape: const StadiumBorder(),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
backgroundColor: Colors.lightBlue[100],
|
||||||
|
foregroundColor: Colors.black
|
||||||
|
),
|
||||||
child: const Text('Register'),
|
child: const Text('Register'),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
121
lib/features/auth/screens/mpin_screen.dart
Normal file
121
lib/features/auth/screens/mpin_screen.dart
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class MPinScreen extends StatefulWidget {
|
||||||
|
const MPinScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
MPinScreenState createState() => MPinScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class MPinScreenState extends State<MPinScreen> {
|
||||||
|
List<String> mPin = [];
|
||||||
|
|
||||||
|
void addDigit(String digit) {
|
||||||
|
if (mPin.length < 4) {
|
||||||
|
setState(() {
|
||||||
|
mPin.add(digit);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteDigit() {
|
||||||
|
if (mPin.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
mPin.removeLast();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildMPinDots() {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: List.generate(4, (index) {
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.all(8),
|
||||||
|
width: 15,
|
||||||
|
height: 15,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: index < mPin.length ? Colors.black : Colors.grey[400],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildNumberPad() {
|
||||||
|
List<List<String>> keys = [
|
||||||
|
['1', '2', '3'],
|
||||||
|
['4', '5', '6'],
|
||||||
|
['7', '8', '9'],
|
||||||
|
['', '0', '<']
|
||||||
|
];
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: keys.map((row) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: row.map((key) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (key == '<') {
|
||||||
|
deleteDigit();
|
||||||
|
} else if (key.isNotEmpty) {
|
||||||
|
addDigit(key);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 70,
|
||||||
|
height: 70,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: Colors.grey[200],
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
key == '<' ? '⌫' : key,
|
||||||
|
style: const TextStyle(fontSize: 24),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: SafeArea(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Spacer(),
|
||||||
|
// Logo
|
||||||
|
const FlutterLogo(size: 100),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
const Text(
|
||||||
|
"Enter your mPIN",
|
||||||
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
buildMPinDots(),
|
||||||
|
const Spacer(),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
TextButton(onPressed: () {}, child: const Text("Try another way")),
|
||||||
|
TextButton(onPressed: () {}, child: const Text("Register?")),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
buildNumberPad(),
|
||||||
|
const Spacer(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -292,10 +292,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: "0ca7359dad67fd7063cb2892ab0c0737b2daafd807cf1acecd62374c8fae6c12"
|
sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.16"
|
version: "2.2.17"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
11
pubspec.yaml
11
pubspec.yaml
@ -81,11 +81,12 @@ flutter:
|
|||||||
# "family" key with the font family name, and a "fonts" key with a
|
# "family" key with the font family name, and a "fonts" key with a
|
||||||
# list giving the asset and other descriptors for the font. For
|
# list giving the asset and other descriptors for the font. For
|
||||||
# example:
|
# example:
|
||||||
# fonts:
|
fonts:
|
||||||
# - family: Schyler
|
- family: Rubik
|
||||||
# fonts:
|
fonts:
|
||||||
# - asset: fonts/Schyler-Regular.ttf
|
- asset: assets/fonts/Rubik-Regular.ttf
|
||||||
# - asset: fonts/Schyler-Italic.ttf
|
- asset: assets/fonts/Rubik-Bold.ttf
|
||||||
|
weight: 700
|
||||||
# style: italic
|
# style: italic
|
||||||
# - family: Trajan Pro
|
# - family: Trajan Pro
|
||||||
# fonts:
|
# fonts:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user