/* The app's base stylesheet (with app-flow.css, app-parity.css, resume-editor.css and coach.css).
   style-src is 'self' with no unsafe-inline, so every visual state is a class here; nothing sets
   inline styles. font-src is 'self' only, so every web font is a woff2 in fonts/ (the build copies
   app/ whole; the one brand cut comes from docs/brand/font).

   The look (design refresh phase 1, 2026-10-16) is applicantaide.com's own system, so the app
   wears its brand: a paper page (--bg) with warm ink, the logo's teal-navy (--accent) as the ONE
   accent, Hanken Grotesk for the UI and Newsreader for each screen's h1 only, pill buttons, three
   radii (--r-control, --r-card, 999px) and four shadows (owner, 2026-10-21: "any use of shadow we
   can add to give the product some more life?"): --shadow-rest, a soft lift under every in-flow
   card and panel beside its 1px --line edge; --shadow-hover, a card you can open lifting under the
   pointer; --shadow-card for the one raised card on a screen; --shadow-pop for menus, drawers and
   dialogs. Filled buttons carry a small accent-tinted shadow (--shadow-btn). The top bar is the paper with a hairline under it and the brandmark in its own blue.
   Light only is the owner's standing call, so there is deliberately no prefers-color-scheme block.
   Colour carries meaning (the verdicts, the grade band, a recommendation's tag, the posting
   status; those tokens live in app-flow.css); everything else is the warm neutral ramp. The
   resume sheet (.resume-preview, .re-sheet) is the printed document and keeps its own colours. */
@font-face {
  font-family: "Applicant Aide Sans";
  src: url("fonts/ApplicantAideSans-BoldItalic.woff2") format("woff2");
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}
/* Hanken Grotesk (SIL OFL, fonts/HankenGrotesk-OFL.txt) and Newsreader (SIL OFL,
   fonts/Newsreader-OFL.txt), static instances cut from the Google Fonts sources. */
