diff --git a/web/src/assets/peregrine.css b/web/src/assets/peregrine.css
index 3ce6817..1b70936 100644
--- a/web/src/assets/peregrine.css
+++ b/web/src/assets/peregrine.css
@@ -58,6 +58,9 @@ body {
--score-low: var(--color-error); /* < 30% */
--score-none: var(--color-text-muted);
+ /* ── Hover overlay ── */
+ --color-hover: rgba(0, 0, 0, 0.06); /* subtle darkening on light surfaces */
+
/* ── Motion tokens ── */
--swipe-exit: 300ms;
--swipe-spring: 400ms cubic-bezier(0.34, 1.56, 0.64, 1);
@@ -91,6 +94,8 @@ body {
--score-mid-high: #5ba3d9; /* lighter blue for dark bg */
+ --color-hover: rgba(255, 255, 255, 0.07); /* subtle lightening on dark surfaces */
+
--status-synced: #9b8fea;
--status-survey: #b08fea;
--status-phone: #4ec9be;
@@ -112,6 +117,8 @@ body {
--score-mid-high: #5ba3d9;
+ --color-hover: rgba(255, 255, 255, 0.07);
+
--status-synced: #9b8fea;
--status-survey: #b08fea;
--status-phone: #4ec9be;
diff --git a/web/src/components/InterviewCard.vue b/web/src/components/InterviewCard.vue
index 9566f0c..7cc7814 100644
--- a/web/src/components/InterviewCard.vue
+++ b/web/src/components/InterviewCard.vue
@@ -151,7 +151,7 @@ async function reclassifySignal(sig: StageSignal, newLabel: StageSignal['stage_s
}
const scoreClass = computed(() => {
- const s = (props.job.match_score ?? 0) * 100
+ const s = props.job.match_score ?? 0
if (s >= 85) return 'score--high'
if (s >= 65) return 'score--mid'
return 'score--low'
@@ -159,7 +159,7 @@ const scoreClass = computed(() => {
const scoreLabel = computed(() =>
props.job.match_score != null
- ? `${Math.round(props.job.match_score * 100)}%`
+ ? `${Math.round(props.job.match_score)}%`
: '—'
)
@@ -588,7 +588,7 @@ async function saveFeedback() {
background: var(--color-hover);
}
.btn-chip-active {
- background: var(--color-primary-muted, #e8f0ff);
+ background: var(--app-primary-light);
color: var(--color-primary); border-color: var(--color-primary);
font-weight: 600;
}
diff --git a/web/src/components/ResumeLibraryCard.vue b/web/src/components/ResumeLibraryCard.vue
index 00dc33d..2941ec4 100644
--- a/web/src/components/ResumeLibraryCard.vue
+++ b/web/src/components/ResumeLibraryCard.vue
@@ -106,7 +106,7 @@ onMounted(load)
}
.rlc__title {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
font-weight: 600;
margin: 0;
display: flex;
@@ -128,7 +128,7 @@ onMounted(load)
.rlc__name {
font-weight: 500;
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
}
.rlc__meta {
@@ -143,7 +143,7 @@ onMounted(load)
}
.rlc__empty {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--color-text-muted, #64748b);
}
@@ -153,7 +153,7 @@ onMounted(load)
}
.rlc__loading {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--color-text-muted, #64748b);
}
@@ -183,7 +183,7 @@ onMounted(load)
padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
cursor: pointer;
border-radius: var(--radius-sm, 0.25rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
}
.rlc__picker-item:hover,
diff --git a/web/src/components/ResumeOptimizerPanel.vue b/web/src/components/ResumeOptimizerPanel.vue
index 41b84b3..60f3a30 100644
--- a/web/src/components/ResumeOptimizerPanel.vue
+++ b/web/src/components/ResumeOptimizerPanel.vue
@@ -578,7 +578,7 @@ onUnmounted(stopPolling)
}
.rop__tier-note {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-text-muted, #64748b);
background: var(--app-surface-alt, #f8fafc);
border: 1px solid var(--app-border, #e2e8f0);
@@ -603,13 +603,13 @@ onUnmounted(stopPolling)
.rop__hint,
.rop__empty {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-text-muted, #64748b);
margin: 0;
}
.rop__error {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-danger, #dc2626);
margin: 0;
}
@@ -618,7 +618,7 @@ onUnmounted(stopPolling)
display: flex;
align-items: center;
gap: var(--space-2, 0.5rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-text-muted, #64748b);
}
@@ -643,7 +643,7 @@ onUnmounted(stopPolling)
border-radius: var(--radius-sm, 0.25rem);
border-left: 3px solid transparent;
background: var(--app-surface-alt, #f8fafc);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
cursor: pointer;
user-select: none;
}
@@ -706,7 +706,7 @@ onUnmounted(stopPolling)
}
.rop__wordcount {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-text-muted, #64748b);
}
@@ -727,7 +727,7 @@ onUnmounted(stopPolling)
background: color-mix(in srgb, var(--app-danger, #dc2626) 8%, transparent);
border: 1px solid color-mix(in srgb, var(--app-danger, #dc2626) 30%, transparent);
border-radius: var(--radius-md, 0.5rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-danger, #dc2626);
}
@@ -736,7 +736,7 @@ onUnmounted(stopPolling)
min-height: 20rem;
padding: var(--space-3, 0.75rem);
font-family: var(--font-mono, monospace);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
line-height: 1.6;
border: 1px solid var(--app-border, #e2e8f0);
border-radius: var(--radius-md, 0.5rem);
@@ -762,7 +762,7 @@ onUnmounted(stopPolling)
color: #fff;
border: none;
border-radius: var(--radius-md, 0.5rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
font-weight: 500;
cursor: pointer;
transition: background 0.15s;
@@ -781,7 +781,7 @@ onUnmounted(stopPolling)
color: var(--app-text, #1e293b);
border: 1px solid var(--app-border, #e2e8f0);
border-radius: var(--radius-md, 0.5rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
font-weight: 500;
cursor: pointer;
transition: background 0.15s;
@@ -799,7 +799,7 @@ onUnmounted(stopPolling)
}
.rop__review-intro {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-text-muted, #64748b);
margin: 0;
padding: var(--space-3, 0.75rem) var(--space-4, 1rem);
@@ -819,7 +819,7 @@ onUnmounted(stopPolling)
}
.rop__review-section-title {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
@@ -852,7 +852,7 @@ onUnmounted(stopPolling)
gap: var(--space-1, 0.25rem);
padding: 0.3em 0.75em;
border-radius: var(--radius-full, 9999px);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
border: 1.5px solid var(--app-border, #e2e8f0);
background: var(--app-surface, #fff);
cursor: pointer;
@@ -887,7 +887,7 @@ onUnmounted(stopPolling)
gap: var(--space-1, 0.25rem);
padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
border-radius: var(--radius-sm, 0.25rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
}
.rop__diff-col--original {
@@ -936,7 +936,7 @@ onUnmounted(stopPolling)
}
.rop__exp-company {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-text-muted, #64748b);
}
@@ -945,7 +945,7 @@ onUnmounted(stopPolling)
display: inline-flex;
align-items: center;
gap: var(--space-1, 0.25rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
cursor: pointer;
color: var(--app-text, #1e293b);
}
@@ -975,7 +975,7 @@ onUnmounted(stopPolling)
background: none;
border: none;
color: var(--app-accent, #6366f1);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
cursor: pointer;
padding: 0;
}
@@ -994,7 +994,7 @@ onUnmounted(stopPolling)
background: var(--app-surface-alt, #f8fafc);
border: 1px solid var(--app-border, #e2e8f0);
border-radius: var(--radius-sm, 0.25rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
}
.rop__history-date {
@@ -1060,7 +1060,7 @@ onUnmounted(stopPolling)
display: inline-flex;
align-items: center;
gap: var(--space-1, 0.25rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
cursor: pointer;
color: var(--app-text, #1e293b);
}
@@ -1068,7 +1068,7 @@ onUnmounted(stopPolling)
.rop__framing-context {
width: 100%;
padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
font-family: inherit;
line-height: 1.5;
border: 1px solid var(--app-border, #e2e8f0);
@@ -1103,7 +1103,7 @@ onUnmounted(stopPolling)
.rop__preview-hint {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-text-muted, #64748b);
margin: 0;
}
@@ -1132,7 +1132,7 @@ onUnmounted(stopPolling)
color: var(--app-text-muted, #64748b);
border: 1px solid var(--app-border, #e2e8f0);
border-radius: var(--radius-md, 0.5rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
cursor: pointer;
transition: background 0.15s;
}
@@ -1163,7 +1163,7 @@ onUnmounted(stopPolling)
display: inline-flex;
align-items: center;
gap: var(--space-2, 0.5rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
color: var(--app-text, #1e293b);
cursor: pointer;
user-select: none;
@@ -1171,7 +1171,7 @@ onUnmounted(stopPolling)
.rop__resume-name-input {
padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
font-family: inherit;
border: 1px solid var(--app-border, #e2e8f0);
border-radius: var(--radius-sm, 0.25rem);
diff --git a/web/src/components/ResumeSyncConfirmModal.vue b/web/src/components/ResumeSyncConfirmModal.vue
index 3739b77..899bedb 100644
--- a/web/src/components/ResumeSyncConfirmModal.vue
+++ b/web/src/components/ResumeSyncConfirmModal.vue
@@ -131,7 +131,7 @@ defineEmits<{
background: var(--color-error, #dc2626);
color: #fff; border: none;
border-radius: var(--radius-md); cursor: pointer;
- font-size: var(--font-sm); font-weight: 600;
+ font-size: var(--text-sm); font-weight: 600;
}
.btn-danger:hover { filter: brightness(1.1); }
.btn-secondary {
@@ -140,7 +140,7 @@ defineEmits<{
color: var(--color-text);
border: 1px solid var(--color-border);
border-radius: var(--radius-md); cursor: pointer;
- font-size: var(--font-sm);
+ font-size: var(--text-sm);
}
.btn-secondary:hover { background: var(--color-surface-alt); }
diff --git a/web/src/components/resume-review/ConfirmPage.vue b/web/src/components/resume-review/ConfirmPage.vue
index 46e37a8..5075ad6 100644
--- a/web/src/components/resume-review/ConfirmPage.vue
+++ b/web/src/components/resume-review/ConfirmPage.vue
@@ -46,11 +46,11 @@ const emit = defineEmits<{
diff --git a/web/src/components/resume-review/ExperiencePage.vue b/web/src/components/resume-review/ExperiencePage.vue
index 00ed8dd..8710543 100644
--- a/web/src/components/resume-review/ExperiencePage.vue
+++ b/web/src/components/resume-review/ExperiencePage.vue
@@ -67,18 +67,18 @@ function updateBullet(idx: number, value: string) {
diff --git a/web/src/components/resume-review/SkillsPage.vue b/web/src/components/resume-review/SkillsPage.vue
index af13b24..9407b10 100644
--- a/web/src/components/resume-review/SkillsPage.vue
+++ b/web/src/components/resume-review/SkillsPage.vue
@@ -58,7 +58,7 @@ const emit = defineEmits<{
diff --git a/web/src/components/resume-review/SummaryPage.vue b/web/src/components/resume-review/SummaryPage.vue
index 14886a4..37f8a4c 100644
--- a/web/src/components/resume-review/SummaryPage.vue
+++ b/web/src/components/resume-review/SummaryPage.vue
@@ -51,9 +51,9 @@ const emit = defineEmits<{
.rp__diff-col { display: flex; flex-direction: column; gap: var(--space-2, 0.5rem); }
.rp__diff-col--editable { gap: var(--space-2, 0.5rem); }
.rp__diff-label { font-size: var(--font-xs, 0.75rem); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-muted, #4a5c7a); }
-.rp__diff-text { font-size: var(--font-sm, 0.875rem); line-height: 1.6; padding: var(--space-3, 0.75rem); background: var(--color-surface-alt, #dde4f0); border-radius: var(--radius-sm, 0.25rem); margin: 0; }
+.rp__diff-text { font-size: var(--text-sm); line-height: 1.6; padding: var(--space-3, 0.75rem); background: var(--color-surface-alt, #dde4f0); border-radius: var(--radius-sm, 0.25rem); margin: 0; }
.rp__edit-textarea {
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
line-height: 1.6;
padding: var(--space-3, 0.75rem);
background: var(--color-surface, #eaeff8);
@@ -67,5 +67,5 @@ const emit = defineEmits<{
font-family: inherit;
}
.rp__edit-textarea:focus { outline: 2px solid var(--color-accent, #c4732a); outline-offset: 2px; }
-.rp__accept-toggle { display: inline-flex; align-items: center; gap: var(--space-2, 0.5rem); cursor: pointer; font-size: var(--font-sm, 0.875rem); }
+.rp__accept-toggle { display: inline-flex; align-items: center; gap: var(--space-2, 0.5rem); cursor: pointer; font-size: var(--text-sm); }
diff --git a/web/src/views/InterviewsView.vue b/web/src/views/InterviewsView.vue
index a54b375..516d611 100644
--- a/web/src/views/InterviewsView.vue
+++ b/web/src/views/InterviewsView.vue
@@ -767,7 +767,7 @@ function formatRejectionDate(job: PipelineJob): string {
background: var(--color-hover);
}
.btn-chip-active {
- background: var(--color-primary-muted, #e8f0ff);
+ background: var(--app-primary-light);
color: var(--color-primary); border-color: var(--color-primary);
font-weight: 600;
}
diff --git a/web/src/views/ResumesView.vue b/web/src/views/ResumesView.vue
index 3e0262f..f17b6c4 100644
--- a/web/src/views/ResumesView.vue
+++ b/web/src/views/ResumesView.vue
@@ -332,7 +332,7 @@ onBeforeRouteLeave(() => {
.rv__item-star { color: var(--color-warning, #f59e0b); font-size: 1rem; flex-shrink: 0; margin-top: 2px; }
.rv__item-info { display: flex; flex-direction: column; gap: 2px; }
-.rv__item-name { font-weight: 500; font-size: var(--font-sm, 0.875rem); }
+.rv__item-name { font-weight: 500; font-size: var(--text-sm); }
.rv__item-meta { font-size: var(--font-xs, 0.75rem); color: var(--color-text-muted, #64748b); }
.rv__item-source { font-size: var(--font-xs, 0.75rem); color: var(--color-accent, #6366f1); }
@@ -340,7 +340,7 @@ onBeforeRouteLeave(() => {
.rv__preview-header { display: flex; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; gap: var(--space-3, 0.75rem); }
.rv__preview-meta { display: flex; align-items: center; gap: var(--space-2, 0.5rem); flex-wrap: wrap; }
.rv__preview-name { font-size: var(--font-lg, 1.125rem); font-weight: 600; margin: 0; }
-.rv__preview-words { font-size: var(--font-sm, 0.875rem); color: var(--color-text-muted, #64748b); }
+.rv__preview-words { font-size: var(--text-sm); color: var(--color-text-muted, #64748b); }
.rv__default-badge {
font-size: var(--font-xs, 0.75rem); font-weight: 600;
background: var(--color-success, #16a34a); color: #fff;
@@ -352,7 +352,7 @@ onBeforeRouteLeave(() => {
border: 1px solid var(--color-error, #dc2626);
border-radius: var(--radius-md, 0.5rem);
padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
- cursor: pointer; font-size: var(--font-sm, 0.875rem);
+ cursor: pointer; font-size: var(--text-sm);
}
.rv__delete-btn:disabled { opacity: 0.4; cursor: not-allowed; }
@@ -364,13 +364,13 @@ onBeforeRouteLeave(() => {
.rv__textarea {
flex: 1; min-height: 400px; padding: var(--space-3, 0.75rem);
border: 1px solid var(--color-border, #e2e8f0); border-radius: var(--radius-md, 0.5rem);
- font-family: monospace; font-size: var(--font-sm, 0.875rem); resize: vertical;
+ font-family: monospace; font-size: var(--text-sm); resize: vertical;
background: var(--color-surface-alt, #f8fafc);
color: var(--color-text);
}
.rv__textarea:not([readonly]) { background: var(--color-surface); }
.rv__edit-actions { display: flex; gap: var(--space-2, 0.5rem); }
-.rv__error { color: var(--color-error, #dc2626); font-size: var(--font-sm, 0.875rem); }
+.rv__error { color: var(--color-error, #dc2626); font-size: var(--text-sm); }
.rv__download-menu { position: relative; }
.rv__download-dropdown {
@@ -382,11 +382,11 @@ onBeforeRouteLeave(() => {
.rv__download-dropdown button {
width: 100%; text-align: left; background: none; border: none;
padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
- cursor: pointer; font-size: var(--font-sm, 0.875rem); border-radius: var(--radius-sm, 0.25rem);
+ cursor: pointer; font-size: var(--text-sm); border-radius: var(--radius-sm, 0.25rem);
}
.rv__download-dropdown button:hover { background: var(--color-surface-alt, #f8fafc); }
-.rv__loading, .rv__empty { color: var(--color-text-muted, #64748b); font-size: var(--font-sm, 0.875rem); }
+.rv__loading, .rv__empty { color: var(--color-text-muted, #64748b); font-size: var(--text-sm); }
/* Button styles — defined locally since no global button sheet exists yet */
.btn-secondary {
@@ -396,7 +396,7 @@ onBeforeRouteLeave(() => {
border-radius: var(--radius-md, 0.5rem);
color: var(--color-text-muted);
cursor: pointer;
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
white-space: nowrap;
}
.btn-secondary:hover:not(:disabled) {
@@ -412,7 +412,7 @@ onBeforeRouteLeave(() => {
border: none;
border-radius: var(--radius-md, 0.5rem);
cursor: pointer;
- font-size: var(--font-sm, 0.875rem);
+ font-size: var(--text-sm);
font-weight: 600;
white-space: nowrap;
display: inline-flex;
diff --git a/web/src/views/wizard/WizardTrainingStep.vue b/web/src/views/wizard/WizardTrainingStep.vue
index 994e5b8..87c32ed 100644
--- a/web/src/views/wizard/WizardTrainingStep.vue
+++ b/web/src/views/wizard/WizardTrainingStep.vue
@@ -65,7 +65,7 @@ function back() { router.push('/setup/resume') }