design: modernize Material 3 UI with drawer navigation and richer teal theme

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Andrew Ridgway 2026-08-04 23:49:37 +10:00
parent 54b002b72f
commit 5754fcf445
Signed by: armistace
GPG Key ID: C8D9EAC514B47EF1
21 changed files with 738 additions and 456 deletions

View File

@ -5,7 +5,6 @@ import android.graphics.PorterDuff
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.ImageView
@ -13,18 +12,21 @@ import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.drawerlayout.widget.DrawerLayout
import com.example.resbuilder.R
import com.example.resbuilder.data.model.User
import com.example.resbuilder.data.remote.ApiClient
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.tabs.TabLayout
import com.google.android.material.navigation.NavigationView
class MainActivity : AppCompatActivity(), JobFormFragment.JobFormListener, ResultFragment.OnNewListener {
private lateinit var drawerLayout: DrawerLayout
private lateinit var toolbar: MaterialToolbar
private lateinit var tabLayout: TabLayout
private lateinit var navView: NavigationView
private lateinit var healthIndicator: ImageView
private lateinit var userName: TextView
private lateinit var userEmail: TextView
private lateinit var usageBanner: TextView
private val handler = Handler(Looper.getMainLooper())
@ -32,43 +34,65 @@ class MainActivity : AppCompatActivity(), JobFormFragment.JobFormListener, Resul
private var healthRunnable: Runnable? = null
companion object {
private const val TAB_RESUME = 0
private const val TAB_COVER = 1
private const val NAV_BUILD_RESUME = 0
private const val NAV_BUILD_COVER_LETTER = 1
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
drawerLayout = findViewById(R.id.drawerLayout)
toolbar = findViewById(R.id.toolbar)
tabLayout = findViewById(R.id.tabLayout)
healthIndicator = findViewById(R.id.healthIndicator)
userName = findViewById(R.id.userName)
navView = findViewById(R.id.navView)
usageBanner = findViewById(R.id.usageBanner)
val header = navView.getHeaderView(0)
healthIndicator = header.findViewById(R.id.healthIndicator)
userName = header.findViewById(R.id.userName)
userEmail = header.findViewById(R.id.userEmail)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_menu_hamburger)
tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_build_resume))
tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_build_cover_letter))
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
switchFormTab(tab?.position ?: TAB_RESUME)
navView.setNavigationItemSelectedListener { item ->
drawerLayout.closeDrawers()
handleNavItem(item.itemId)
true
}
override fun onTabUnselected(tab: TabLayout.Tab?) {}
override fun onTabReselected(tab: TabLayout.Tab?) {
switchFormTab(tab?.position ?: TAB_RESUME)
}
})
loadUser()
startHealthPolling()
if (savedInstanceState == null) {
switchFormTab(TAB_RESUME)
showBuildForm(NAV_BUILD_RESUME)
}
}
private fun handleNavItem(itemId: Int) {
when (itemId) {
R.id.navBuildResume -> showBuildForm(NAV_BUILD_RESUME)
R.id.navBuildCoverLetter -> showBuildForm(NAV_BUILD_COVER_LETTER)
R.id.navMyResumes -> showMyResumes()
R.id.navAdmin -> startActivity(Intent(this, AdminActivity::class.java))
R.id.navSignOut -> signOut()
}
}
private fun showBuildForm(position: Int) {
val type = if (position == NAV_BUILD_COVER_LETTER) JobFormFragment.TYPE_COVER_LETTER else JobFormFragment.TYPE_RESUME
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, JobFormFragment.newInstance(type))
.commitAllowingStateLoss()
}
private fun showMyResumes() {
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, MyResumesFragment())
.addToBackStack(null)
.commitAllowingStateLoss()
}
private fun loadUser() {
Thread {
try {
@ -86,20 +110,13 @@ class MainActivity : AppCompatActivity(), JobFormFragment.JobFormListener, Resul
private fun updateUserUI() {
userName.text = user.name ?: user.email ?: getString(R.string.unknown_user)
if (!user.authenticated || (!user.is_admin && !user.can_submit)) {
usageBanner.visibility = View.VISIBLE
userEmail.text = user.email ?: getString(R.string.unknown_email)
usageBanner.visibility = if (!user.authenticated || (!user.is_admin && !user.can_submit)) {
View.VISIBLE
} else {
usageBanner.visibility = View.GONE
View.GONE
}
invalidateOptionsMenu()
}
private fun switchFormTab(position: Int) {
val type = if (position == TAB_COVER) JobFormFragment.TYPE_COVER_LETTER else JobFormFragment.TYPE_RESUME
val fragment = JobFormFragment.newInstance(type)
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, fragment)
.commitAllowingStateLoss()
navView.menu.findItem(R.id.navAdmin)?.isVisible = user.is_admin
}
private fun startHealthPolling() {
@ -130,34 +147,12 @@ class MainActivity : AppCompatActivity(), JobFormFragment.JobFormListener, Resul
}.start()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
menu?.findItem(R.id.menuAdminPanel)?.isVisible = user.is_admin
return super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menuMyResumes -> {
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, MyResumesFragment())
.addToBackStack(null)
.commitAllowingStateLoss()
return if (item.itemId == android.R.id.home) {
drawerLayout.openDrawer(navView)
true
}
R.id.menuSignOut -> {
signOut()
true
}
R.id.menuAdminPanel -> {
startActivity(Intent(this, AdminActivity::class.java))
true
}
else -> super.onOptionsItemSelected(item)
} else {
super.onOptionsItemSelected(item)
}
}
@ -183,8 +178,8 @@ class MainActivity : AppCompatActivity(), JobFormFragment.JobFormListener, Resul
fun onResultNewJob() {
supportFragmentManager.popBackStackImmediate()
tabLayout.getTabAt(TAB_RESUME)?.select()
switchFormTab(TAB_RESUME)
navView.menu.getItem(NAV_BUILD_RESUME)?.isChecked = true
showBuildForm(NAV_BUILD_RESUME)
}
override fun onNewJob() {

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="270"
android:angle="135"
android:startColor="?attr/colorPrimary"
android:centerColor="?attr/colorPrimaryInverse"
android:endColor="?attr/colorPrimaryContainer"
android:type="linear" />
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="270"
android:startColor="?attr/colorPrimary"
android:centerColor="?attr/colorPrimaryInverse"
android:endColor="?attr/colorPrimaryContainer"
android:type="linear" />
</shape>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorOnSurfaceVariant"
android:pathData="M14,2H6C4.9,2 4,2.9 4,4V20C4,21.1 4.9,22 6,22H18C19.1,22 20,21.1 20,20V8L14,2M13,9V3.5L18.5,9H13Z" />
</vector>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorOnSurface">
<path
android:fillColor="?attr/colorOnSurface"
android:pathData="M3,6h18v2H3V6zM3,11h18v2H3v-2zM3,16h18v2H3v-2z" />
</vector>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorOnPrimary"
android:pathData="M12,2L13.5,9.5L21,12L13.5,14.5L12,22L10.5,14.5L3,12L10.5,9.5L12,2Z" />
</vector>

View File

@ -7,7 +7,7 @@
android:background="?attr/colorSurface"
tools:context=".ui.LoginActivity">
<!-- Decorative background element -->
<!-- Decorative gradient background behind card -->
<View
android:layout_width="0dp"
android:layout_height="0dp"
@ -17,21 +17,32 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginEnd="@dimen/space_lg"
android:layout_marginBottom="@dimen/space_lg"
android:alpha="0.15"
android:contentDescription="@null"
android:src="@drawable/ic_sparkle"
app:layout_constraintBottom_toTopOf="@id/guidelineTop"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.35" />
app:layout_constraintGuide_percent="0.40" />
<!-- Main content card -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/loginCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
app:cardBackgroundColor="?attr/colorSurfaceContainer"
app:cardCornerRadius="24dp"
android:layout_marginHorizontal="@dimen/space_lg"
app:cardBackgroundColor="?attr/colorSurfaceContainerLow"
app:cardCornerRadius="@dimen/card_radius_large"
app:cardElevation="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@ -46,21 +57,22 @@
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="32dp">
android:padding="@dimen/space_xl">
<!-- App icon with elevation -->
<!-- App icon with tonal surface -->
<com.google.android.material.card.MaterialCardView
android:layout_width="88dp"
android:layout_height="88dp"
android:layout_width="@dimen/space_xxl"
android:layout_height="@dimen/space_xxl"
app:cardBackgroundColor="?attr/colorPrimaryContainer"
app:cardCornerRadius="22dp"
app:cardElevation="4dp">
app:cardCornerRadius="@dimen/card_radius_large"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/cd_app_logo"
android:padding="20dp"
android:padding="@dimen/space_md"
android:scaleType="centerInside"
android:src="@drawable/ic_launcher_foreground"
app:tint="?attr/colorOnPrimaryContainer" />
@ -71,7 +83,7 @@
android:id="@+id/loginTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginTop="@dimen/space_lg"
android:text="@string/app_title"
android:textAlignment="center"
android:textAppearance="?attr/textAppearanceHeadlineMedium"
@ -83,7 +95,7 @@
android:id="@+id/loginSubtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginTop="@dimen/space_sm"
android:text="@string/welcome_subtitle"
android:textAlignment="center"
android:textAppearance="?attr/textAppearanceBodyLarge"
@ -93,16 +105,17 @@
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginVertical="24dp"
android:layout_marginVertical="@dimen/space_lg"
android:background="?attr/colorOutlineVariant" />
<!-- Sign in button container -->
<!-- Sign in button -->
<com.google.android.material.button.MaterialButton
android:id="@+id/googleSignInButton"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="56dp"
android:fontFamily="sans-serif-medium"
android:minHeight="@dimen/button_height"
android:text="@string/sign_in_with_google"
android:textAllCaps="false"
android:textColor="?attr/colorOnSurface"
@ -110,7 +123,7 @@
app:cornerRadius="14dp"
app:icon="@drawable/ic_google"
app:iconGravity="textStart"
app:iconPadding="12dp"
app:iconPadding="@dimen/space_md"
app:iconSize="24dp"
app:iconTint="@null"
app:strokeColor="?attr/colorOutline"
@ -120,7 +133,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginTop="@dimen/space_md"
android:text="@string/sign_in_terms"
android:textAlignment="center"
android:textAppearance="?attr/textAppearanceBodySmall"
@ -136,7 +149,7 @@
android:indeterminate="true"
android:visibility="gone"
app:indicatorColor="?attr/colorOnPrimary"
app:indicatorSize="48dp"
app:indicatorSize="@dimen/space_xxl"
app:layout_constraintBottom_toTopOf="@id/loginCard"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@ -1,105 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:fitsSystemWindows="true"
tools:context=".ui.MainActivity">
<!-- Main content -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Modern colored app bar with gradient surface and centered title -->
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true"
app:elevation="0dp"
app:liftOnScroll="false">
app:elevation="0dp">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorSurface"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|enterAlways|snap"
android:background="@drawable/bg_gradient_primary_bottom"
android:elevation="0dp"
app:navigationIcon="@drawable/ic_menu_hamburger"
app:navigationIconTint="?attr/colorOnPrimary"
app:title="@string/app_title"
app:titleCentered="true"
app:titleTextAppearance="?attr/textAppearanceTitleLarge"
app:titleTextColor="?attr/colorOnSurface">
<LinearLayout
android:id="@+id/healthContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="16dp"
android:background="?attr/colorSurfaceContainer"
android:gravity="center_vertical"
android:minHeight="32dp"
android:orientation="horizontal"
android:paddingHorizontal="12dp"
android:paddingVertical="4dp">
<ImageView
android:id="@+id/healthIndicator"
android:layout_width="12dp"
android:layout_height="12dp"
android:contentDescription="@string/cd_health_indicator"
android:src="@drawable/ic_circle_status" />
<TextView
android:id="@+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/unknown_user"
android:textAppearance="?attr/textAppearanceLabelMedium"
android:textColor="?attr/colorOnSurface" />
</LinearLayout>
</com.google.android.material.appbar.MaterialToolbar>
app:titleTextColor="?attr/colorOnPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<TextView
android:id="@+id/usageBanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="8dp"
android:layout_marginHorizontal="@dimen/space_md"
android:layout_marginTop="@dimen/space_sm"
android:background="@drawable/bg_banner_warning"
android:drawableStart="@drawable/ic_circle_status"
android:drawableTint="?attr/colorWarning"
android:gravity="center_vertical"
android:minHeight="48dp"
android:padding="12dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:minHeight="@dimen/touch_target_min"
android:padding="@dimen/space_sm"
android:text="@string/usage_limit_banner"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?attr/colorOnSurface"
android:visibility="gone"
tools:visibility="visible" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
android:contentDescription="@string/app_title"
app:tabBackground="?attr/colorSurface"
app:tabGravity="fill"
app:tabIndicatorColor="?attr/colorPrimary"
app:tabMode="fixed"
app:tabTextAppearance="?attr/textAppearanceLabelLarge"
app:tabTextColor="?attr/colorOnSurfaceVariant"
app:tabSelectedTextColor="?attr/colorOnSurface" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
android:background="?attr/colorSurface" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- Navigation drawer with richer surface and modern item styling -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/navView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="?attr/colorSurfaceContainerLowest"
app:headerLayout="@layout/nav_header"
app:itemHorizontalPadding="@dimen/space_md"
app:itemIconPadding="@dimen/space_md"
app:itemIconTint="?attr/colorOnSurfaceVariant"
app:itemRippleColor="?attr/colorPrimaryContainer"
app:itemTextAppearance="?attr/textAppearanceBodyLarge"
app:itemTextColor="?attr/colorOnSurface"
app:itemVerticalPadding="@dimen/space_md"
app:menu="@menu/menu_nav_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@ -6,18 +6,67 @@
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:fillViewport="true"
android:clipToPadding="false"
android:paddingBottom="@dimen/space_md"
tools:context=".ui.JobFormFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
android:orientation="vertical">
<!-- Hero header with gradient surface and section title -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_gradient_primary"
android:minHeight="@dimen/hero_header_min_height"
android:padding="@dimen/space_lg">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="top|end"
android:alpha="0.25"
android:contentDescription="@null"
android:src="@drawable/ic_sparkle" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_title"
android:textAppearance="?attr/textAppearanceLabelMedium"
android:textColor="?attr/colorOnPrimary"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/space_xs"
android:text="@string/hint_job_title"
android:textAppearance="?attr/textAppearanceHeadlineMedium"
android:textColor="?attr/colorOnPrimary" />
</LinearLayout>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/space_md">
<!-- Job details card -->
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="12dp"
app:cardBackgroundColor="?attr/colorSurfaceContainerLow"
app:cardCornerRadius="@dimen/card_radius"
app:cardElevation="0dp"
app:strokeColor="?attr/colorOutlineVariant"
app:strokeWidth="1dp">
@ -26,7 +75,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
android:padding="@dimen/space_md">
<TextView
android:layout_width="wrap_content"
@ -38,24 +87,26 @@
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginTop="@dimen/space_sm"
android:hint="@string/hint_job_title"
app:boxBackgroundColor="?attr/colorSurfaceContainer"
app:hintTextColor="?attr/colorOnSurfaceVariant"
style="@style/Widget.Material3.TextInputLayout.FilledBox">
style="@style/Widget.Material3.TextInputLayout.FilledBox"
app:boxBackgroundColor="?attr/colorSurfaceContainerHighest"
app:boxStrokeColor="?attr/colorPrimary"
app:cursorColor="?attr/colorPrimary"
app:hintTextColor="?attr/colorOnSurfaceVariant">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/jobTitleInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:minHeight="48dp" />
android:minHeight="@dimen/touch_target_min" />
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginTop="@dimen/space_sm"
android:baselineAligned="false"
android:orientation="horizontal">
@ -64,24 +115,26 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/hint_seek_url"
app:boxBackgroundColor="?attr/colorSurfaceContainer"
app:hintTextColor="?attr/colorOnSurfaceVariant"
style="@style/Widget.Material3.TextInputLayout.FilledBox">
style="@style/Widget.Material3.TextInputLayout.FilledBox"
app:boxBackgroundColor="?attr/colorSurfaceContainerHighest"
app:boxStrokeColor="?attr/colorPrimary"
app:cursorColor="?attr/colorPrimary"
app:hintTextColor="?attr/colorOnSurfaceVariant">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/seekUrlInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:minHeight="48dp" />
android:minHeight="@dimen/touch_target_min" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/scrapeButton"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_height="@dimen/button_height"
android:layout_marginStart="@dimen/space_sm"
android:contentDescription="@string/cd_scrape_job"
android:minWidth="64dp"
android:text="@string/button_scrape" />
@ -90,11 +143,13 @@
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginTop="@dimen/space_md"
android:hint="@string/hint_job_description"
app:boxBackgroundColor="?attr/colorSurfaceContainer"
app:hintTextColor="?attr/colorOnSurfaceVariant"
style="@style/Widget.Material3.TextInputLayout.FilledBox">
style="@style/Widget.Material3.TextInputLayout.FilledBox"
app:boxBackgroundColor="?attr/colorSurfaceContainerHighest"
app:boxStrokeColor="?attr/colorPrimary"
app:cursorColor="?attr/colorPrimary"
app:hintTextColor="?attr/colorOnSurfaceVariant">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/jobDescriptionInput"
@ -102,16 +157,19 @@
android:layout_height="wrap_content"
android:gravity="top"
android:inputType="textMultiLine"
android:minLines="4" />
android:minLines="4"
android:minHeight="@dimen/touch_target_min" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<!-- Resume / cover letter input card -->
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
app:cardCornerRadius="12dp"
android:layout_marginTop="@dimen/space_md"
app:cardBackgroundColor="?attr/colorSurfaceContainerLow"
app:cardCornerRadius="@dimen/card_radius"
app:cardElevation="0dp"
app:strokeColor="?attr/colorOutlineVariant"
app:strokeWidth="1dp">
@ -120,7 +178,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
android:padding="@dimen/space_md">
<LinearLayout
android:layout_width="match_parent"
@ -141,7 +199,7 @@
android:id="@+id/uploadButton"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_height="@dimen/button_height"
android:contentDescription="@string/cd_upload_document"
android:text="@string/button_upload" />
</LinearLayout>
@ -150,11 +208,13 @@
android:id="@+id/docInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginTop="@dimen/space_sm"
android:hint="@string/hint_your_resume"
app:boxBackgroundColor="?attr/colorSurfaceContainer"
app:hintTextColor="?attr/colorOnSurfaceVariant"
style="@style/Widget.Material3.TextInputLayout.FilledBox">
style="@style/Widget.Material3.TextInputLayout.FilledBox"
app:boxBackgroundColor="?attr/colorSurfaceContainerHighest"
app:boxStrokeColor="?attr/colorPrimary"
app:cursorColor="?attr/colorPrimary"
app:hintTextColor="?attr/colorOnSurfaceVariant">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/docInput"
@ -162,7 +222,8 @@
android:layout_height="wrap_content"
android:gravity="top"
android:inputType="textMultiLine"
android:minLines="6" />
android:minLines="6"
android:minHeight="@dimen/touch_target_min" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
@ -170,18 +231,19 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/submitButton"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="16dp"
android:layout_height="@dimen/button_height"
android:layout_marginTop="@dimen/space_md"
android:text="@string/generate_resume" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_width="@dimen/space_xxl"
android:layout_height="@dimen/space_xxl"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:layout_marginTop="@dimen/space_md"
android:contentDescription="@string/cd_loading"
android:indeterminateTint="?attr/colorPrimary"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -7,14 +7,15 @@
android:background="?attr/colorSurface"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp">
android:padding="@dimen/space_md">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="8dp"
app:cardCornerRadius="12dp"
android:layout_marginHorizontal="@dimen/space_md"
android:layout_marginVertical="@dimen/space_sm"
app:cardBackgroundColor="?attr/colorSurfaceContainerLow"
app:cardCornerRadius="@dimen/card_radius_large"
app:cardElevation="0dp"
app:strokeColor="?attr/colorOutlineVariant"
app:strokeWidth="1dp">
@ -24,27 +25,36 @@
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="24dp">
android:padding="@dimen/space_lg">
<!-- Status badge: now a tonal chip-style pill -->
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="?attr/colorPrimaryContainer"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<TextView
android:id="@+id/statusBadge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_status_badge"
android:contentDescription="@string/status_queued"
android:gravity="center"
android:minHeight="32dp"
android:paddingHorizontal="16dp"
android:paddingHorizontal="@dimen/space_md"
android:paddingVertical="4dp"
android:text="@string/status_queued"
android:textAppearance="?attr/textAppearanceLabelLarge"
android:textColor="?attr/colorOnPrimary" />
android:textColor="?attr/colorOnPrimaryContainer" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/statusProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginTop="@dimen/space_lg"
android:contentDescription="@string/content_generation_running"
android:indeterminate="true"
app:indicatorColor="?attr/colorPrimary"
@ -54,7 +64,7 @@
android:id="@+id/statusMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginTop="@dimen/space_md"
android:gravity="center"
android:text="@string/job_wait_message"
android:textAppearance="?attr/textAppearanceBodyLarge"
@ -64,7 +74,7 @@
android:id="@+id/statusDetail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginTop="@dimen/space_sm"
android:gravity="center"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
@ -74,8 +84,8 @@
android:id="@+id/tryAgainButton"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginTop="24dp"
android:layout_height="@dimen/button_height"
android:layout_marginTop="@dimen/space_lg"
android:minWidth="120dp"
android:text="@string/try_again"
android:visibility="gone" />

View File

@ -5,24 +5,55 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:orientation="vertical"
android:padding="16dp">
android:orientation="vertical">
<!-- Hero header for list screen -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_gradient_primary"
android:minHeight="@dimen/hero_header_min_height"
android:padding="@dimen/space_lg">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="top|end"
android:alpha="0.25"
android:contentDescription="@null"
android:src="@drawable/ic_sparkle" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_title"
android:textAppearance="?attr/textAppearanceLabelMedium"
android:textColor="?attr/colorOnPrimary"
android:textStyle="bold" />
<TextView
android:id="@+id/myResumesTitle"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="4dp"
android:paddingBottom="8dp"
android:layout_marginTop="@dimen/space_xs"
android:text="@string/my_resumes_title"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textColor="?attr/colorOnSurface" />
android:textAppearance="?attr/textAppearanceHeadlineMedium"
android:textColor="?attr/colorOnPrimary" />
</LinearLayout>
</FrameLayout>
<TextView
android:id="@+id/myResumesEmpty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginHorizontal="@dimen/space_md"
android:layout_marginTop="@dimen/space_xl"
android:gravity="center"
android:text="@string/my_resumes_empty"
android:textAppearance="?attr/textAppearanceBodyLarge"
@ -34,7 +65,7 @@
android:id="@+id/myResumesProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginTop="@dimen/space_md"
android:indeterminate="true"
android:visibility="gone"
app:indicatorColor="?attr/colorPrimary"
@ -45,9 +76,12 @@
android:id="@+id/myResumesList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginHorizontal="@dimen/space_md"
android:layout_marginTop="@dimen/space_md"
android:clipToPadding="false"
android:divider="@null"
android:listSelector="@android:color/transparent"
android:paddingBottom="@dimen/space_md"
android:visibility="gone"
tools:visibility="visible" />

View File

@ -8,13 +8,15 @@
android:orientation="vertical"
tools:context=".ui.ResultFragment">
<!-- Top action bar card with tonal surface -->
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
app:cardCornerRadius="12dp"
android:layout_marginHorizontal="@dimen/space_md"
android:layout_marginTop="@dimen/space_md"
android:layout_marginBottom="@dimen/space_sm"
app:cardBackgroundColor="?attr/colorSurfaceContainerLow"
app:cardCornerRadius="@dimen/card_radius"
app:cardElevation="0dp"
app:strokeColor="?attr/colorOutlineVariant"
app:strokeWidth="1dp">
@ -23,23 +25,31 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="48dp"
android:minHeight="@dimen/touch_target_min"
android:orientation="horizontal"
android:padding="12dp">
android:padding="@dimen/space_sm">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="?attr/colorSuccessContainer"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<TextView
android:id="@+id/resultBadge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_status_badge"
android:contentDescription="@string/status_completed"
android:gravity="center"
android:minHeight="32dp"
android:paddingHorizontal="12dp"
android:paddingHorizontal="@dimen/space_md"
android:paddingVertical="4dp"
android:text="@string/status_completed"
android:textAppearance="?attr/textAppearanceLabelLarge"
android:textColor="?attr/colorOnPrimary" />
android:textColor="?attr/colorOnSuccessContainer" />
</com.google.android.material.card.MaterialCardView>
<View
android:layout_width="0dp"
@ -50,7 +60,7 @@
android:id="@+id/copyButton"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_height="@dimen/button_height"
android:contentDescription="@string/cd_copy_result"
android:minWidth="64dp"
android:text="@string/copy_text" />
@ -59,8 +69,8 @@
android:id="@+id/newButton"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginStart="4dp"
android:layout_height="@dimen/button_height"
android:layout_marginStart="@dimen/space_xs"
android:contentDescription="@string/cd_new_job"
android:minWidth="64dp"
android:text="@string/new_job" />
@ -71,17 +81,19 @@
android:id="@+id/resultWebView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="16dp"
android:layout_marginHorizontal="@dimen/space_md"
android:layout_weight="1"
android:contentDescription="@string/result_preview" />
<!-- Export action bar with tonal surface -->
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
app:cardCornerRadius="12dp"
android:layout_marginHorizontal="@dimen/space_md"
android:layout_marginTop="@dimen/space_sm"
android:layout_marginBottom="@dimen/space_md"
app:cardBackgroundColor="?attr/colorSurfaceContainerLow"
app:cardCornerRadius="@dimen/card_radius"
app:cardElevation="0dp"
app:strokeColor="?attr/colorOutlineVariant"
app:strokeWidth="1dp">
@ -90,14 +102,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="12dp">
android:padding="@dimen/space_sm">
<com.google.android.material.button.MaterialButton
android:id="@+id/pdfButton"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginEnd="8dp"
android:layout_height="@dimen/button_height"
android:layout_marginEnd="@dimen/space_sm"
android:layout_weight="1"
android:contentDescription="@string/cd_export_pdf"
android:text="@string/export_pdf" />
@ -106,8 +118,8 @@
android:id="@+id/docxButton"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_height="@dimen/button_height"
android:layout_marginStart="@dimen/space_sm"
android:layout_weight="1"
android:contentDescription="@string/cd_export_docx"
android:text="@string/export_docx" />

View File

@ -4,17 +4,45 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="6dp"
app:cardCornerRadius="12dp"
android:layout_marginVertical="@dimen/space_sm"
app:cardBackgroundColor="?attr/colorSurfaceContainerLow"
app:cardCornerRadius="@dimen/card_radius"
app:cardElevation="0dp"
app:rippleColor="?attr/colorPrimaryContainer"
app:strokeColor="?attr/colorOutlineVariant"
app:strokeWidth="1dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
android:gravity="center_vertical"
android:minHeight="@dimen/touch_target_min"
android:orientation="horizontal"
android:padding="@dimen/space_md">
<com.google.android.material.card.MaterialCardView
android:layout_width="@dimen/space_xxl"
android:layout_height="@dimen/space_xxl"
app:cardBackgroundColor="?attr/colorPrimaryContainer"
app:cardCornerRadius="@dimen/card_radius"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:contentDescription="@string/result_preview"
android:src="@drawable/ic_document"
app:tint="?attr/colorOnPrimaryContainer" />
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/space_md"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/itemTitle"
@ -30,10 +58,19 @@
android:id="@+id/itemSubtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginTop="@dimen/space_xs"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
tools:text="Resume · 12 Aug 2026" />
</LinearLayout>
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="@dimen/space_sm"
android:contentDescription="@null"
android:src="@drawable/ic_circle_status"
app:tint="?attr/colorOnSurfaceVariant" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_gradient_primary"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="@dimen/space_lg">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="?attr/colorSurfaceContainerLowest"
app:cardCornerRadius="@dimen/card_radius"
app:cardElevation="0dp"
app:strokeWidth="0dp">
<ImageView
android:id="@+id/healthIndicator"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_margin="@dimen/space_xs"
android:contentDescription="@string/cd_health_indicator"
android:src="@drawable/ic_circle_status" />
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/space_md"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/unknown_user"
android:textAppearance="?attr/textAppearanceTitleMedium"
android:textColor="?attr/colorOnPrimary" />
<TextView
android:id="@+id/userEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/space_xs"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnPrimary" />
</LinearLayout>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menuMyResumes"
android:title="@string/menu_my_resumes" />
<item
android:id="@+id/menuAdminPanel"
android:title="@string/menu_admin_panel"
android:visible="false" />
<item
android:id="@+id/menuSignOut"
android:title="@string/menu_sign_out" />
</menu>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:id="@+id/navGroupActions"
android:checkableBehavior="single">
<item
android:id="@+id/navBuildResume"
android:icon="@drawable/ic_sparkle"
android:title="@string/tab_build_resume" />
<item
android:id="@+id/navBuildCoverLetter"
android:icon="@drawable/ic_sparkle"
android:title="@string/tab_build_cover_letter" />
<item
android:id="@+id/navMyResumes"
android:icon="@drawable/ic_circle_status"
android:title="@string/menu_my_resumes" />
</group>
<group
android:id="@+id/navGroupAdmin"
android:checkableBehavior="none">
<item
android:id="@+id/navAdmin"
android:title="@string/menu_admin_panel"
android:visible="false" />
</group>
<group
android:id="@+id/navGroupAccount"
android:checkableBehavior="none">
<item
android:id="@+id/navSignOut"
android:title="@string/menu_sign_out" />
</group>
</menu>

View File

@ -1,41 +1,43 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.ResBuilder" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Primary color roles (dark) -->
<item name="colorPrimary">#4DD9DB</item>
<!-- Primary color roles (dark): bright teal on deep surfaces -->
<item name="colorPrimary">#80DADC</item>
<item name="colorOnPrimary">#003738</item>
<item name="colorPrimaryContainer">#004F51</item>
<item name="colorOnPrimaryContainer">#6FF6F8</item>
<item name="colorPrimaryInverse">#006A6C</item>
<item name="colorPrimaryContainer">#005A5C</item>
<item name="colorOnPrimaryContainer">#B5F2F3</item>
<item name="colorPrimaryInverse">#004F4F</item>
<item name="colorPrimaryFixed">#80DADC</item>
<item name="colorOnPrimaryFixed">#002020</item>
<!-- Secondary color roles (dark) -->
<item name="colorSecondary">#B0CCCB</item>
<item name="colorOnSecondary">#1B3535</item>
<item name="colorSecondaryContainer">#324C4B</item>
<item name="colorOnSecondaryContainer">#CCE8E7</item>
<item name="colorSecondary">#9CBEBD</item>
<item name="colorOnSecondary">#1B3534</item>
<item name="colorSecondaryContainer">#2F4A49</item>
<item name="colorOnSecondaryContainer">#BDD6D5</item>
<!-- Tertiary color roles (dark) -->
<item name="colorTertiary">#B1C8E8</item>
<item name="colorOnTertiary">#19324C</item>
<item name="colorTertiaryContainer">#324963</item>
<item name="colorOnTertiaryContainer">#D2E4FF</item>
<item name="colorTertiary">#A4C9E8</item>
<item name="colorOnTertiary">#0B2D45</item>
<item name="colorTertiaryContainer">#27475F</item>
<item name="colorOnTertiaryContainer">#BFE0FF</item>
<!-- Surface color roles (dark) -->
<item name="android:colorBackground">#0E1515</item>
<item name="colorSurface">#0E1515</item>
<item name="colorOnSurface">#DDE4E4</item>
<item name="colorSurfaceVariant">#3F4949</item>
<item name="colorOnSurfaceVariant">#BEC9C8</item>
<item name="colorSurfaceContainerLowest">#090F0F</item>
<item name="colorSurfaceContainerLow">#161D1D</item>
<item name="colorSurfaceContainer">#1A2121</item>
<item name="colorSurfaceContainerHigh">#242B2B</item>
<item name="colorSurfaceContainerHighest">#2F3636</item>
<item name="colorSurfaceInverse">#DDE4E4</item>
<item name="colorOnSurfaceInverse">#2D3131</item>
<!-- Surface color roles (dark): deep charcoal-teal -->
<item name="android:colorBackground">#0C1414</item>
<item name="colorSurface">#0C1414</item>
<item name="colorOnSurface">#E0ECEC</item>
<item name="colorSurfaceVariant">#3F4A4A</item>
<item name="colorOnSurfaceVariant">#BEC9C9</item>
<item name="colorSurfaceContainerLowest">#070E0E</item>
<item name="colorSurfaceContainerLow">#121B1B</item>
<item name="colorSurfaceContainer">#182222</item>
<item name="colorSurfaceContainerHigh">#242D2D</item>
<item name="colorSurfaceContainerHighest">#303939</item>
<item name="colorSurfaceInverse">#E0ECEC</item>
<item name="colorOnSurfaceInverse">#0C1414</item>
<!-- Outline -->
<item name="colorOutline">#889393</item>
<item name="colorOutlineVariant">#3F4949</item>
<item name="colorOutline">#899999</item>
<item name="colorOutlineVariant">#3F4A4A</item>
<!-- Error (dark) -->
<item name="colorError">#F2B8B5</item>
@ -59,12 +61,12 @@
<item name="colorInfoContainer">#0B4576</item>
<item name="colorOnInfoContainer">#D4EAFB</item>
<!-- System bars - edge-to-edge ready (dark) -->
<!-- System bars -->
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowLightStatusBar">false</item>
<!-- M3 Typography and shape defaults inherited from Material3 parent -->
<!-- Typography -->
<item name="textAppearanceDisplayLarge">@style/TextAppearance.Material3.DisplayLarge</item>
<item name="textAppearanceDisplayMedium">@style/TextAppearance.Material3.DisplayMedium</item>
<item name="textAppearanceDisplaySmall">@style/TextAppearance.Material3.DisplaySmall</item>
@ -81,7 +83,7 @@
<item name="textAppearanceLabelMedium">@style/TextAppearance.Material3.LabelMedium</item>
<item name="textAppearanceLabelSmall">@style/TextAppearance.Material3.LabelSmall</item>
<!-- Default M3 component styles inherited from Material3 parent; explicit overrides kept to a minimum -->
<!-- Component defaults -->
<item name="materialButtonStyle">@style/Widget.Material3.Button</item>
<item name="materialButtonOutlinedStyle">@style/Widget.Material3.Button.OutlinedButton</item>

View File

@ -2,56 +2,58 @@
<resources>
<!-- Material Design 3 semantic color tokens -->
<!-- Primary palette -->
<color name="primary">#006A6C</color>
<!-- Primary palette: rich teal with stronger contrast -->
<color name="primary">#004F4F</color>
<color name="on_primary">#FFFFFF</color>
<color name="primary_container">#6FF6F8</color>
<color name="on_primary_container">#002021</color>
<color name="primary_container">#B5F2F3</color>
<color name="on_primary_container">#002020</color>
<color name="primary_fixed">#B5F2F3</color>
<color name="on_primary_fixed">#002020</color>
<!-- Secondary palette -->
<color name="secondary">#4A6363</color>
<!-- Secondary palette: cool slate with more depth -->
<color name="secondary">#3D5252</color>
<color name="on_secondary">#FFFFFF</color>
<color name="secondary_container">#CCE8E7</color>
<color name="on_secondary_container">#051F1F</color>
<color name="secondary_container">#BDD6D5</color>
<color name="on_secondary_container">#041E1E</color>
<!-- Tertiary palette -->
<color name="tertiary">#4B617C</color>
<!-- Tertiary palette: deep blue-grey accent -->
<color name="tertiary">#365064</color>
<color name="on_tertiary">#FFFFFF</color>
<color name="tertiary_container">#D2E4FF</color>
<color name="on_tertiary_container">#051E35</color>
<color name="tertiary_container">#BFE0FF</color>
<color name="on_tertiary_container">#001D31</color>
<!-- Surface colors -->
<color name="surface">#F4FBFB</color>
<color name="on_surface">#161D1D</color>
<color name="surface_variant">#DAE5E4</color>
<color name="on_surface_variant">#3F4949</color>
<!-- Surface colors: warmer off-white base with visible tonal elevation -->
<color name="surface">#FAFDFD</color>
<color name="on_surface">#0A1414</color>
<color name="surface_variant">#D8E5E5</color>
<color name="on_surface_variant">#3F4A4A</color>
<color name="surface_container_lowest">#FFFFFF</color>
<color name="surface_container_low">#EEF6F6</color>
<color name="surface_container">#E8F0F0</color>
<color name="surface_container_high">#E2EAEA</color>
<color name="surface_container_highest">#DDE5E5</color>
<color name="surface_container_low">#F0F6F6</color>
<color name="surface_container">#E8F1F1</color>
<color name="surface_container_high">#DFEAEA</color>
<color name="surface_container_highest">#D6E4E4</color>
<!-- Outline -->
<color name="outline">#6F7979</color>
<color name="outline_variant">#BEC9C8</color>
<color name="outline">#6F7E7E</color>
<color name="outline_variant">#BEC9C9</color>
<!-- Status / Semantic colors -->
<color name="success">#4CAF50</color>
<!-- Status / Semantic colors: richer and more saturated -->
<color name="success">#2E7D32</color>
<color name="on_success">#FFFFFF</color>
<color name="success_container">#D9F6DA</color>
<color name="on_success_container">#1F5E22</color>
<color name="warning">#FF9800</color>
<color name="warning">#E65100</color>
<color name="on_warning">#FFFFFF</color>
<color name="warning_container">#FFE3B6</color>
<color name="on_warning_container">#693B00</color>
<color name="error">#F44336</color>
<color name="error">#C62828</color>
<color name="on_error">#FFFFFF</color>
<color name="error_container">#F9DEDC</color>
<color name="on_error_container">#410E0B</color>
<color name="info">#2196F3</color>
<color name="info">#1565C0</color>
<color name="on_info">#FFFFFF</color>
<color name="info_container">#D4EAFB</color>
<color name="on_info_container">#0B4576</color>
@ -59,20 +61,19 @@
<!-- Inverse surface -->
<color name="inverse_surface">#2D3131</color>
<color name="inverse_on_surface">#DFE4E4</color>
<color name="inverse_primary">#4DD9DB</color>
<color name="inverse_primary">#80DADC</color>
<!-- Status indicator palettes (kept for programmatic tint compatibility) -->
<!-- Status indicator palettes -->
<color name="status_healthy">@color/success</color>
<color name="status_degraded">@color/warning</color>
<color name="status_unhealthy">@color/error</color>
<!-- Legacy aliases to avoid breaking any remaining references during migration -->
<!-- Legacy aliases -->
<color name="purple_200">@color/primary_container</color>
<color name="purple_500">@color/primary</color>
<color name="purple_700">@color/on_primary_container</color>
<color name="teal_200">@color/primary_container</color>
<color name="teal_700">@color/primary</color>
<!-- Legacy neutral aliases kept for programmatic compatibility in unchanged Kotlin code -->
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Spacing system: multiples of 4dp -->
<dimen name="space_xs">4dp</dimen>
<dimen name="space_sm">8dp</dimen>
<dimen name="space_md">16dp</dimen>
<dimen name="space_lg">24dp</dimen>
<dimen name="space_xl">32dp</dimen>
<dimen name="space_xxl">48dp</dimen>
<!-- Component dimensions -->
<dimen name="card_radius">12dp</dimen>
<dimen name="card_radius_large">16dp</dimen>
<dimen name="button_height">48dp</dimen>
<dimen name="touch_target_min">48dp</dimen>
<dimen name="hero_header_min_height">160dp</dimen>
<dimen name="app_logo_size">64dp</dimen>
</resources>

View File

@ -23,6 +23,7 @@
<string name="menu_admin_panel">Admin Panel</string>
<string name="usage_limit_banner">You have reached your free limit. Please contact support to upgrade.</string>
<string name="unknown_user">Unknown user</string>
<string name="unknown_email">Not signed in</string>
<!-- Job form -->
<string name="hint_job_title">Job Title</string>
@ -55,6 +56,9 @@
<string name="export_docx">DOCX</string>
<string name="copied_to_clipboard">Copied to clipboard</string>
<string name="nothing_to_copy">Nothing to copy</string>
<string name="exporting">Exporting…</string>
<string name="export_failed">Export failed</string>
<string name="export_no_viewer">No app found to open this file</string>
<!-- Accessibility labels -->
<string name="cd_app_logo">resBuilder app logo</string>

View File

@ -6,6 +6,8 @@
<item name="colorPrimaryContainer">@color/primary_container</item>
<item name="colorOnPrimaryContainer">@color/on_primary_container</item>
<item name="colorPrimaryInverse">@color/inverse_primary</item>
<item name="colorPrimaryFixed">@color/primary_fixed</item>
<item name="colorOnPrimaryFixed">@color/on_primary_fixed</item>
<!-- Secondary color roles -->
<item name="colorSecondary">@color/secondary</item>
@ -64,7 +66,7 @@
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowLightStatusBar">true</item>
<!-- M3 Typography and shape defaults inherited from Material3 parent -->
<!-- M3 Typography -->
<item name="textAppearanceDisplayLarge">@style/TextAppearance.Material3.DisplayLarge</item>
<item name="textAppearanceDisplayMedium">@style/TextAppearance.Material3.DisplayMedium</item>
<item name="textAppearanceDisplaySmall">@style/TextAppearance.Material3.DisplaySmall</item>
@ -81,11 +83,10 @@
<item name="textAppearanceLabelMedium">@style/TextAppearance.Material3.LabelMedium</item>
<item name="textAppearanceLabelSmall">@style/TextAppearance.Material3.LabelSmall</item>
<!-- Default M3 component styles inherited from Material3 parent; explicit overrides kept to a minimum -->
<!-- Default M3 component styles -->
<item name="materialButtonStyle">@style/Widget.Material3.Button</item>
<item name="materialButtonOutlinedStyle">@style/Widget.Material3.Button.OutlinedButton</item>
<!-- Window background uses surface so app surfaces are always theme-aware -->
<item name="android:windowBackground">?attr/colorSurface</item>
</style>