@font-face { font-family: "Hanken Grotesk"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/hanken-grotesk-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Hanken Grotesk"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("fonts/hanken-grotesk-500-normal.woff2") format("woff2"); }
@font-face { font-family: "Hanken Grotesk"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/hanken-grotesk-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Hanken Grotesk"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("fonts/hanken-grotesk-700-normal.woff2") format("woff2"); }
@font-face { font-family: "Newsreader"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("fonts/newsreader-500-normal.woff2") format("woff2"); }
@font-face { font-family: "Newsreader"; font-style: italic; font-weight: 400; font-display: swap;
  src: url("fonts/newsreader-400-italic.woff2") format("woff2"); }
/* contrast-pairs: --ink on --bg; --ink on --panel; --ink on --panel-2; --ink-dim on --bg; --ink-dim on --panel; --ink-dim on --panel-2; --muted on --bg; --fg on --bg; --on-bar on --bar; --bar on --on-bar; --on-accent on --accent; --on-accent on --accent-strong; --accent on --panel; --accent on --bg; --accent on --panel-2; --accent on --accent-soft; --accent-strong on --accent-soft; --ink on --accent-soft; --danger on --panel; --danger on --bg; --danger-strong on --danger-soft; --danger-strong on --panel; --accent-strong on --panel; --ink-dim on --accent-soft; --ink-dim on --line; --kw-have-ink on --kw-have-bg; --kw-add-ink on --kw-add-bg */
:root {
  color-scheme: light;
  /* The neutral ramp: paper, two panel tints, two edges, two inks. */
  --bg: #f7f4ec; --panel: #fffdf8; --panel-2: #f1ede3; --line: #e6e1d6; --line-strong: #cfc8b9;
  --ink: #211c16; --ink-dim: #6b6256;
  /* Borders and hover edges only: #8f8779 is 3.2:1 on the paper and 3.5:1 on a panel, below AA
     for text but above the 3:1 a field's edge needs (WCAG 1.4.11), so form fields draw their
     border with it. Never text (app-a11y.test.js). */
  --ink-faint: #8f8779;
  /* The top bar is the brand blue with white type; the brandmark is filtered white. */
  --bar: #1d4f91; --on-bar: #ffffff;
  /* The one accent: the logo's teal-navy. Paper type on it, never pure white. */
  --accent: #20536e; --accent-strong: #173f55; --accent-soft: #e8eff2; --on-accent: #f7f4ec;
  --danger: #b3261e; --danger-strong: #8f1e18; --danger-soft: #fdecea;
  /* The names older rules and tests use, on the new values. */
  --fg: #211c16; --muted: #6b6256; --focus: #20536e;
  --star: #b26a00; /* the ratings stars and meters (views/job-ratings.js); 3:1 on --panel as a graphic */
  /* The posting keyword marks (2026-10-20, owner: "a color for keywords that's orange or
     something ... a color for added and a color for already existed"): green for a keyword already
     in his core resume, orange for one the tailoring ADDED (it was amber, which read as yellow).
     2026-10-21 (owner: "existing keywords ... their own color, maybe purple since red / green /
     orange are taken"): the kept keyword is purple, so green only ever means new wording.
     Each ink is text on its own tint; the edges are graphics (3:1+). */
  --kw-have-bg: #ece3fb; --kw-have-ink: #4c1d95; --kw-have-edge: #7c3aed;
  --kw-add-bg: #ffd8b5; --kw-add-ink: #7c2d12; --kw-add-edge: #c2410c;
  /* Transparent tints for hover on any surface, and the focus ring on fields. */
  --hover: rgba(33, 28, 22, 0.06); --hover-strong: rgba(33, 28, 22, 0.1);
  --ring: 0 0 0 3px rgba(32, 83, 110, 0.22);
  /* The desk the resume sheets sit on (the editor's and the preview's), app chrome, not paper. */
  --desk: #f1ede3;
  /* Type. The UI face and the display face (each screen's h1 only), and a five-step scale. */
  --font-ui: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-display: "Newsreader", Georgia, "Times New Roman", serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, monospace;
  --t-xs: 13px; --t-sm: 15px; --t-md: 18px; --t-lg: 24px; --t-xl: 32px;
  --lh-md: 1.35; --lh-lg: 1.2; --lh-xl: 1.1; --ls-lg: -0.015em; --ls-xl: -0.02em;
  --t-eyebrow: 11px;
  /* Shape and elevation: three radii, two shadows. */
  --r-control: 8px; --r-card: 12px; --r-pill: 999px;
  --shadow-rest: 0 1px 2px rgba(33, 28, 22, 0.05), 0 2px 6px rgba(33, 28, 22, 0.04);
  --shadow-hover: 0 2px 4px rgba(33, 28, 22, 0.06), 0 12px 28px rgba(33, 28, 22, 0.12);
  --shadow-card: 0 1px 2px rgba(33, 28, 22, 0.06), 0 8px 24px rgba(33, 28, 22, 0.08);
  --shadow-btn: 0 1px 2px rgba(20, 52, 70, 0.2), 0 2px 6px rgba(32, 83, 110, 0.16);
  --shadow-pop: 0 8px 24px rgba(33, 28, 22, 0.14), 0 2px 6px rgba(33, 28, 22, 0.08);
  /* Motion: one curve, two durations; a press is 160ms on the same curve. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1); --dur-fast: 120ms; --dur-base: 200ms;
  /* The page shell (owner feedback 2026-10-05: "we're wasting space by just centering the
     content"). One content width for the top bar, every screen and the footer: up to 1360px
     (the resume canvas's own width, so every job section lines up with the pages), with a 16px
     gutter each side below that. --edge is the side padding that lines a full-bleed bar up with
     the content; its 100% is the bar's own width, resolved where it is used. */
  --page-max: 1360px; --gutter: 16px;
  --edge: max(var(--gutter), calc((100% - var(--page-max)) / 2));
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
/* No scrollbar-gutter: stable here. With classic scrollbars it reserved a 15px strip on the
   right of every screen, even one that does not scroll, and the full-bleed top bar and the
   pinned job bar stopped short of the window beside it (2026-10-21). */
/* A full-height column: the footer sits at the bottom of the window even on a short screen
   (the Cloudflare dashboard's pattern), and nothing follows it, so the page never scrolls past it. */
body {
  display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh;
  background: var(--bg); color: var(--ink);
  font: var(--t-sm)/1.5 var(--font-ui);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); }
.brand { font-weight: 600; }
/* The product name inside running text (ui.js withName): brand font, bold italic, never
   split across lines. It inherits the surrounding text colour, so contrast is the text's. */
.aa-name { font-family: "Applicant Aide Sans", system-ui, sans-serif; font-weight: 700;
  font-style: italic; font-synthesis: none; white-space: nowrap; }
/* A section label: small caps in the accent, tracked wide (applicantaide.com's eyebrow). */
.eyebrow { font-size: var(--t-eyebrow); font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); }

/* ------------------------------------------------------------------ top bar
   The brand blue with the white mark and white type (its pre-refresh colour, back at the
   owner's ask 2026-10-19). One row at
   every width, a fixed 56px tall on every screen (the locked and onboarding screens' own header
   in index.html too), its controls centred in it: the name, the nav, then the credits and
   account controls at the right. Under 640px the credits and Buy credits leave the bar for the
   account menu (app-flow.css). padding-block: 0 lets the 56px alone set the height. */
.top {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px;
  padding: 12px var(--edge); padding-block: 0; min-height: 56px;
  background: var(--bar); color: var(--on-bar);
  /* A shadow, not a border, so the bar stays the 56px --top-h assumes. */
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08), 0 2px 8px rgba(16, 24, 40, 0.12);
}
/* The top-bar name stays upright (owner's rule). The only brand cut shipped is Bold Italic,
   so this is the UI face. The mark is a CSS image, so the name stays one text node. */
