/* The face (js/views/face.js): the brandmark as a character at its moments (CLAUDE.md "The
   face"). Every expression is a class on the <svg>; every movement is a transform or an
   opacity on a child, timed by the motion doctrine: UI under 300ms, entrances and reveals
   ease-out, on-screen morphs ease-in-out, and the one loop (reading) only while a run is in
   flight. Reduced motion: the loop stops and every switch is instant (the global block in
   app-flow.css covers transitions and animations; the rules at the foot pin the face's own). */
/* The brandmark's own blue (docs/brand/README.md), which phase 1 made the app's accent; the
   fallback keeps it right if the token is ever missing. The only colour the face is drawn in. */
.face { --face-ink: var(--accent); display: block; color: var(--face-ink); fill: currentColor; stroke: currentColor; overflow: visible; }
.face-letter path { fill: currentColor; stroke: none; }
/* The eyes. The pupil and the lid sit inside each counter; transform-box: fill-box keeps the
   lid's scale from its own top edge and the pupil's slide inside the hole at any size. */
.face-pupil { opacity: 0; transform-box: fill-box; transform-origin: 50% 50%; }
.face-lid { transform-box: fill-box; transform-origin: 50% 0; transform: scaleY(0); transition: transform var(--dur-fast) var(--ease-out); }
.face-closed .face-lid { transform: scaleY(1); }
.face-reading .face-pupil { opacity: 1; animation: face-read 1.6s linear infinite; }
@keyframes face-read {
  0% { transform: translateX(-190px); }
  82% { transform: translateX(190px); }
  100% { transform: translateX(-190px); }
}
/* Watching (the resume sheet while a tailor run writes it): the pupils sit low in the counter,
   looking down at the page; they hold, glance left, glance right and come back, and the lids
   blink once near the end of each 4.8s loop. The glances move on the ease-in-out curve the mouth
   uses (an on-screen move), each about 190ms of the loop; the blink closes and opens in about
   100ms. The pupil stays inside the hole: 50 down and 170 across keep its 112 radius within
   the counter's 688 by 360. */
.face-watching .face-pupil { opacity: 1; transform: translate(0, 50px); animation: face-watch 4.8s infinite; }
@keyframes face-watch {
  0%, 26% { transform: translate(0, 50px); animation-timing-function: cubic-bezier(0.77, 0, 0.175, 1); }
  30%, 50% { transform: translate(-170px, 50px); animation-timing-function: cubic-bezier(0.77, 0, 0.175, 1); }
  54%, 74% { transform: translate(170px, 50px); animation-timing-function: cubic-bezier(0.77, 0, 0.175, 1); }
  78%, 100% { transform: translate(0, 50px); }
}
.face-watching .face-lid { animation: face-blink 4.8s infinite; }
@keyframes face-blink {
  0%, 87% { transform: scaleY(0); }
  88% { transform: scaleY(1); }
  90%, 100% { transform: scaleY(0); }
}
/* The mouth: the arc and the wider arc crossfade (240ms ease-in-out); the flat line stands in
   for both with no animation. */
.face-arc, .face-arc-wide, .face-flat-line { transition: opacity 240ms cubic-bezier(0.77, 0, 0.175, 1); }
.face-arc-wide, .face-flat-line { opacity: 0; }
.face-smile .face-arc { opacity: 0; }
.face-smile .face-arc-wide { opacity: 1; }
.face-flat .face-arc, .face-flat .face-arc-wide { opacity: 0; transition: none; }
.face-flat .face-flat-line { opacity: 1; transition: none; }
/* The check mark beside the face when a job is marked as applied: drawn once, 240ms ease-out,
   from the first frame after it is mounted (face.js drawnCheck adds is-drawn). */
.face-check { display: inline-block; vertical-align: middle; color: var(--ok); stroke: currentColor; }
.face-check path { stroke-dashoffset: 20; transition: stroke-dashoffset 240ms cubic-bezier(0.23, 1, 0.32, 1); }
.face-check.is-drawn path { stroke-dashoffset: 0; }
@media (prefers-reduced-motion: reduce) {
  .face-lid, .face-arc, .face-arc-wide, .face-flat-line, .face-check path { transition: none; }
  .face-reading .face-pupil { animation: none; transform: none; }
  .face-watching .face-pupil { animation: none; transform: translate(0, 50px); }
  .face-watching .face-lid { animation: none; transform: scaleY(0); }
}

/* Moment (a), the tailoring wait (views/progress.js): the reading face in the run card the page
   scrolls to, in place of the spinner, beside the step the run is on. */
.run-now .face { flex: none; }

/* Moment (a2), the resume sheet while a tailor run writes it (views/resume-placeholder.js):
   the face peeks over the top edge of the page, its eyes above the paper and its smile tucked
   behind it, watching the lines being typed. Its own rules live with the placeholder in
   resume-editor.css. */

/* Moment (b), marked as applied (views/job.js statusControl): one row in place of the pill,
   the face (40px, so the row keeps its height), the drawn check and the words, in green. */
.job-applied-moment { display: inline-flex; align-items: center; gap: 10px; }
.job-applied-words { font-weight: 600; color: var(--ok); }

/* Moment (c), the empty jobs list (views/jobs.js): a centred column, the face, the sentence,
   the one link. */
.jobs-empty { display: flex; flex-direction: column; align-items: center; gap: 12px; max-width: 36rem; margin: 40px auto; text-align: center; }
.jobs-empty .face { margin-bottom: 8px; }
.jobs-empty > p { margin: 0; }

/* Moment (d), the locked and unlock screens (views/unlock.js): the face, eyes open like the
   brandmark (owner, 2026-10-19: closed lids read as filled-in eyes), centred over "Unlock your
   resumes". */
.unlock-head .face { margin: 0 auto 4px; }

/* The refusal on the paste box (views/addjob.js): the flat face beside the reason. */
.paste-refusal { display: flex; gap: 10px; align-items: center; margin-bottom: 12px; }
.paste-refusal .face { flex: none; }
.paste-refusal .hint { margin: 0; }