.top .brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: var(--t-md); font-weight: 600; line-height: 1; letter-spacing: -0.01em;
  color: var(--on-bar); text-decoration: none; white-space: nowrap;
}
.top .brand::before {
  content: ""; flex: none; width: 38px; height: 26px;
  background: url("brandmark.svg") center / contain no-repeat;
  filter: brightness(0) invert(1);
}
/* The focus ring in the bar's own type colour, so it shows on the blue; the account menu's
   list opens on a panel, so it keeps the page's ring. */
.top :focus-visible { outline-color: var(--on-bar); }
.top .account-panel :focus-visible { outline-color: var(--focus); }
/* The credits count and Buy credits (owner, 2026-10-21: they read as two look-alike pills of
   different sizes, one a button and one not). The count is plain text with no edge; Buy credits
   is the bar's one filled control, white on the blue, the same 32px as the nav. */
.top .credit-group { display: inline-flex; align-items: center; gap: 12px; }
.top .credit-group .credits {
  min-height: 0; padding: 0; border: 0; border-radius: 0;
  font-size: var(--t-sm); font-weight: 500; color: var(--on-bar);
}
.top .credit-group .buy {
  min-height: 32px; padding: 4px 14px; border: 1px solid var(--on-bar);
  background: var(--on-bar); color: var(--bar); font-size: var(--t-xs); font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}
.top .credit-group .buy:hover { background: rgba(255, 255, 255, 0.88); border-color: rgba(255, 255, 255, 0.88); color: var(--bar); }
main { flex: 1 0 auto; width: min(var(--page-max), 100% - 2 * var(--gutter)); margin: 0 auto; padding: 24px 0 64px; }
main:focus, h1:focus, h2:focus { outline: none; }
/* Each screen's h1 is the display face; every other heading is the UI face. */
h1 { font-family: var(--font-display); font-weight: 500; font-size: var(--t-xl); line-height: var(--lh-xl); letter-spacing: var(--ls-xl); margin: 0 0 12px; text-wrap: balance; }
h2 { font-size: var(--t-md); line-height: var(--lh-md); font-weight: 600; letter-spacing: -0.005em; margin: 24px 0 12px; }
h3 { font-size: var(--t-sm); line-height: var(--lh-md); font-weight: 600; margin: 18px 0 8px; }
p { margin: 0 0 12px; }
.muted { color: var(--ink-dim); }

/* ------------------------------------------------------------ buttons, inputs
   A plain button is the primary action (2E's screens rely on that), as is .primary: a filled
   pill in the accent. .secondary is a pill with an edge on a panel; .quiet (app-flow.css) is a
   text button. A press scales the button down a hair; the reduced-motion rule in app-flow.css
   covers the transition. */
button {
  font: inherit; font-weight: 500; line-height: 1.3;
  min-height: 40px; padding: 8px 18px; border-radius: var(--r-pill); cursor: pointer;
  border: 1px solid var(--accent); background: var(--accent); color: var(--on-accent);
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out), transform 160ms var(--ease-out);
}
button:not(:disabled):hover { background: var(--accent-strong); border-color: var(--accent-strong); }
/* A filled button sits a hair above the page; an edged or text button stays flat. */
button.primary, button.danger { box-shadow: var(--shadow-btn); }
button.primary:not(:disabled):hover { box-shadow: 0 2px 4px rgba(20, 52, 70, 0.22), 0 6px 14px rgba(32, 83, 110, 0.2); }
button.secondary:not(.quiet):not(.chip):not(.menu-item) { box-shadow: 0 1px 1px rgba(33, 28, 22, 0.05); }
button:not(:disabled):active { transform: scale(0.97); }
button.secondary { background: var(--panel); color: var(--ink); border-color: var(--line-strong); }
button.secondary:not(:disabled):hover { background: var(--panel-2); border-color: var(--ink-faint); }
button.danger { background: var(--danger); border-color: var(--danger); color: var(--on-band); }
button.danger:not(:disabled):hover { background: var(--danger-strong); border-color: var(--danger-strong); }
button:disabled { opacity: 0.6; cursor: not-allowed; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
/* The Google sign-in popup's one link to the new Doc (js/google-callback.js), drawn as a primary
   pill. */
a.gc-open { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 18px; border-radius: var(--r-pill);
  background: var(--accent); color: var(--on-accent); font-weight: 600; text-decoration: none; }
a.gc-open:hover { background: var(--accent-strong); }
label { display: block; font-weight: 600; margin: 12px 0 4px; }
input[type="text"], input[type="password"], input[type="file"], input[type="email"], input[type="tel"],
input[type="url"], input[type="date"], input[type="number"], input[type="search"], select, textarea {
  font: inherit; width: 100%; padding: 7px 10px; min-height: 40px;
  /* --ink-faint, not --line: a field's edge needs 3:1 to be seen (WCAG 1.4.11). */
  border: 1px solid var(--ink-faint); border-radius: var(--r-control); background: var(--panel); color: var(--ink);
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
input:focus-visible, select:focus-visible, textarea:focus-visible, input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: var(--ring);
}
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); }
label.check { display: flex; gap: 8px; align-items: center; font-weight: 400; }
label.check input { width: 20px; height: 20px; }
.actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.message { padding: 10px 12px; border-radius: var(--r-control); border: 1px solid var(--line); background: var(--panel-2); color: var(--ink); }
.message.error { border-color: var(--danger); border-left-width: 5px; }
.message.ok { border-color: var(--ok); border-left-width: 5px; }
.code { font-family: var(--font-mono); font-size: var(--t-md); letter-spacing: 0.05em; font-variant-numeric: tabular-nums;
  display: flex; flex-wrap: wrap; gap: 12px; padding: 16px; background: var(--panel-2);
  border: 1px solid var(--line); border-radius: var(--r-control); }

/* ------------------------------------------------------------------ panels
   An in-flow card: a panel with a 1px edge and the soft --shadow-rest. The one raised card on a
   screen (the job page's next-step card, a form screen's card) adds --shadow-card where it is
   drawn. */
.panel {
  border: 1px solid var(--line); border-radius: var(--r-card); background: var(--panel); box-shadow: var(--shadow-rest);
  padding: 20px 22px; margin: 0 0 16px;
}
.panel > h2:first-child { margin-top: 0; }

/* ------------------------------------------------------------ resume document
   The resume as it prints: Letter sheets (8.5 x 11) on the desk, one sheet per page,
   breaks placed by js/views/paper.js. Every size inside a sheet is in container units
   (--in is one inch of the sheet), so the sheet is the same page at any width, only scaled,
   and the breaks match the paper. Single column; the one flex row is the role line, so the
   dates can sit on the right. Near-black on white, one accent (the navy of the exported Doc)
   on the name and the section headings. The sheet's own colours are fixed: it is the printed
   document, not app chrome. */
.resume-preview { background: var(--desk); border-radius: var(--r-control); padding: 24px;
  max-width: calc(8.5in + 48px); container-type: inline-size; }
.resume-preview .paper-ruler { height: 0; }
.resume-preview .sheet { --in: calc(100cqw / 8.5); --pt: calc(var(--in) / 72);
  box-sizing: border-box; width: 100%; aspect-ratio: 8.5 / 11; background: #ffffff;
  padding: calc(0.7 * var(--in)) calc(0.75 * var(--in));
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.12), 0 6px 18px rgba(15, 23, 42, 0.08);
  font-family: Calibri, Carlito, "Helvetica Neue", Arial, sans-serif;
  font-size: calc(10 * var(--pt)); line-height: 1.3; color: #1a1a1a; }
.resume-preview .sheet + .sheet { margin-top: 20px; }
.resume-preview .sheet-body { display: flow-root; }
.resume-preview .sheet-body > :first-child { margin-top: 0; }
.resume-preview h1 { font-family: inherit; font-size: calc(24 * var(--pt)); font-weight: 700; line-height: 1.1;
  letter-spacing: -0.01em; color: #1f3d5c; margin: 0; text-wrap: auto; }
.resume-preview .contact { font-size: calc(9.5 * var(--pt)); color: #333333; margin: calc(3 * var(--pt)) 0 calc(4 * var(--pt)); }
.resume-preview hr { display: none; }
.resume-preview h2 { font-size: calc(12 * var(--pt)); font-weight: 700; letter-spacing: 0.02em; color: #1f3d5c;
  margin: calc(11 * var(--pt)) 0 calc(4 * var(--pt)); padding-bottom: calc(2 * var(--pt)); line-height: 1.3;
  border-bottom: calc(0.75 * var(--pt)) solid #b9c4d0; }
.resume-preview .summary { font-style: italic; color: #262626; margin: 0 0 calc(2 * var(--pt)); }
.resume-preview .rolehead { display: flex; flex-wrap: wrap; align-items: baseline;
  margin: calc(7 * var(--pt)) 0 calc(1 * var(--pt)); color: #1a1a1a; }
.resume-preview .rolehead .company { font-weight: 700; color: #111111; font-size: calc(10.5 * var(--pt)); }
.resume-preview .rolehead .sep { white-space: pre; color: #9a9a9a; }
.resume-preview .rolehead .sep:nth-last-child(2) { display: none; }
.resume-preview .rolehead .dates { margin-left: auto; padding-left: calc(10 * var(--pt)); white-space: nowrap;
  color: #555555; font-size: calc(9.5 * var(--pt)); }
.resume-preview .context { font-style: italic; font-size: calc(9.5 * var(--pt)); color: #4a4a4a; margin: 0 0 calc(2 * var(--pt)); }
/* A name inside an already-italic line (the Summary, a context line) is set upright for contrast. */
.resume-preview .summary em.upright, .resume-preview .context em.upright { font-style: normal; }
.resume-preview p { margin: 0 0 calc(4 * var(--pt)); }
.resume-preview ul { margin: calc(1 * var(--pt)) 0 calc(4 * var(--pt)); padding-left: calc(14 * var(--pt)); }
.resume-preview li { margin: 0 0 calc(1.5 * var(--pt)); padding-left: calc(2 * var(--pt)); line-height: 1.28; color: #262626; }
.resume-preview strong { font-weight: 700; }

/* The redline (core/render.mjs redlineHtml): the tailored resume marked against the master, on
   screen only; no export ever carries a mark. Inserted words underlined in green, cut master
   words struck in red, a green bar in the margin beside a bullet with no master bullet, a left
   out master bullet struck and faint where it sat, and an orange pill on a bullet nothing in
   the master backs. Fixed colours: the sheet is white paper whatever the theme. */
.resume-preview ins.rl-ins { text-decoration: underline; text-decoration-color: #1f7a45;
  text-decoration-thickness: calc(1 * var(--pt)); text-underline-offset: calc(1.5 * var(--pt));
  color: #14532d; background: #e6f4ec; }
.resume-preview del.rl-del { text-decoration: line-through; text-decoration-color: #b3261e; color: #b3261e; }
.resume-preview li.rl-new { position: relative; }
.resume-preview li.rl-new::before { content: ""; position: absolute; top: calc(1 * var(--pt)); bottom: calc(1 * var(--pt));
  left: calc(-18 * var(--pt)); width: calc(2.5 * var(--pt)); border-radius: calc(1 * var(--pt)); background: #1f7a45; }
.resume-preview li.rl-dropped { opacity: 0.6; }
/* The collapsed left-out lines (2026-10-06, core/render.mjs droppedGroupHtml and
   droppedRoleHtml): one muted grey line at the end of a role that opens in place to show its
   left-out bullets struck in grey, and one muted line where a left-out role sat. */
.resume-preview li.rl-drops-line { list-style: none; color: #5a626c; }
.resume-preview .rl-drops-sum { cursor: pointer; color: #5a626c; font-style: normal; }
.resume-preview .rl-drops-list { margin: calc(2 * var(--pt)) 0 0; }
.resume-preview .rl-drops del.rl-del { color: #5a626c; text-decoration-color: #5a626c; }
.resume-preview p.rl-dropped-role { color: #5a626c; font-style: normal; }
.resume-preview .rl-flag { display: inline-block; margin-left: calc(2 * var(--pt)); padding: 0 calc(4 * var(--pt));
  border: calc(0.75 * var(--pt)) solid #5a626c; border-radius: 999px; background: #f1f0ec; color: #3b4048;
  font-size: calc(7.5 * var(--pt)); font-style: normal; font-weight: 700; line-height: 1.35; white-space: nowrap; }
/* Fix before export (core/claims.mjs): the same pill as .rl-flag, in the block colour. */
.resume-preview .rl-claim { display: inline-block; margin-left: calc(2 * var(--pt)); padding: 0 calc(4 * var(--pt));
  border: calc(0.75 * var(--pt)) solid var(--blocker, #b3261e); border-radius: 999px; background: var(--blocker-bg, #fdecea); color: var(--blocker, #b3261e);
  font-size: calc(7.5 * var(--pt)); font-style: normal; font-weight: 700; line-height: 1.35; white-space: nowrap; }

/* The footer on every screen (index.html). Muted, never faint. The paper with its rule edge
   to edge, the content lined up with the page's; margin-top: auto pins it to the bottom. */
.site-footer { margin-top: auto; padding: 8px var(--edge) 24px; border-top: 1px solid var(--line); background: var(--bg); font-size: var(--t-xs); }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: nowrap; gap: 0 16px; }
.site-footer a { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; padding: 0 4px; color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.site-footer a:hover { color: var(--fg); }
.site-footer a:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; color: var(--fg); }
/* The mark and name as a lockup (upright, like the top bar), sized like applicantaide.com's footer. */
/* Two rows at every width: the mark, name and links, then the copyright and the stamp. */
.foot-row { display: flex; flex-wrap: nowrap; align-items: center; gap: 0 24px; }
.foot-brand { display: flex; flex: none; align-items: center; gap: 8px; padding: 0 4px; }
.foot-logo { display: block; width: auto; height: 22px; }
.foot-name { font-weight: 600; color: var(--fg); }
/* Copyright, then the build stamp (version, commit, commit time) written in by scripts/build.mjs. */
.foot-meta { display: flex; flex-wrap: nowrap; gap: 0 16px; margin: 0; padding: 0 4px; color: var(--muted); font-size: var(--t-xs); white-space: nowrap; }
.build-stamp { font-variant-numeric: tabular-nums; }
@media print { .top, .actions, .no-print, .site-footer { display: none !important; } body { display: block; min-height: 0; } }
/* Personal mode (set on <html> by js/mode.js from the server's own /api/config). */
.mode-badge { display: none; border: 1px solid currentColor; border-radius: var(--r-pill); padding: 2px 8px; font-size: var(--t-xs); line-height: 1.4; }
html[data-mode="personal"] .mode-badge { display: inline-block; }
html[data-mode="personal"] [data-credits] { display: none !important; }

/* A phone's buttons are 44px tall. */
@media (max-width: 767px) {
  button, .view button.chip, .view button.quiet, .job-card button.quiet, .job-card button.icon-btn,
  .view .re button.doc-kw, .dm .dm-trigger { min-height: 44px; }
}
/* The top bar's links only where the bar scrolls away; from 641px it is pinned at --top-h. */
@media (max-width: 640px) {
  .top nav a, .top .buy { min-height: 44px; }
}
@media (max-width: 640px) {
  .top .brand { font-size: var(--t-sm); gap: 6px; }
  .top .brand::before { width: 34px; height: 23px; }
  main { padding: 18px 0 48px; }
  .foot-logo { height: 18px; }
  .foot-row { gap: 0 12px; }
  .site-footer ul { gap: 0 4px; }
  .foot-meta { gap: 0 12px; }
  /* A phone cannot hold the full stamp on one line: the date and time drop, the version and
     commit stay (the time is still in the markup). */
  .build-stamp time, .build-stamp .stamp-sep { display: none; }
  h1 { font-size: var(--t-lg); line-height: var(--lh-lg); letter-spacing: var(--ls-lg); }
  .panel { padding: 16px; }
  .resume-preview { padding: 8px; }
  .resume-preview .sheet + .sheet { margin-top: 10px; }
}

/* The narrowest phones (320px): smaller footer type and tighter links keep row one on one line,
   with the 44px tap height kept. */
@media (max-width: 360px) {
  .site-footer { font-size: 0.8125rem; }
  .site-footer a { padding: 0 2px; }
  .foot-row { gap: 0 8px; }
  .foot-brand { gap: 6px; }
}

/* The import screen's three ways in (views/resume.js renderImport, 2026-10-19): a file, a
   paste, or no resume yet. Equal cards with the same parts (a heading, one line, a left-aligned
   secondary button at the foot): three columns from 768px, stacked below. The whole file card is
   the drop zone (settings.js fileDropZone fills it), and the paste box opens inside the paste
   card, when the cards stack so it has the full width. */
.import-choices { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 12px; }
@media (min-width: 768px) {
  .import-choices { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .import-choices:has(.import-paste:not([hidden])) { grid-template-columns: minmax(0, 1fr); }
}
.import-card, .import-choices > .import-card > .drop-zone { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; }
.import-card { background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--r-control); padding: 14px 16px; min-height: 168px; box-sizing: border-box; }
.import-card-title { margin: 0 0 6px; font-size: var(--t-md); overflow-wrap: anywhere; }
.import-card .hint { margin: 0 0 10px; }
.import-card:has(> .drop-zone) { padding: 0; }
.import-choices > .import-card > .drop-zone {
  flex: 1 1 auto; align-self: stretch; margin: 0; padding: 14px 16px; text-align: left;
  border: 0; border-radius: inherit; background: transparent;
}
.import-choices > .import-card > .drop-zone.is-over { background: var(--accent-soft); }
.import-card:has(> .drop-zone.is-over) { border-color: var(--accent); }
/* The field's label is the card's one line, read like the other cards' lines. */
.import-choices > .import-card > .drop-zone label { margin: 0 0 10px; font-weight: 400; font-size: var(--t-xs); color: var(--ink-dim); }
.import-choices > .import-card > button, .import-choices > .import-card > .drop-zone > button { margin: auto 0 0; align-self: flex-start; }
.import-choices > .import-card > .import-paste { align-self: stretch; margin-top: 4px; }
@media (max-width: 767px) {
  .import-card button, .first-fix-item button { min-height: 44px; }
  /* app-flow.css makes every summary in main a flex box on a phone, which hides the disclosure
     marker; the format fold stays a list item and a 44px target, like the coach guide's folds. */
  .layout-note > summary { display: list-item; min-height: 44px; padding: 10px 0; box-sizing: border-box; }
}
/* The first-fix screen after an import (spec B3). */
.first-fix { list-style: none; margin: 16px 0; padding: 0; display: grid; gap: 12px; }
.first-fix-item { border: 1px solid var(--line); border-radius: var(--r-control); padding: 12px 14px; background: var(--panel-2); }
.first-fix-title { margin: 0 0 6px; font-size: var(--t-md); }
.first-fix-item p { margin: 0 0 8px; overflow-wrap: anywhere; }
.first-fix-line { font-size: var(--t-xs); color: var(--ink-dim); border-left: 3px solid var(--line-strong); padding-left: 8px; }
/* The quiet way on lines up with the cards' left edge (no inset from its pill padding). */
.first-fix-actions > button.quiet { padding-left: 0; padding-right: 0; }

/* Loading skeletons (2026-10-20, views/skeleton.js): grey shapes laid out like the job page, the
   jobs list and the Resume tab, mounted by the route loader when a view is slow. No text, so no
   contrast pair; the shapes are --line on the page and --panel-2 on a panel. A fade in and a
   slow opacity pulse, both stopped under reduced motion. */
.skel { pointer-events: none; user-select: none; }
.skel-frame { animation: skel-in var(--dur-base) var(--ease-out); }
@keyframes skel-in { from { opacity: 0; } }
.skel-line, .skel-block { display: block; background: var(--line); border-radius: 4px; }
.skel-line { width: 100%; height: 15px; }
.skel .skel-line, .skel .skel-block, .skel .re-ph-line { animation: skel-pulse calc(var(--dur-base) * 8) ease-in-out infinite; }
@keyframes skel-pulse { 50% { opacity: 0.5; } }
.skel-w-70 { width: 70%; }
.skel-w-45 { width: 45%; }
.skel-w-30 { width: 30%; }
.skel-pill { width: 160px; height: 40px; border-radius: var(--r-pill); }
.skel-title { height: var(--t-xl); border-radius: var(--r-control); }
/* The job page: header, the raised next-step card, the sheet. */
.skel-head { display: flex; align-items: flex-start; gap: 16px; margin: 0 0 24px; }
.skel-logo { flex: none; width: 60px; height: 60px; border-radius: var(--r-control); }
.skel-head-text { flex: 1 1 auto; min-width: 0; display: grid; gap: 10px; }
.skel-eyebrow { width: 32%; height: 13px; }
.skel-head .skel-title { width: 55%; }
.skel-meta { width: 40%; }
.skel-steps { width: 36%; height: 24px; margin-top: 6px; }
.skel-status { width: 48%; height: 32px; border-radius: var(--r-pill); margin-top: 6px; }
.skel-about { display: grid; gap: 10px; margin: 0 0 32px; }
.skel-about-h { width: 180px; height: var(--t-md); }
.skel-next { display: grid; gap: 12px; margin: 0 0 24px; padding: 24px; background: var(--panel); border-radius: var(--r-card); box-shadow: var(--shadow-card); }
.skel-next .skel-line, .skel-next .skel-block { background: var(--panel-2); }
.skel-next-title { width: 50%; height: var(--t-lg); }
.skel-next .skel-pill { margin-top: 4px; }
/* The jobs list: the real list grid and card box, grey content. */
.skel-titlerow { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin: 0 0 16px; }
.skel-titlerow > .skel-title, .skel-resume > .skel-title { width: min(240px, 60%); }
.skel-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.skel-chip { width: 72px; height: 32px; border-radius: var(--r-pill); }
.skel-jobcard .skel-line, .skel-jobcard .skel-block { background: var(--panel-2); }
.skel-card-logo { grid-column: 1; grid-row: 1; width: var(--card-logo); height: var(--card-logo); border-radius: var(--r-control); }
.skel-card-main { grid-column: 2 / -1; grid-row: 1; min-width: 0; display: grid; gap: 7px; padding-bottom: 32px; }
.skel-company { width: 45%; height: 13px; }
.skel-role { width: 75%; height: var(--t-md); }
.skel-cardmeta { width: 60%; height: 13px; }
/* The Resume tab: title, tab row, sheet. */
.skel-resume > .skel-title { margin: 0 0 16px; }
.skel-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.skel-tab { width: 120px; height: 36px; border-radius: var(--r-pill); }
.skel-page > .skel-line + .skel-line { margin-top: 12px; }
@media (max-width: 640px) {
  .skel-title { height: var(--t-lg); }
  .skel-logo { width: 54px; height: 54px; }
  .skel-next { padding: 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .skel-frame, .skel .skel-line, .skel .skel-block, .skel .re-ph-line { animation: none; }
}

/* A disclosure drawn as a quiet button (views/ui.js disclosure: Show N more, the ratings
   breakdown): accent text and a caret that turns when open, so it reads as something to press. */
button.disclosure { display: inline-flex; align-items: center; gap: 6px; color: var(--accent); font-weight: 600; }
.disclosure-caret { display: inline-block; transition: transform var(--dur-fast) var(--ease-out); }
.disclosure-caret.is-open { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .disclosure-caret { transition: none; } }
