/* =====================================================================
   HireHub — design system
   Layout language follows the Indian job-board convention (Naukri et al):
   a white sticky top bar, a blue hero with an inline segmented search,
   dense white result cards with skill chips, and a left filter rail.
   ===================================================================== */

/* ---------- tokens --------------------------------------------------
   Palette sampled from naukri.com's own computed styles, so the blues,
   greys and CTA red match the reference rather than approximating it.
   ------------------------------------------------------------------- */
:root {
  --brand-50:  #edf4ff;   /* tinted surfaces, chips */
  --brand-100: #dbe7ff;
  --brand-200: #b8ceff;
  --brand-300: #7ca3fa;
  --brand-400: #4a7cf7;
  --brand-500: #275df5;   /* primary — naukri blue */
  --brand-600: #1e4bd8;
  --brand-700: #1739a8;
  --brand-800: #122b7d;

  /* CTA red-orange: reserved for the single most important action on a
     page (Register, Apply). Using it anywhere else destroys its meaning. */
  --cta-500: #de370d;
  --cta-600: #c22f0a;
  --cta-50:  #fff1ed;

  --ok-50:  #e9f7ea;  --ok-500:  #2e9b31;  --ok-600: #218024;
  --warn-50:#fff6e0;  --warn-500:#b57b00;  --warn-600:#946400;
  --bad-50: #fdecea;  --bad-500: #d93a22;  --bad-600: #b52f1b;
  --info-50:#edf4ff;  --info-500:#275df5;

  /* Accent hues for category tiles, stat cards and avatars. Colour here is
     decorative and must never be the only carrier of meaning. */
  --violet-50:#f3ecff; --violet-500:#8951ff;
  --teal-50:  #e3f7f6; --teal-500:  #0e9b93;
  --amber-50: #fff5db; --amber-500: #d99400;
  --pink-50:  #ffecf3; --pink-500:  #e0417a;
  --lime-50:  #eefae0; --lime-500:  #5c9a12;
  --sky-50:   #e6f5ff; --sky-500:   #0b83d9;

  /* Darker pair for small text on the -50 tints: violet-500 and sky-500
     land near 4:1 on their own wash, which is short of AA at chip sizes. */
  --violet-600: #6b2fd6;
  --sky-600:    #0a5f9e;

  --ink-900: #121224;   /* headings */
  --ink-800: #1b2437;
  --ink-700: #474d6a;   /* body */
  --ink-600: #5b6285;
  --ink-500: #717b9e;   /* muted */
  --ink-400: #979ec2;

  --surface:      #ffffff;
  --surface-sunk: #f7f7f9;
  --surface-alt:  #fbfbfd;
  --line:         #e7e7f1;
  --line-strong:  #d3d4e3;

  --shadow-sm: 0 1px 2px rgba(16, 21, 31, .06);
  --shadow-md: 0 2px 8px rgba(16, 21, 31, .08);
  --shadow-lg: 0 8px 28px rgba(16, 21, 31, .12);

  --r-sm: 4px;  --r-md: 8px;  --r-lg: 12px;  --r-pill: 999px;

  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;

  /* Body/UI stack, then the display stack for headings. The system fonts stay
     as the fallback so nothing reflows into something unreadable if a woff2
     fails to load. */
  --font: 'InterVar', "Segoe UI", Roboto, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --font-display: 'Jakarta', 'InterVar', "Segoe UI", Roboto, -apple-system, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", Consolas, "Courier New", monospace;

  --shell-nav: 236px;
  --topbar-h:  60px;
}

/* ---------- type -----------------------------------------------------
   Self-hosted variable fonts, latin subset. Two files, 80 KB total — Google
   serves one variable file per family for a multi-weight request, so every
   weight from 400 to 800 comes out of the same download.

   Self-hosted rather than linked to fonts.googleapis.com: it removes a
   third-party request from every page load, keeps the app working with no
   internet, and avoids sending visitor IPs to Google.

   Two families, each doing one job:
     Plus Jakarta Sans — headings and numbers. Geometric with a tall x-height,
                         so large type has character the old system stack
                         (Segoe UI) never had.
     Inter             — body, forms, tables. Designed for small sizes on
                         screen, which is what the admin data grids need.
   ------------------------------------------------------------------- */
@font-face {
  font-family: 'Jakarta';
  src: url('../fonts/jakarta-var.woff2') format('woff2');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'InterVar';
  src: url('../fonts/inter-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Headings and display type take Jakarta; everything else inherits Inter
   from body. Grouped in one place so the pairing is a single decision. */
h1, h2, h3, h4, h5, h6,
.hero__trio, .hero__hook,
.page-head__title, .card__title,
.aiband__title, .capband__title, .cap__head,
.corail__title, .qphero__title,
.tile__value, .statbar__v,
.slide__title, .empty__title, .shotline {
  font-family: var(--font-display);
  letter-spacing: -.02em;
}

/* ---------- reset --------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-800);
  background: var(--surface-sunk);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5 { margin: 0 0 var(--sp-3); line-height: 1.25; color: var(--ink-900); font-weight: 600; }
h1 { font-size: 26px; }
h2 { font-size: 20px; }
h3 { font-size: 17px; }
h4 { font-size: 15px; }
p  { margin: 0 0 var(--sp-3); }

a { color: var(--brand-500); text-decoration: none; }
a:hover { text-decoration: underline; }

img { max-width: 100%; height: auto; display: block; }

:focus-visible {
  outline: 2px solid var(--brand-400);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* Screen-reader-only, but focusable (skip links) */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link:focus {
  position: fixed; top: 8px; left: 8px; z-index: 200;
  width: auto; height: auto; clip: auto; margin: 0;
  padding: var(--sp-2) var(--sp-4); background: var(--surface);
  box-shadow: var(--shadow-lg); border-radius: var(--r-md);
}

/* ---------- layout helpers ------------------------------------------ */
.container { width: min(1200px, 100% - 32px); margin-inline: auto; }
.container--narrow { width: min(760px, 100% - 32px); }
.container--wide   { width: min(1440px, 100% - 32px); }

.stack > * + * { margin-top: var(--sp-3); }
.row { display: flex; gap: var(--sp-3); }
.row--between { justify-content: space-between; }
.row--center  { align-items: center; }
.row--wrap    { flex-wrap: wrap; }
/* flex-basis 0, not auto: with `auto` the browser uses this column's
   CONTENT width to decide whether the flex line fits, so a column full of
   wide cards claims the whole row and pushes a fixed-width sidebar onto
   the next line. Basing it on 0 means only an explicit min-width counts
   toward line-breaking, which is what the sidebar layouts expect. */
.grow { flex: 1 1 0%; min-width: 0; }

.muted { color: var(--ink-600); }
.small { font-size: 12.5px; }
.strong { font-weight: 600; }
.nowrap { white-space: nowrap; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-right { text-align: right; }
.text-center { text-align: center; }

/* ---------- top bar ------------------------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  height: var(--topbar-h);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
.topbar__inner { display: flex; align-items: center; gap: var(--sp-5); height: 100%; }

.brand { display: flex; align-items: center; gap: var(--sp-2); font-size: 19px; font-weight: 700; color: var(--brand-500); }
.brand:hover { text-decoration: none; }
.brand__mark {
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--brand-500), var(--brand-400));
  color: #fff; font-size: 15px; font-weight: 700;
}
.brand__mark--accent { background: linear-gradient(135deg, var(--cta-500), #f7794e); }

.topnav { display: flex; align-items: center; gap: var(--sp-1); margin-left: auto; }
.topnav__link {
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  color: var(--ink-700); font-weight: 500;
}
.topnav__link:hover { background: var(--surface-sunk); text-decoration: none; color: var(--brand-500); }
.topnav__link.is-active { color: var(--brand-500); background: var(--brand-50); }

/* avatar + dropdown */
.avatar {
  display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--brand-100); color: var(--brand-600);
  font-size: 12.5px; font-weight: 700; letter-spacing: .3px; flex: none;
}
.avatar--lg { width: 56px; height: 56px; font-size: 18px; }
.avatar--sm { width: 28px; height: 28px; font-size: 11px; }

.menu { position: relative; }
.menu__toggle {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2); border: 0; background: none;
  border-radius: var(--r-pill); cursor: pointer; font: inherit; color: var(--ink-800);
}
.menu__toggle:hover { background: var(--surface-sunk); }
.menu__panel {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 220px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--shadow-lg);
  padding: var(--sp-2); display: none; z-index: 60;
}
.menu.is-open .menu__panel { display: block; }
.menu__head { padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--line); margin-bottom: var(--sp-2); }
.menu__item {
  display: block; padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm); color: var(--ink-700);
}
.menu__item:hover { background: var(--surface-sunk); text-decoration: none; }
.menu__item--danger { color: var(--bad-500); }

/* ---------- buttons ------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: 9px 18px; border-radius: var(--r-pill);
  border: 1px solid transparent; background: var(--brand-500); color: #fff;
  font: inherit; font-weight: 600; line-height: 1.2;
  cursor: pointer; white-space: nowrap;
  transition: background .15s ease, border-color .15s ease, color .15s ease, transform .05s ease;
}
.btn:hover { background: var(--brand-600); text-decoration: none; color: #fff; }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn.is-disabled { opacity: .55; pointer-events: none; }

/* The one high-emphasis action per page (Register, Apply). */
.btn--accent  { background: var(--cta-500); }
.btn--accent:hover { background: var(--cta-600); }
.btn--ghost   { background: transparent; border-color: var(--brand-500); color: var(--brand-500); }
.btn--ghost:hover { background: var(--brand-50); color: var(--brand-600); }
.btn--subtle  { background: var(--surface-sunk); color: var(--ink-700); border-color: var(--line); }
.btn--subtle:hover { background: var(--line); color: var(--ink-900); }
.btn--danger  { background: var(--bad-500); }
.btn--danger:hover { background: #9e2525; }
.btn--sm { padding: 6px 13px; font-size: 13px; }
.btn--lg { padding: 12px 26px; font-size: 15px; }
.btn--block { width: 100%; }
.btn--square { border-radius: var(--r-md); }

/* ---------- cards --------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.card__head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: 13px var(--sp-4);
  border-bottom: 1px solid var(--line);
}
.card__title { margin: 0; font-size: 16px; }
.card__body { padding: var(--sp-4); }
.card__body--tight { padding: 13px var(--sp-4); }
.card__foot {
  padding: 11px var(--sp-4);
  border-top: 1px solid var(--line);
  background: var(--surface-alt);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* ---------- whole-card click target ---------------------------------
   The card's title stays a real <a>; a transparent ::after stretches it
   over the whole card. That keeps proper link semantics — middle-click,
   ctrl-click, "copy link address", one focus stop in the tab order —
   which a JS click handler on the container would all break, and avoids
   the invalid nested-interactive markup a wrapping <a> would produce.

   Everything else interactive inside the card is lifted above the
   overlay so phone, email, CV download and buttons still work.        */
.jobcard, .crow { position: relative; }
.jobcard__title a::after,
.crow__name a::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  border-radius: inherit;
}
.jobcard:hover, .crow:hover { cursor: pointer; }

/* Nested controls sit above the stretched overlay. */
.jobcard a:not(.jobcard__title a),
.jobcard button, .jobcard form, .jobcard input, .jobcard select, .jobcard label,
.crow a:not(.crow__name a),
.crow button, .crow form, .crow input, .crow select, .crow label {
  position: relative; z-index: 2;
}

/* Text stays selectable above the overlay where it matters. */
.jobcard__desc, .jobcard__meta, .crow__facts { position: relative; z-index: 2; }

/* Pill-shaped controls are sometimes rendered as a <span> in their
   disabled state ("No resume"), which the element selectors above miss.
   Lift them by class so the row never has an inert dead patch. */
.jobcard .rlink, .jobcard .cbtn, .jobcard .chips,
.crow .rlink, .crow .cbtn, .crow .chips,
.crow .contactrow, .jobcard .contactrow { position: relative; z-index: 2; }

/* ---------- job / candidate result cards ---------------------------- */
.jobcard {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--sp-4) 18px;
  transition: box-shadow .15s ease, border-color .15s ease;
}
.jobcard:hover { box-shadow: var(--shadow-md); border-color: var(--line-strong); }
.jobcard__top { display: flex; gap: var(--sp-4); align-items: flex-start; justify-content: space-between; }
.jobcard__i { color: var(--ink-400); font-size: 12px; }
.jobcard__skills {
  margin: 0 0 var(--sp-3); font-size: 12.5px; color: var(--ink-600); line-height: 1.9;
}
.jobcard__skills a { color: var(--ink-600); }
.jobcard__skills a:hover { color: var(--brand-500); }
.jobcard__dot { color: var(--ink-400); margin: 0 7px; }
/* A chip block sitting above the card footer needs clearance from the
   dashed rule — whether it wrapped or not.
   NB: no :last-child exception here. The chips ARE the last child of
   their wrapper, so resetting the margin on :last-child cancelled the
   spacing in exactly the case it was written for. */
.jobcard .chips { margin-bottom: var(--sp-4); }

/* Same for a chip block that ends a card body or a profile section. */
.card__body > .chips:last-child,
.psection__body > .chips:last-child,
.field > .chips { padding-bottom: 2px; }

/* Chip input: once tokens exist they sit between the text box and the
   hint, and the hint's own 5px top margin is not enough separation.
   :not(:empty) so an unused input doesn't gain a phantom gap. */
[data-chip-input] [data-chip-list]:not(:empty) { margin-bottom: var(--sp-3); }

.jobcard__save {
  border: 0; background: none; cursor: pointer; font: inherit; font-size: 12.5px;
  color: var(--ink-600); padding: 2px 4px; border-radius: var(--r-sm);
}
.jobcard__save:hover { color: var(--brand-500); background: var(--brand-50); }
.jobcard__logo {
  width: 46px; height: 46px; border-radius: var(--r-md); flex: none;
  display: grid; place-items: center;
  background: var(--surface-sunk); border: 1px solid var(--line);
  color: var(--ink-600); font-weight: 700; font-size: 15px; overflow: hidden;
}
.jobcard__title { font-size: 16px; margin: 0 0 2px; }
.jobcard__title a { color: var(--ink-900); }
.jobcard__title a:hover { color: var(--brand-500); }
.jobcard__company { color: var(--ink-600); font-size: 13.5px; }
.jobcard__meta {
  display: flex; flex-wrap: wrap; gap: 6px var(--sp-4);
  margin: 10px 0; color: var(--ink-700); font-size: 13px;
}
.jobcard__meta span { display: inline-flex; align-items: center; gap: 6px; }
.jobcard__desc { color: var(--ink-600); font-size: 13px; margin: 0 0 var(--sp-3); }
.jobcard__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding-top: var(--sp-4); border-top: 1px dashed var(--line);
  font-size: 12.5px; color: var(--ink-500);
}

/* ---------- chips & badges ------------------------------------------ */
/* Row gap is larger than the column gap: wrapped chip rows need more
   vertical separation than neighbouring chips need horizontal, or the
   block reads as one dense mass. */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); row-gap: 7px; align-content: flex-start; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 11px; border-radius: var(--r-pill);
  background: var(--surface-sunk); border: 1px solid var(--line);
  color: var(--ink-700); font-size: 12.5px; white-space: nowrap;
}
.chip--brand { background: var(--brand-50); border-color: var(--brand-100); color: var(--brand-600); }
.chip--more  { background: transparent; border-style: dashed; color: var(--ink-500); }
.chip__x {
  border: 0; background: none; cursor: pointer; padding: 0 0 0 2px;
  color: inherit; font-size: 14px; line-height: 1; opacity: .6;
}
.chip__x:hover { opacity: 1; }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 10px; border-radius: var(--r-pill);
  font-size: 12px; font-weight: 600; white-space: nowrap;
}
.badge--ok    { background: var(--ok-50);   color: var(--ok-500); }
.badge--warn  { background: var(--warn-50); color: var(--warn-500); }
.badge--bad   { background: var(--bad-50);  color: var(--bad-500); }
.badge--info  { background: var(--info-50); color: var(--info-500); }
.badge--muted { background: var(--surface-sunk); color: var(--ink-600); }

.dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }

/* ---------- forms --------------------------------------------------- */
.field { margin-bottom: 14px; }
.field__label {
  display: block; margin-bottom: 6px;
  font-size: 13px; font-weight: 600; color: var(--ink-700);
}
.field__label .req { color: var(--bad-500); }
.field__hint { display: block; margin-top: 5px; font-size: 12.5px; color: var(--ink-500); }
.field__error { display: block; margin-top: 5px; font-size: 12.5px; color: var(--bad-500); }

.input, .select, .textarea {
  width: 100%; padding: 9px 12px;
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink-900);
  font: inherit; line-height: 1.4;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink-400); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--brand-400);
  box-shadow: 0 0 0 3px var(--brand-50);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-400); }
.input:disabled, .select:disabled, .textarea:disabled { background: var(--surface-sunk); color: var(--ink-500); }
.textarea { min-height: 110px; resize: vertical; }
.select { appearance: none; padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%235a6478' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 13px center;
}
.is-invalid { border-color: var(--bad-500) !important; }
.is-invalid:focus { box-shadow: 0 0 0 3px var(--bad-50) !important; }

.check { display: flex; align-items: flex-start; gap: var(--sp-2); cursor: pointer; font-size: 13.5px; }
.check input { margin-top: 3px; accent-color: var(--brand-500); flex: none; }

.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 var(--sp-4); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 var(--sp-4); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-4); }

.fieldset { border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--sp-4); margin: 0 0 var(--sp-5); }
.fieldset > legend { padding: 0 var(--sp-2); font-size: 13px; font-weight: 700; color: var(--ink-700); text-transform: uppercase; letter-spacing: .4px; }

/* ---------- hero + segmented search --------------------------------- */
/* Light hero — the reference boards keep this airy and put the colour in
   the category tiles below rather than in a heavy coloured band. */
/* Background artwork with a white scrim over it. The scrim is what keeps
   body text and the search field readable — an illustration behind live
   text needs a wash, not just low opacity on the art itself. The image is
   decorative, so it lives in CSS rather than as an <img>. */
.hero {
  /* Dark bed, light type. A white scrim strong enough to keep dark text
     readable also washes the photograph out — which is why the image looked
     absent. Going the other way keeps the picture at full strength and moves
     the text to white, where contrast climbs as the overlay deepens. */
  /* Gradient rather than a flat fill: a single dark colour behind a glass
     search field looks like an unstyled block. */
  background:
    radial-gradient(120% 90% at 50% -10%, #1b2b6b 0%, rgba(27,43,107,0) 62%),
    linear-gradient(170deg, #0a1024 0%, #0b1226 45%, #070c1c 100%);
  /* sp-5 rather than sp-7: the companies rail has to clear the fold on a
     ~700px viewport, and 24px of band padding either side buys 48 of it. */
  padding: var(--sp-5) 0;
  position: relative; overflow: hidden;
}
/* Fine dot texture, drawn in CSS so it stays crisp at any width and fades
   out before it reaches the headline. */
.hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  z-index: 2;
  background-image:
    linear-gradient(to right, rgba(255,255,255,.03) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.03) 1px, transparent 1px);
  background-size: 86px 86px;
  /* Fades before it reaches the headline so the grid never crosses the type. */
  mask-image: radial-gradient(100% 78% at 50% 42%, transparent 22%, #000 82%);
  -webkit-mask-image: radial-gradient(100% 78% at 50% 42%, transparent 22%, #000 82%);
}
.hero > * { position: relative; z-index: 3; }   /* above aurora (1) and grid (2) */
/* Split: message and search on the left, the product on the right. Wider than
   the old centred measure because it now carries two columns. */
.hero__inner {
  max-width: 1180px; margin-inline: auto;
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: var(--sp-6) var(--sp-7); align-items: center;
}
.herosplit__text { text-align: left; min-width: 0; }
.herosplit__text .hero__trio,
.herosplit__text .hero__cta { justify-content: flex-start; }
.herosplit__text .hero__hook,
.herosplit__text .hero__lede { margin-left: 0; margin-right: 0; }

/* One column below 980px: two columns of this content would leave the frame
   too narrow for a job row to be legible. */
@media (max-width: 980px) {
  .hero__inner { grid-template-columns: 1fr; }
  .shotwrap { display: none; }
  .herosplit__text { text-align: center; }
  .herosplit__text .hero__trio,
  .herosplit__text .hero__cta { justify-content: center; }
  .herosplit__text .hero__hook,
  .herosplit__text .hero__lede { margin-inline: auto; }
}

.searchbar {
  display: flex; align-items: stretch; gap: 0;
  background: var(--surface); border-radius: var(--r-pill);
  padding: 6px 6px 6px var(--sp-4); box-shadow: var(--shadow-lg);
  position: relative; z-index: 1;
}
.searchbar__seg { display: flex; align-items: center; gap: var(--sp-2); flex: 1 1 0; min-width: 0; padding: 0 var(--sp-3); }
.searchbar__seg + .searchbar__seg { border-left: 1px solid var(--line); }
.searchbar__seg input, .searchbar__seg select {
  border: 0; outline: none; width: 100%; font: inherit; font-size: 14px;
  background: transparent; color: var(--ink-900); padding: 10px 0;
}
.searchbar__icon { color: var(--ink-400); flex: none; }
.searchbar .btn { flex: none; }

.hero__stats {
  display: flex; gap: var(--sp-6); margin-top: var(--sp-5);
  flex-wrap: wrap; justify-content: center;
}
.hero__stat b { display: block; font-size: 22px; color: var(--ink-900); }
.hero__stat span { color: var(--ink-500); font-size: 13px; }


/* ---------- dashboard shell ----------------------------------------- */
.app-shell { background: var(--surface-sunk); }
.shell { display: flex; align-items: flex-start; gap: var(--sp-4); padding: var(--sp-4) 0; }

.sidenav {
  width: var(--shell-nav); flex: none;
  position: sticky; top: calc(var(--topbar-h) + var(--sp-4));
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 10px; box-shadow: var(--shadow-sm);
}
.sidenav__group + .sidenav__group { margin-top: var(--sp-3); }
.sidenav__label {
  padding: 0 var(--sp-3) var(--sp-2);
  font-size: 11px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: var(--ink-500);
}
.sidenav__link {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: var(--r-md);
  color: var(--ink-700); font-weight: 500; font-size: 13.5px;
}
.sidenav__link:hover { background: var(--surface-sunk); color: var(--brand-500); text-decoration: none; }
.sidenav__link.is-active { background: var(--brand-50); color: var(--brand-600); font-weight: 600; }
.sidenav__link .count { margin-left: auto; font-size: 12px; color: var(--ink-500); }
.sidenav__icon { width: 18px; text-align: center; flex: none; opacity: .8; }

.shell__main { flex: 1 1 auto; min-width: 0; }

.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-4);
}
.page-head__title { margin: 0 0 4px; }
.page-head__sub { color: var(--ink-600); margin: 0; font-size: 13.5px; }

/* ---------- dashboard welcome band -----------------------------------
   A coloured band instead of dark text on grey. Dashboards open on numbers
   and empty states, both of which are pale by nature, so the greeting is
   where the colour has to come from — without it the whole screen reads as
   an unstyled report.

   Its own class, not a change to .page-head: every admin list and form uses
   that, and they should stay quiet. */
.page-hero {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-5); margin-bottom: var(--sp-4);
  border-radius: var(--r-lg); color: #fff;
  /* Bright brand blue, not navy. It started at #122b7d and read as a heavy
     dark slab; this runs brand-600 -> brand-500 -> brand-400 instead.
     The floor matters — white text against each stop, measured:
       brand-600  6.88:1   brand-500  5.29:1   brand-400  3.81:1
     Only the first two clear AA for body text, so the light end is kept to
     the right of the band, where the buttons sit and no small text does. */
  background:
    radial-gradient(120% 150% at 90% 4%, rgba(137, 81, 255, .42), transparent 60%),
    linear-gradient(115deg, var(--brand-600) 0%, var(--brand-500) 46%, var(--brand-400) 100%);
  box-shadow: 0 12px 30px rgba(39, 93, 245, .28);
}
/* Same dot texture as the auth canvas, masked so it never reaches the type. */
.page-hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: radial-gradient(rgba(255, 255, 255, .16) 1px, transparent 1px);
  background-size: 20px 20px;
  mask-image: radial-gradient(110% 80% at 20% 15%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(110% 80% at 20% 15%, #000 30%, transparent 78%);
}
/* The stock .btn--glass is built for the home hero's near-black bed, where a
   12% white fill is enough to read. On this much brighter blue it disappeared
   — so the secondary action gets a stronger fill and a near-solid border
   here. It still stays clearly below the solid-white primary beside it. */
.page-hero .btn--glass {
  background: rgba(255, 255, 255, .2);
  border-color: rgba(255, 255, 255, .72);
  color: #fff; font-weight: 700;
}
.page-hero .btn--glass:hover { background: rgba(255, 255, 255, .32); border-color: #fff; }

.page-hero__title { margin: 0 0 5px; color: #fff; font-size: clamp(21px, 2.1vw, 28px); line-height: 1.15; }
.page-hero__sub { margin: 0; font-size: 14px; color: rgba(255, 255, 255, .9); }
.page-hero .row { flex-wrap: wrap; }

/* ---------- stat tiles ---------------------------------------------- */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--sp-3); }
.tile {
  position: relative;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 16px var(--sp-4);
  box-shadow: var(--shadow-sm);
  transition: transform .16s ease, box-shadow .16s ease;
}
.tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
@media (prefers-reduced-motion: reduce) {
  .tile, .tile:hover { transition: none; transform: none; }
}
.tile__label { font-size: 12.5px; color: var(--ink-600); margin-bottom: 6px; display: block; }
.tile__value { font-size: 26px; font-weight: 700; color: var(--ink-900); line-height: 1.1; }
.tile__delta { font-size: 12.5px; margin-top: 4px; }
.tile__delta--up { color: var(--ok-500); }
.tile__delta--down { color: var(--bad-500); }
.tile--brand { border-left: 3px solid var(--brand-500); }
.tile--ok    { border-left: 3px solid var(--ok-500); }
.tile--warn  { border-left: 3px solid var(--warn-500); }
.tile--bad   { border-left: 3px solid var(--bad-500); }

/* ---------- AI suggestion cards --------------------------------------
   One card per suggested candidate: who, how well they fit, and why. The
   score gets a band word beside it as well as a number, so the ranking is
   never carried by colour or by a bare percentage alone. */
.suggests { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: var(--sp-3); }
.suggest { transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
.suggest:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--brand-200); }
.suggest__name { display: block; font-weight: 700; color: var(--ink-900); }
.suggest__name:hover { color: var(--brand-600); }
.suggest__score { flex: none; text-align: right; display: grid; gap: 4px; justify-items: end; }
.suggest__pct {
  font-family: var(--font-display); font-size: 22px; font-weight: 800;
  line-height: 1; color: var(--brand-600);
}
.suggest__pct span { font-size: 12px; font-weight: 700; color: var(--ink-400); margin-left: 1px; }

.suggest__why { display: flex; flex-wrap: wrap; gap: 6px; margin: var(--sp-3) 0 0; }
.suggest__reason {
  font-size: 12px; padding: 4px 10px; border-radius: var(--r-pill);
  background: var(--brand-50); color: var(--brand-700); border: 1px solid var(--brand-100);
}
.suggest__foot { gap: var(--sp-2); margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--line); }

@media (prefers-reduced-motion: reduce) {
  .suggest, .suggest:hover { transition: none; transform: none; }
}

/* ---------- tables -------------------------------------------------- */
.table-wrap { overflow-x: auto; border-radius: var(--r-lg); }
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; background: var(--surface); }
.table th, .table td { padding: 9px 14px; text-align: left; vertical-align: middle; }
.table thead th {
  background: var(--surface-alt); color: var(--ink-600);
  font-size: 11.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase;
  border-bottom: 1px solid var(--line); white-space: nowrap; position: sticky; top: 0; z-index: 1;
}
.table tbody tr { border-bottom: 1px solid var(--line); }
.table tbody tr:last-child { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-alt); }
.table--fixed { table-layout: fixed; }
.table__actions { display: flex; gap: var(--sp-2); justify-content: flex-end; }
.table td.num, .table th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- profile-update landing page ------------------------------
   The page the bulk-email link lands on. It has to justify the ask in a
   few seconds, so the header states who we think they are and how far
   along they already are, and the flow strip shows what filling it in
   actually leads to. */
.plhead {
  position: relative; overflow: hidden;
  border-radius: var(--r-lg); box-shadow: var(--shadow-md);
  background:
    radial-gradient(520px 200px at 8% -30%, rgba(255,255,255,.55), transparent 70%),
    radial-gradient(460px 190px at 92% 120%, rgba(255,255,255,.35), transparent 68%),
    linear-gradient(122deg, var(--brand-600), var(--brand-500) 46%, var(--violet-500));
  color: #fff; padding: var(--sp-5);
  margin-bottom: var(--sp-4);
}
.plhead::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(118deg, rgba(255,255,255,.07) 0 2px, transparent 2px 20px);
}
.plhead__grid {
  position: relative; display: grid; gap: var(--sp-5);
  grid-template-columns: minmax(0, 1fr) auto; align-items: center;
}
.plhead__title { color: #fff; font-size: 26px; margin: 0 0 6px; letter-spacing: -.3px; }
.plhead__sub { color: rgba(255,255,255,.85); margin: 0; font-size: 14.5px; max-width: 52ch; }
.plhead__badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 12px; border-radius: var(--r-pill);
  background: rgba(255,255,255,.18); color: #fff;
  font-size: 12.5px; font-weight: 600; margin-bottom: var(--sp-3);
}

/* completeness dial on the header */
.dial { position: relative; display: grid; place-items: center; }
.dial__track { stroke: rgba(255,255,255,.25); }
.dial__bar   { stroke: #fff; transition: stroke-dashoffset .8s ease; }
.dial__label { position: absolute; text-align: center; color: #fff; }
.dial__pct   { display: block; font-size: 26px; font-weight: 700; line-height: 1; }
.dial__cap   { display: block; font-size: 11px; opacity: .8; }

/* three-step "what happens next" strip */
.flow {
  display: grid; gap: 10px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-bottom: var(--sp-4);
}
.flowstep {
  position: relative; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 13px var(--sp-3); text-align: center;
}
.flowstep__icon {
  width: 44px; height: 44px; border-radius: 50%; margin: 0 auto var(--sp-2);
  display: grid; place-items: center; font-size: 19px;
}
.flowstep__n {
  position: absolute; top: 10px; left: 12px;
  font-size: 11px; font-weight: 700; color: var(--ink-400);
}
.flowstep__t { font-size: 13.5px; font-weight: 700; color: var(--ink-900); margin-bottom: 2px; }
.flowstep__d { font-size: 12.5px; color: var(--ink-600); margin: 0; }

/* "what recruiters filter on" checklist */
.whylist { display: flex; flex-direction: column; gap: var(--sp-2); }
.whyrow {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 9px var(--sp-3); border-radius: var(--r-md);
  background: var(--surface-sunk); font-size: 13px;
}
.whyrow__i { width: 26px; height: 26px; border-radius: 7px; display: grid; place-items: center; font-size: 12px; flex: none; }
.whyrow__s { margin-left: auto; font-size: 11.5px; font-weight: 700; }
.whyrow--done { background: var(--ok-50); }
.whyrow--done .whyrow__s { color: var(--ok-500); }
.whyrow--todo .whyrow__s { color: var(--warn-500); }

@media (max-width: 780px) {
  .plhead__grid { grid-template-columns: 1fr; }
  .flow { grid-template-columns: 1fr; }
}

/* ---------- hero: asymmetric split ----------------------------------
   Deliberately NOT the centred-headline + single-pill-search layout the
   big Indian boards use. This is left-aligned and asymmetric: copy and a
   panelled search card on one side, a visual on the other. The search
   fields are stacked and individually labelled rather than fused into
   one pill, which also reads better on mobile and for screen readers. */
.hero--split { text-align: left; padding: var(--sp-7) 0; }
.hero__grid {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: var(--sp-7); align-items: center;
}

/* the search panel */
.hsearch {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
  padding: var(--sp-5); margin-top: var(--sp-5);
  border-top: 4px solid var(--brand-500);
}
.hsearch__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.hsearch__full { grid-column: 1 / -1; }
.hsearch__label {
  display: block; font-size: 11.5px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: var(--ink-500); margin-bottom: 5px;
}
.hsearch__row { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-4); }
.hsearch__hint { font-size: 12.5px; color: var(--ink-500); }

/* quick links under the panel */
.qlinks { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-4); align-items: center; }
.qlink {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 13px; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid var(--line);
  font-size: 12.5px; font-weight: 500; color: var(--ink-700);
}
.qlink:hover { text-decoration: none; border-color: var(--brand-300); color: var(--brand-600); box-shadow: var(--shadow-sm); }
.qlink__dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }

/* stat strip */
.hstats {
  display: flex; gap: var(--sp-6); flex-wrap: wrap;
  margin-top: var(--sp-5); padding-top: var(--sp-5);
  border-top: 1px dashed var(--line-strong);
}
.hstat b { display: block; font-size: 21px; color: var(--ink-900); line-height: 1.1; }
.hstat span { font-size: 12.5px; color: var(--ink-500); }

/* right-hand visual */
.hero__visual { position: relative; display: grid; place-items: center; }
.hero__visual svg { width: 100%; height: auto; max-width: 430px; }

@media (max-width: 980px) {
  .hero__grid { grid-template-columns: 1fr; gap: var(--sp-5); }
  .hero__visual { display: none; }   /* decorative only */
}
@media (max-width: 560px) {
  .hsearch__grid { grid-template-columns: 1fr; }
  .hsearch__row { flex-direction: column; align-items: stretch; }
}

/* ---------- hero slideshow ------------------------------------------
   Slides are stacked and cross-faded rather than translated, so there is
   no horizontal overflow to manage and the band never jumps height. Only
   the active slide is reachable by keyboard or screen reader. */
.slider { position: relative; border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-md); }
.slide {
  display: grid; grid-template-columns: 1.15fr .85fr; gap: var(--sp-5);
  align-items: center; padding: var(--sp-6) var(--sp-7); min-height: 268px;
  opacity: 0; visibility: hidden;
  position: absolute; inset: 0;
  transition: opacity .55s ease;
}
.slide.is-active { opacity: 1; visibility: visible; position: relative; }
.slide__eyebrow {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase;
  padding: 4px 12px; border-radius: var(--r-pill); background: rgba(255,255,255,.75);
  margin-bottom: var(--sp-3);
}
.slide__title { font-size: 27px; line-height: 1.22; margin: 0 0 var(--sp-2); color: var(--ink-900); letter-spacing: -.3px; }
.slide__text  { font-size: 14.5px; color: var(--ink-700); margin: 0 0 var(--sp-4); max-width: 46ch; }
.slide__art   { display: grid; place-items: center; }
.slide__art svg { width: 100%; height: auto; max-width: 320px; }

.slide--a { background: linear-gradient(120deg, #e5edff 0%, #f4f0ff 55%, #ffeef6 100%); }
.slide--b { background: linear-gradient(120deg, #e2f7f4 0%, #eaf6ff 55%, #f3f0ff 100%); }
.slide--c { background: linear-gradient(120deg, #fff1e8 0%, #fff7e0 52%, #eefbe8 100%); }
.slide--a .slide__eyebrow { color: var(--brand-600); }
.slide--b .slide__eyebrow { color: var(--teal-500); }
.slide--c .slide__eyebrow { color: var(--cta-500); }

.slider__nav {
  position: absolute; left: 0; right: 0; bottom: var(--sp-4);
  display: flex; align-items: center; justify-content: center; gap: var(--sp-2);
}
.slider__dot {
  width: 9px; height: 9px; border-radius: 50%; border: 0; padding: 0; cursor: pointer;
  background: rgba(18,18,36,.22); transition: width .25s ease, background .25s ease;
}
.slider__dot.is-active { width: 26px; border-radius: var(--r-pill); background: var(--brand-500); }
.slider__arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--line);
  background: rgba(255,255,255,.9); color: var(--ink-700);
  display: grid; place-items: center; cursor: pointer; font-size: 15px;
}
.slider__arrow:hover { background: #fff; color: var(--brand-500); box-shadow: var(--shadow-sm); }
.slider__arrow--prev { left: var(--sp-3); }
.slider__arrow--next { right: var(--sp-3); }

@media (max-width: 820px) {
  .slide { grid-template-columns: 1fr; padding: var(--sp-5); text-align: center; }
  .slide__art { order: -1; }
  .slide__art svg { max-width: 210px; }
  .slide__title { font-size: 21px; }
  .slide__text { margin-inline: auto; }
  .slider__arrow { display: none; }
}

/* Auto-advance is motion; honour the OS setting and stop it. */
@media (prefers-reduced-motion: reduce) {
  .slide { transition: none; }
}

/* ---------- company banner strip ------------------------------------ */
.banners {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
}
.banner {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); color: inherit;
  transition: transform .12s ease, box-shadow .15s ease, border-color .15s ease;
}
.banner:hover { text-decoration: none; transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--brand-200); }
.banner__logo {
  width: 42px; height: 42px; border-radius: var(--r-md); flex: none;
  display: grid; place-items: center; font-size: 14px; font-weight: 700;
}
.banner__name { display: block; font-size: 13.5px; font-weight: 600; color: var(--ink-900); }
.banner__meta { display: block; font-size: 12px; color: var(--ink-500); }

/* ---------- type-to-filter inside a long option list ----------------- */
.lsearch { position: relative; margin-bottom: var(--sp-3); }
.lsearch__i {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: var(--ink-400); font-size: 13px; pointer-events: none;
}
.lsearch__input {
  width: 100%; padding: 7px 10px 7px 30px;
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  font: inherit; font-size: 13px; background: var(--surface); color: var(--ink-900);
}
.lsearch__input:focus {
  outline: none; border-color: var(--brand-400); box-shadow: 0 0 0 3px var(--brand-50);
}
.lsearch__empty { font-size: 12.5px; color: var(--ink-500); padding: 8px 2px; margin: 0; }

/* a checkbox row that reads as a pressable option */
.check--opt {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 6px 8px; border-radius: var(--r-md);
  font-size: 13px; cursor: pointer;
}
/* Any `display` rule beats the UA's `[hidden] { display: none }`, so a
   component that sets display MUST restore it — otherwise setting
   el.hidden appears to do nothing and the filter looks broken. */
[hidden] { display: none !important; }
.check--opt:hover { background: var(--brand-50); }
.check--opt.is-on { background: var(--brand-50); color: var(--brand-600); font-weight: 600; }
.check--opt input { margin: 0; }
.check__n { font-size: 11.5px; color: var(--ink-400); font-variant-numeric: tabular-nums; }
.filters__title { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }

/* ---------- "already seen" treatment --------------------------------
   A viewed candidate is de-emphasised, never hidden: the recruiter still
   needs to be able to go back to them. The left rail plus an explicit
   text badge carry the state — the muted photo alone would not. */
/* Candidate cards carry a coloured rail keyed to the person, so a long
   result list has rhythm instead of being a wall of white boxes. */
.ccard { border-left: 4px solid var(--brand-300); }
.ccard--t1 { border-left-color: var(--brand-500); }
.ccard--t2 { border-left-color: var(--violet-500); }
.ccard--t3 { border-left-color: var(--teal-500); }
.ccard--t4 { border-left-color: var(--amber-500); }
.ccard--t5 { border-left-color: var(--pink-500); }
.ccard--t6 { border-left-color: var(--lime-500); }
.ccard--t7 { border-left-color: var(--sky-500); }
.ccard--t8 { border-left-color: var(--cta-500); }
.ccard:hover { box-shadow: var(--shadow-md); }

.jobcard--seen { background: var(--surface-alt); border-left: 3px solid var(--brand-200); }
.jobcard--seen .cphoto { opacity: .72; }
.jobcard--seen .jobcard__title a { color: var(--ink-600); }

.seenbar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 10px; }
.seenmark {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: var(--r-pill);
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
}
.seenmark--view { background: var(--brand-50);  color: var(--brand-600); }
.seenmark--dl   { background: var(--violet-50); color: var(--violet-500); }
.seenmark--new  { background: var(--ok-50);     color: var(--ok-500); }

/* candidate activity recency */
.actmark {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 9px; border-radius: var(--r-pill);
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
}
.actmark .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.actmark--live  { background: var(--ok-50);   color: var(--ok-500); }
.actmark--warm  { background: var(--warn-50); color: var(--warn-500); }
.actmark--stale { background: var(--surface-sunk); color: var(--ink-500); }

/* toolbar above the results */
.stoolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
}
.stoggle {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px; border-radius: var(--r-pill);
  border: 1px solid var(--line-strong); font-size: 12.5px;
  color: var(--ink-700); background: var(--surface); cursor: pointer;
}
.stoggle:hover { border-color: var(--brand-300); color: var(--brand-600); text-decoration: none; }
.stoggle.is-on { background: var(--brand-500); border-color: var(--brand-500); color: #fff; }

/* ---------- candidate photo / initials ------------------------------ */
.cphoto {
  display: inline-grid; place-items: center; flex: none;
  border-radius: 50%; overflow: hidden;
  font-weight: 700; letter-spacing: .3px; line-height: 1;
  background: var(--brand-50); color: var(--brand-600);
}
.cphoto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cphoto--sq { border-radius: var(--r-lg); }
.cphoto--ring { box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--brand-100); }

/* resume download control */
.rlink {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: var(--r-pill);
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
  background: var(--ok-50); color: var(--ok-500); border: 1px solid #bfe3c0;
}
.rlink:hover { background: var(--ok-500); color: #fff; text-decoration: none; border-color: var(--ok-500); }
.rlink--none {
  background: var(--surface-sunk); color: var(--ink-500);
  border-color: var(--line); font-weight: 500; cursor: default;
}

/* contact row — phone / email as tappable links */
.contactrow { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; }
.cbtn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: var(--r-pill);
  font-size: 12.5px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink-700); white-space: nowrap;
}
.cbtn:hover { border-color: var(--brand-300); color: var(--brand-600); background: var(--brand-50); text-decoration: none; }
.cbtn__i { color: var(--ink-400); font-size: 12px; }
.cbtn:hover .cbtn__i { color: var(--brand-500); }

/* rich candidate row used by the admin list */
.crow {
  display: grid; gap: var(--sp-4); align-items: center;
  grid-template-columns: auto minmax(0, 2.1fr) minmax(0, 1.5fr) minmax(0, 1.4fr) auto;
  /* Generous vertical padding: rows can grow to two or three lines once
     skills wrap, and a tight row then collides with the divider. */
  padding: 18px var(--sp-4);
  border-bottom: 1px solid var(--line);
  transition: background .12s ease;
}
/* Breathing room under a wrapped chip block, which is usually the tallest
   thing in the row and otherwise ends flush against the border. */
.crow .chips { padding-block: 2px 4px; }
.crow__facts > span { line-height: 1.5; }
.crow:last-child { border-bottom: 0; }
.crow:hover { background: var(--surface-alt); }
.crow__name { font-size: 14.5px; font-weight: 600; color: var(--ink-900); }
.crow__name a { color: inherit; }
.crow__name a:hover { color: var(--brand-500); }
.crow__sub { font-size: 12.5px; color: var(--ink-500); }
.crow__facts { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--ink-700); }
.crow__facts span { display: inline-flex; align-items: center; gap: 6px; }
.crow__actions { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }

@media (max-width: 1150px) {
  .crow { grid-template-columns: auto minmax(0, 1fr) auto; }
  .crow__facts--hide { display: none; }
}
@media (max-width: 700px) {
  .crow { grid-template-columns: auto minmax(0, 1fr); }
  .crow__actions { grid-column: 1 / -1; flex-direction: row; align-items: center; }
}

/* ---------- job listing: three columns ------------------------------
   Filter rail | results | promo rail, as the reference boards use. Grid
   rather than flex so the middle column can shrink freely while the two
   rails hold their width, then drop away in order on narrow screens. */
.joblayout {
  display: grid; gap: var(--sp-5); align-items: start;
  grid-template-columns: 260px minmax(0, 1fr) 290px;
}
.joblayout__main { min-width: 0; }
.joblayout__rail { position: sticky; top: calc(var(--topbar-h) + var(--sp-4)); }

@media (max-width: 1200px) {
  /* The promo rail is the least important column, so it goes first. */
  .joblayout { grid-template-columns: 250px minmax(0, 1fr); }
  .joblayout__rail { display: none; }
}
@media (max-width: 860px) {
  .joblayout { grid-template-columns: 1fr; }
  .filters { width: 100%; position: static; }
}

/* collapsible filter group */
.fgroup { border-bottom: 1px solid var(--line); }
.fgroup:last-child { border-bottom: 0; }
.fgroup__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-3) 0; cursor: pointer; list-style: none;
  font-size: 13.5px; font-weight: 700; color: var(--ink-900);
}
.fgroup__head::-webkit-details-marker { display: none; }
.fgroup__chev { color: var(--ink-400); transition: transform .2s ease; }
.fgroup[open] .fgroup__chev { transform: rotate(180deg); }
.fgroup__body { padding-bottom: var(--sp-3); display: flex; flex-direction: column; gap: 2px; max-height: 230px; overflow-y: auto; }

/* one filter option — a link, so every state is a shareable URL */
.fopt {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 6px 6px 6px 0; border-radius: var(--r-sm);
  color: var(--ink-700); font-size: 13px;
}
.fopt:hover { text-decoration: none; color: var(--brand-500); }
.fopt__box {
  width: 16px; height: 16px; flex: none; border-radius: 4px;
  border: 1.5px solid var(--line-strong); background: var(--surface);
  display: grid; place-items: center; font-size: 10px; color: #fff;
}
.fopt.is-on .fopt__box { background: var(--brand-500); border-color: var(--brand-500); }
.fopt.is-on { color: var(--brand-600); font-weight: 600; }
.fopt__label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fopt__n {
  color: var(--ink-600); font-size: 11.5px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: 1px 7px; border-radius: var(--r-pill); background: var(--surface-sunk);
}
.fopt:hover .fopt__n,
.fopt.is-on .fopt__n { background: var(--brand-100); color: var(--brand-600); }
.fopt.is-on { background: var(--brand-50); padding-left: 6px; }

/* A colour per filter group, so the rail reads as sections at a glance. */
.fgroup__head { position: relative; padding-left: 15px; }
.fgroup__head::before {
  content: ""; position: absolute; left: 0; top: 50%; margin-top: -3px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--brand-500);
}
.fgroup:nth-of-type(2) .fgroup__head::before { background: var(--violet-500); }
.fgroup:nth-of-type(3) .fgroup__head::before { background: var(--teal-500); }
.fgroup:nth-of-type(4) .fgroup__head::before { background: var(--amber-500); }
.fgroup:nth-of-type(5) .fgroup__head::before { background: var(--pink-500); }

/* =====================================================================
   Jobs search page — gradient hero, tinted result pills, tone accents.
   ===================================================================== */
.jobshero {
  position: relative; overflow: hidden; isolation: isolate;
  padding: var(--sp-6) 0 var(--sp-5); color: #fff;
  background: linear-gradient(135deg, #1739a8 0%, #1e4bd8 46%, #275df5 100%);
}
.jobshero__blob {
  position: absolute; border-radius: 50%; filter: blur(60px);
  opacity: .45; z-index: -1; pointer-events: none;
}
.jobshero__blob--a { width: 320px; height: 320px; top: -150px; right: 6%;  background: #8951ff; }
.jobshero__blob--b { width: 260px; height: 260px; bottom: -170px; left: 2%; background: #0e9b93; }
.jobshero__grid {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: radial-gradient(rgba(255, 255, 255, .16) 1px, transparent 1px);
  background-size: 22px 22px;
  mask-image: radial-gradient(110% 85% at 18% 8%, #000 30%, transparent 76%);
  -webkit-mask-image: radial-gradient(110% 85% at 18% 8%, #000 30%, transparent 76%);
}
.jobshero__inner { position: relative; }
.jobshero__title {
  margin: 0 0 4px; font-size: 26px; font-weight: 700;
  letter-spacing: -.3px; color: #fff;
}
.jobshero__title em {
  font-style: normal;
  background: linear-gradient(92deg, #fff 10%, #b8ceff 58%, #7ef29a 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.jobshero__sub { margin: 0 0 var(--sp-4); font-size: 13.5px; color: rgba(255, 255, 255, .82); }
.jobshero__sub strong { color: #fff; }
.jobshero__search { box-shadow: 0 14px 32px rgba(9, 22, 68, .3); }

.jobshero__quick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-4); }
.jobshero__quicklabel {
  font-size: 11px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: rgba(255, 255, 255, .68);
}
.qchip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 8px 5px 12px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .24);
  color: #fff; font-size: 12.5px; font-weight: 600;
  transition: background .15s ease, transform .15s ease;
}
.qchip:hover { background: rgba(255, 255, 255, .27); color: #fff; text-decoration: none; transform: translateY(-1px); }
.qchip__n {
  font-size: 11px; padding: 1px 7px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .22); font-variant-numeric: tabular-nums;
}

/* result-card facts as tinted pills */
.jobcard__meta { gap: var(--sp-2); }
.jmeta {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: var(--r-pill);
  font-size: 12.5px; font-weight: 600;
  background: var(--surface-sunk); color: var(--ink-700);
}
.jmeta__i { font-size: 11px; opacity: .9; }
.jmeta--exp  { background: var(--brand-50);  color: var(--brand-600); }
.jmeta--pay  { background: var(--ok-50);     color: var(--ok-600); }
.jmeta--loc  { background: var(--sky-50);    color: var(--sky-600); }
.jmeta--mode { background: var(--violet-50); color: var(--violet-600); }

/* One hue per portal track, matching the home-page track cards. */
.jmeta--lvl-fresher     { background: var(--teal-50);  color: var(--teal-500); }
.jmeta--lvl-experienced { background: var(--brand-50); color: var(--brand-600); }
.jmeta--lvl-unskilled   { background: var(--amber-50); color: var(--warn-600); }

.jnew {
  display: inline-block; margin-left: var(--sp-2); vertical-align: 2px;
  padding: 2px 8px; border-radius: var(--r-pill);
  background: var(--ok-50); color: var(--ok-600);
  font-size: 10.5px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase;
}

/* Company-tone accent down the card's leading edge. Matches the logo's
   hue, so an employer keeps one colour across every list. */
.jobcard { --jc: var(--brand-500); padding-left: 20px; }
.jobcard::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--jc); border-radius: var(--r-lg) 0 0 var(--r-lg);
}
.jobcard:hover { border-color: var(--jc); }
.jobcard--t1 { --jc: var(--brand-500); }
.jobcard--t2 { --jc: var(--violet-500); }
.jobcard--t3 { --jc: var(--teal-500); }
.jobcard--t4 { --jc: var(--amber-500); }
.jobcard--t5 { --jc: var(--pink-500); }
.jobcard--t6 { --jc: var(--lime-500); }
.jobcard--t7 { --jc: var(--sky-500); }
.jobcard--t8 { --jc: var(--cta-500); }

/* soft-tinted sidebar card */
.card--tint {
  background: linear-gradient(160deg, var(--brand-50), var(--violet-50) 120%);
  border-color: var(--brand-100);
}

/* =====================================================================
   Home page: the three tracks the portal is organised around.
   One card per track, each owning a hue that the job cards reuse.
   ===================================================================== */
/* ---------- hero colour field + glass controls ------------------------
   Restored deliberately: these rules previously sat next to the photo-slide
   block and were removed with it, which flattened the band and put the solid
   white search slab back.
   -------------------------------------------------------------------- */
.hero__aurora { position: absolute; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
/* A pool of light behind the type, so the node field's masked-out centre
   reads as deliberate negative space rather than a hole in the artwork. */
.hero__aurora::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(52% 62% at 50% 42%, rgba(84, 130, 255, .12), rgba(7, 12, 26, 0) 72%);
}
.hero__orb { position: absolute; border-radius: 50%; filter: blur(96px); }
.hero__orb--a {
  width: 46vw; height: 46vw; max-width: 620px; max-height: 620px;
  top: -34%; left: -12%; background: rgba(39, 93, 245, .26);
  animation: apDrift 21s ease-in-out infinite;
}
.hero__orb--b {
  width: 40vw; height: 40vw; max-width: 540px; max-height: 540px;
  top: -30%; right: -10%; background: rgba(137, 81, 255, .22);
  animation: apDrift 26s ease-in-out infinite reverse;
}
.hero__orb--c {
  width: 34vw; height: 34vw; max-width: 460px; max-height: 460px;
  bottom: -46%; left: 30%; background: rgba(14, 155, 147, .16);
  animation: apDrift 31s ease-in-out infinite;
}

/* Glass search field: translucent over the field instead of a solid white
   slab. Tinted dark, not white — white glass over a bright orb goes muddy
   and drops the placeholder below a readable contrast. */
.hero .searchbar {
  background: rgba(9, 13, 26, .46);
  border: 1px solid rgba(255, 255, 255, .20);
  box-shadow: 0 18px 44px rgba(4, 8, 20, .48), inset 0 1px 0 rgba(255, 255, 255, .12);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
}
.hero .searchbar__seg + .searchbar__seg { border-left-color: rgba(255, 255, 255, .16); }
.hero .searchbar__icon { color: rgba(255, 255, 255, .6); }
.hero .searchbar__seg input,
.hero .searchbar__seg select { color: #fff; }
.hero .searchbar__seg input::placeholder { color: rgba(255, 255, 255, .72); }
/* The dropdown list is drawn by the OS, so its options need ink back. */
.hero .searchbar__seg select option { color: var(--ink-900); background: #fff; }
.hero .searchbar .btn {
  background: linear-gradient(135deg, var(--brand-400), var(--brand-600) 70%, var(--violet-500));
  border-color: transparent;
  box-shadow: 0 8px 24px rgba(39, 93, 245, .5);
}
.hero .searchbar .btn:hover { box-shadow: 0 10px 30px rgba(39, 93, 245, .62); }

/* ---------- hero product frame ----------------------------------------
   A browser chrome around real job rows. Tilted very slightly — enough to
   read as an object in space, not enough to make the type inside it awkward
   to read, which is where most "3D mockup" heroes go wrong.
   -------------------------------------------------------------------- */
/* --t is the hero demo's timeline. The caption lines under the frame read it
   from here; .demo declares the same value for itself. Change one, change
   both — they are the same 16 seconds. */
.shotwrap { position: relative; perspective: 1400px; min-width: 0; --t: 16s; }
.shot {
  /* relative so .shotline can pin itself to the frame's bottom edge */
  position: relative;
  border-radius: 14px; overflow: hidden;
  background: var(--surface);
  border: 1px solid rgba(255, 255, 255, .14);
  box-shadow: 0 40px 80px rgba(2, 6, 18, .58), 0 2px 0 rgba(255, 255, 255, .06) inset;
  transform: none;
  transition: transform .5s cubic-bezier(.22, .8, .3, 1);
}
.shotwrap:hover .shot { transform: translateY(-4px); }

.shot__bar {
  display: flex; align-items: center; gap: 6px;
  padding: 9px 12px; background: #eef0f6; border-bottom: 1px solid var(--line);
}
.shot__dot { width: 9px; height: 9px; border-radius: 50%; background: #cdd3e2; flex: none; }
.shot__url {
  margin-left: 10px; flex: 1 1 auto;
  padding: 3px 10px; border-radius: var(--r-pill);
  background: #fff; border: 1px solid var(--line);
  font-size: 11px; color: var(--ink-500);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Bottom padding clears the .shotline strip, so the demo's own fields never
   render underneath it. 72px, not 66: the strip grows to 58px at the top of
   its clamp() and the last field row was landing 1px into it. Keep the two in
   step if the strip's type size or padding changes. */
.shot__body { padding: var(--sp-3) var(--sp-3) 72px; }
.shot__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-3); }
.shot__title { font-size: 13px; font-weight: 700; color: var(--ink-900); }
.shot__chip {
  font-size: 11px; font-weight: 600; color: var(--ink-600);
  padding: 3px 9px; border-radius: var(--r-pill); background: var(--surface-sunk);
}

.shotrow {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: 11px 0; border-top: 1px solid var(--line);
}
.shotrow:first-of-type { border-top: 0; }
.shotrow__logo {
  width: 34px; height: 34px; flex: none; border-radius: var(--r-md);
  display: grid; place-items: center; overflow: hidden;
  font-size: 12px; font-weight: 700;
}
.shotrow__logo img { width: 100%; height: 100%; object-fit: contain; padding: 3px; display: block; }
.shotrow__main { min-width: 0; }
.shotrow__title {
  font-size: 13px; font-weight: 700; color: var(--ink-900);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.shotrow__co { font-size: 11.5px; color: var(--ink-600); margin-bottom: 5px; }
.shotrow__pills { display: flex; flex-wrap: wrap; gap: 5px; }
.shotpill {
  font-size: 10.5px; font-weight: 600; padding: 2px 7px; border-radius: var(--r-pill);
  white-space: nowrap;
}
.shotpill--exp { background: var(--brand-50); color: var(--brand-600); }
.shotpill--pay { background: var(--ok-50);    color: var(--ok-600); }
.shotpill--loc { background: var(--sky-50);   color: var(--sky-600); }

@media (prefers-reduced-motion: reduce) {
  .shot, .shotwrap:hover .shot { transition: none; }
}

/* Colour glows only; the node-link field that used to sit here is gone —
   it read as busy behind the type. Reduced-motion stops the drift. */
@media (prefers-reduced-motion: reduce) {
  .hero__orb { animation: none !important; }
}




/* ---------- hero background: city skyline ----------------------------
   Sits along the bottom edge, behind the content, fading up into the sky
   gradient. Windows twinkle on staggered delays; the towers never move.
   -------------------------------------------------------------------- */
.skyline {
  position: absolute; left: 0; right: 0; bottom: 0; height: 76%;
  z-index: 0; pointer-events: none; overflow: hidden;
  /* Fades out upward so there is no hard line where the city stops. */
  mask-image: linear-gradient(to bottom, transparent 0%, #000 46%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 46%);
}
.skyline__svg { width: 100%; height: 100%; display: block; }

/* Depth by value: far towers barely lighter than the sky, near ones solid. */
.skyline__far  { fill: #16204a; }
.skyline__mid  { fill: #111a3d; }
.skyline__near { fill: #0b1230; }

.skyline .win { fill: #2b3a72; }
.skyline .win--lit {
  fill: #ffd98a;
  animation: winGlow 5.5s ease-in-out infinite;
  animation-delay: calc(var(--i) * .42s);
}
/* Lights never go fully dark — an office does not blink, it dims. */
@keyframes winGlow {
  0%, 100% { opacity: .38; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .skyline .win--lit { animation: none; opacity: .85; }
}


/* ---------- hero CTA row --------------------------------------------- */

.hero__cta { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3); margin-top: var(--sp-4); }
.btn--onlight {
  background: #fff; color: var(--ink-900); border: 1px solid #fff;
  box-shadow: 0 10px 28px rgba(4, 8, 20, .38);
}
.btn--onlight:hover { background: #f2f5ff; color: var(--ink-900); }

.btn--glass {
  background: rgba(255, 255, 255, .12); color: #fff;
  border: 1px solid rgba(255, 255, 255, .28);
  backdrop-filter: blur(10px);
}
.btn--glass:hover { background: rgba(255, 255, 255, .2); color: #fff; }
.hero__cta .btn { display: inline-flex; align-items: center; gap: 8px; }

/* ---------- hero type ------------------------------------------------ */

/* The three tracks as the headline, each word in its track's own colour — the
   same hue as its card below and its pill on every job card. Bolder and more
   saturated on purpose: this line is the page's hook.
   The words name the tracks, so colour is never the only signal. */
.hero__trio {
  margin: 0 0 8px; font-weight: 800;
  font-size: clamp(26px, 3.7vw, 38px); line-height: 1.12;
  letter-spacing: -1.1px;
  text-shadow: 0 1px 18px rgba(0, 0, 0, .35);
  display: flex; flex-wrap: wrap; justify-content: center; gap: 0 .38em;
}
.hero__trio--f { color: #5ad9c9; }
.hero__trio--e { color: #9dbcff; }
.hero__trio--u { color: #ffca5f; }

/* The hook line: three short beats, then the reassurance. */
.hero__hook {
  margin: 0 auto var(--sp-4); font-size: clamp(18px, 2.1vw, 24px);
  font-weight: 800; letter-spacing: -.5px; color: #fff;
  text-shadow: 0 1px 16px rgba(0, 0, 0, .4);
}
.hero__hook em {
  font-style: normal;
  /* Brighter than the first pass: on a dark bed the pale pastels read as
     washed out next to the white, which lost the emphasis this phrase carries. */
  background: linear-gradient(92deg, #6ee7d7, #a5c8ff 52%, #ffb3d2);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}




/* ---------- top companies carousel ---------------------------------- */
/* Even top and bottom. The block previously ended flush under the logo
   rail's own bottom padding, so it read as clipped against the next
   section rather than spaced from it. */
.corail {
  background: var(--surface);
  border-top: 1px solid var(--line);
  /* Less above than below: this block sits right under the fold, so the space
     is better spent showing the logos than padding the heading. */
  padding: var(--sp-5) 0 var(--sp-6);
}
.corail__title { margin: 0 0 var(--sp-4); text-align: center; font-size: 21px; }
.corail__sub { margin: 4px 0 var(--sp-5); text-align: center; font-size: 13.5px; color: var(--ink-500); }
.corail__wrap { position: relative; }
.corail__track {
  display: flex; gap: var(--sp-3); overflow-x: auto; scroll-behavior: smooth;
  scroll-snap-type: x proximity; padding: 4px 2px 10px;
  /* Rail scrolls on touch; the arrows are the pointer affordance. */
  scrollbar-width: none;
}
.corail__track::-webkit-scrollbar { display: none; }

.cochip {
  flex: 0 0 168px; scroll-snap-align: start;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 18px 14px 13px; border-radius: var(--r-lg);
  background: #fff; border: 1px solid var(--line); box-shadow: var(--shadow-sm);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.cochip:hover {
  text-decoration: none; transform: translateY(-3px);
  border-color: var(--brand-300); box-shadow: var(--shadow-lg);
}
.cochip__art { height: 36px; width: 100%; display: grid; place-items: center; }
/* contain + height-bound: a 2.5:1 wordmark and a 1:1 monogram then sit on the
   same optical baseline, and neither is ever cropped. */
.cochip__art img { max-height: 36px; max-width: 100%; object-fit: contain; display: block; }
.cochip__word {
  font-size: 14px; font-weight: 700; color: var(--ink-800); text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.cochip__n { font-size: 11.5px; font-weight: 600; color: var(--ink-500); white-space: nowrap; }

.corail__arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center; font-size: 20px; line-height: 1;
  background: #fff; border: 1px solid var(--line-strong); color: var(--ink-700);
  box-shadow: var(--shadow-md);
}
.corail__arrow:hover { color: var(--brand-600); border-color: var(--brand-300); }
.corail__arrow[hidden] { display: none; }
.corail__arrow--prev { left: -14px; }
.corail__arrow--next { right: -14px; }
.corail__foot { text-align: center; margin-top: var(--sp-4); }

@media (max-width: 760px) {
  .corail__arrow { display: none; }
}


/* in-results registration prompt */
.promo {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5); border-radius: var(--r-lg);
  background: linear-gradient(120deg, var(--cta-50), #fff 55%, var(--brand-50));
  border: 1px solid var(--line); flex-wrap: wrap;
}
.promo__art { font-size: 26px; }
.promo__list {
  list-style: none; margin: 6px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px var(--sp-4); font-size: 12.5px; color: var(--ink-600);
}
.promo__list li::before { content: "✓ "; color: var(--ok-500); font-weight: 700; }

/* compact company row in the right rail */
.minico {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 9px 0; border-bottom: 1px solid var(--line); color: inherit;
}
.minico:last-child { border-bottom: 0; }
.minico:hover { text-decoration: none; }
.minico:hover .minico__name { color: var(--brand-500); }
.minico__logo {
  width: 34px; height: 34px; border-radius: var(--r-md); flex: none;
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  overflow: hidden;
}

/* A real logo sits on white and is never cropped — contain, not cover, since
   a wordmark loses its meaning the moment its edges are cut off. */
.has-logo { background: #fff; border: 1px solid var(--line); }
.has-logo img { width: 100%; height: 100%; object-fit: contain; padding: 3px; display: block; }
.minico__name { display: block; font-size: 13.5px; font-weight: 600; color: var(--ink-900); }
.minico__meta { display: block; font-size: 12px; color: var(--ink-500); }

/* ---------- filter rail --------------------------------------------- */
.filters { width: 260px; flex: none; }
.filters__group { padding: var(--sp-4) 0; border-bottom: 1px solid var(--line); }
.filters__group:last-child { border-bottom: 0; }
.filters__title {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; font-weight: 700; color: var(--ink-800); margin-bottom: var(--sp-3);
}
.filters__list { display: flex; flex-direction: column; gap: var(--sp-2); max-height: 210px; overflow-y: auto; }

/* ---------- flash / alerts ------------------------------------------ */
.flash {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md);
  border: 1px solid; margin-bottom: var(--sp-4); font-size: 13.5px;
}
.flash__icon {
  display: grid; place-items: center; width: 20px; height: 20px;
  border-radius: 50%; background: currentColor; color: #fff;
  font-size: 12px; font-weight: 700; flex: none;
}
.flash__icon::before { content: ""; }
.flash__close { margin-left: auto; border: 0; background: none; font-size: 20px; line-height: 1; cursor: pointer; color: inherit; opacity: .5; }
.flash__close:hover { opacity: 1; }
.flash--success { background: var(--ok-50);   border-color: #bfe3cd; color: var(--ok-500); }
.flash--error   { background: var(--bad-50);  border-color: #f2c4c4; color: var(--bad-500); }
.flash--warning { background: var(--warn-50); border-color: #f0d9ae; color: var(--warn-500); }
.flash--info    { background: var(--info-50); border-color: var(--brand-100); color: var(--info-500); }
.flash > span:not(.flash__icon) { color: var(--ink-800); }

.callout {
  padding: var(--sp-4); border-radius: var(--r-md);
  background: var(--brand-50); border-left: 3px solid var(--brand-500);
  font-size: 13.5px;
}
.callout--warn { background: var(--warn-50); border-left-color: var(--warn-500); }

/* =====================================================================
   Auth stage — login and register
   ---------------------------------------------------------------------
   A full-bleed two-pane stage rather than a card floating inside the page.
   The brand canvas runs to the viewport edge and the form sits centred
   opposite it, so the screen fills instead of leaving a band of dead grey
   between the content and the footer — which is what the old floating
   panel did at every viewport height.

   Scoped to the .au and .aff class families, used only by auth/login.php
   and auth/register.php. The shared .pwfield, .rolepick, .auth__divider and
   .btn--sheen rules are deliberately NOT touched here: admin/settings.php
   and both import wizards depend on them.

   Every animation is decorative and is switched off wholesale under
   prefers-reduced-motion at the end of this block. Looping animations
   stagger through absolute keyframe percentages on one shared duration
   rather than animation-delay — a delay keeps an element's period but
   shifts its phase for good, so a loop drifts apart after the first cycle.
   ===================================================================== */

/* One screen, no page scroll.
   The stage is exactly the viewport minus the sticky top bar, and
   .auth-screen drops the footer, so signing in never asks anyone to scroll.

   The escape hatch matters as much as the rule: on a short viewport the
   register form is taller than the space available, so the FORM side scrolls
   inside itself rather than being clipped. A page that does not scroll is
   good; a Register button nobody can reach is not. */
.auth-screen .footer { display: none; }
.austage {
  display: grid;
  grid-template-columns: minmax(0, 1.04fr) minmax(0, .96fr);
  height: calc(100vh - var(--topbar-h));
}

/* ---------- brand canvas --------------------------------------------- */
.aubrand {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; align-items: center;
  padding: var(--sp-8) clamp(26px, 4.2vw, 64px);
  color: #fff;
  background:
    radial-gradient(118% 100% at 76% 6%, rgba(74, 124, 247, .40), transparent 58%),
    linear-gradient(163deg, #070d1f 0%, #0d1836 34%, #122b7d 74%, #1e4bd8 100%);
}

/* Soft colour fields drifting behind the content. Three separate keyframe
   sets on one shared 26s duration: same period, different phase, so they
   stay in step forever instead of separating the way delays would. */
.aubrand__aura {
  position: absolute; border-radius: 50%; filter: blur(64px);
  z-index: -1; pointer-events: none; will-change: transform;
}
.aubrand__aura--a {
  width: 44vmin; height: 44vmin; top: -13%; right: -9%;
  background: rgba(137, 81, 255, .50); animation: auAuraA 26s ease-in-out infinite;
}
.aubrand__aura--b {
  width: 38vmin; height: 38vmin; bottom: -15%; left: -11%;
  background: rgba(14, 155, 147, .44); animation: auAuraB 26s ease-in-out infinite;
}
.aubrand__aura--c {
  width: 30vmin; height: 30vmin; top: 42%; left: 46%;
  background: rgba(39, 93, 245, .40); animation: auAuraC 26s ease-in-out infinite;
}
@keyframes auAuraA {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  32%      { transform: translate3d(-5%, 6%, 0) scale(1.14); }
  68%      { transform: translate3d(4%, -4%, 0) scale(.92); }
}
@keyframes auAuraB {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1.06); }
  46%      { transform: translate3d(7%, -6%, 0) scale(.9); }
  74%      { transform: translate3d(-3%, 3%, 0) scale(1.12); }
}
@keyframes auAuraC {
  0%, 100% { transform: translate3d(0, 0, 0) scale(.94); }
  22%      { transform: translate3d(6%, 5%, 0) scale(1.1); }
  60%      { transform: translate3d(-6%, -5%, 0) scale(1); }
}

/* Fine dot texture, masked so it never reaches the headline. */
.aubrand__grid {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: radial-gradient(rgba(255, 255, 255, .16) 1px, transparent 1px);
  background-size: 22px 22px;
  mask-image: radial-gradient(115% 85% at 26% 16%, #000 30%, transparent 76%);
  -webkit-mask-image: radial-gradient(115% 85% at 26% 16%, #000 30%, transparent 76%);
}
.aubrand__inner { position: relative; width: min(520px, 100%); margin-inline: auto; }

.aubrand__badge {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 5px 13px 5px 10px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .13); border: 1px solid rgba(255, 255, 255, .24);
  font-size: 12px; font-weight: 600; letter-spacing: .2px;
  backdrop-filter: blur(4px);
}
.aubrand__pulse {
  width: 7px; height: 7px; border-radius: 50%; background: #7ef29a;
  box-shadow: 0 0 0 0 rgba(126, 242, 154, .7);
  animation: auPulse 2.4s ease-out infinite;
}
@keyframes auPulse {
  0%   { box-shadow: 0 0 0 0 rgba(126, 242, 154, .7); }
  70%  { box-shadow: 0 0 0 9px rgba(126, 242, 154, 0); }
  100% { box-shadow: 0 0 0 0 rgba(126, 242, 154, 0); }
}

/* h1/h2 already take Jakarta from the single display-font rule near the
   top of this file, so nothing here restates font-family. */
.aubrand__title {
  margin: var(--sp-5) 0 var(--sp-3);
  font-size: clamp(30px, 3.2vw, 42px); line-height: 1.08;
  font-weight: 800; letter-spacing: -1.1px; color: #fff;
}
/* The AI phrase carries a light travelling across it. The gradient is twice
   the width of the text and slides, so the highlight moves through the
   letters rather than the letters moving — type that shifts position is
   hard to read, and this is a headline someone is meant to read once. */
.aubrand__title em {
  font-style: normal;
  /* Mostly white with one mint highlight travelling through it. An earlier
     version graded the whole phrase through pale blue, which dropped it
     below the plain white beside it — a headline that dims as it animates
     reads as a rendering fault, not as emphasis. */
  background: linear-gradient(94deg,
    #fff 0%, #fff 20%, #7ef29a 38%, #fff 56%, #fff 100%);
  background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: auSheen 11s ease-in-out infinite;
}
@keyframes auSheen {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

/* Sparkle in the AI pill. Twinkles on its own shared duration with the
   phases written into the keyframes, so it never needs a delay. */
.aubrand__spark { display: block; width: 13px; height: 13px; color: #7ef29a; }
.aubrand__spark svg { width: 13px; height: 13px; display: block; }
.aubrand__spark--a { animation: auTwinkleA 4.2s ease-in-out infinite; }
.aubrand__spark--b { animation: auTwinkleB 4.2s ease-in-out infinite; }
@keyframes auTwinkleA {
  0%, 100% { opacity: 1;  transform: scale(1); }
  38%      { opacity: .45; transform: scale(.82); }
}
@keyframes auTwinkleB {
  0%, 100% { opacity: .5; transform: scale(.85); }
  62%      { opacity: 1;  transform: scale(1.08); }
}
.aubrand__sub {
  margin: 0; font-size: 15.5px; line-height: 1.55;
  color: rgba(255, 255, 255, .78); max-width: 48ch;
}

.aubrand__art { position: relative; margin: var(--sp-6) 0; }
.aubrand__art svg { display: block; width: 100%; height: auto; }

/* Own top margin rather than relying on the scene above it: when the scene is
   hidden on a short or narrow viewport the list would otherwise sit straight
   against the subtitle. Adjacent margins collapse, so this costs nothing when
   the scene is present. */
.aubrand__list { list-style: none; margin: var(--sp-5) 0 0; padding: 0; display: grid; gap: var(--sp-3); }
.aubrand__list li {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  font-size: 14px; line-height: 1.5; color: rgba(255, 255, 255, .9);
}
.aubrand__ico {
  flex: none; width: 21px; height: 21px; border-radius: 50%; margin-top: 1px;
  display: grid; place-items: center; color: #7ef29a;
  background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .2);
}
.aubrand__ico svg { width: 12px; height: 12px; }

/* ---------- form side ------------------------------------------------ */
/* Centring is done with an auto block margin on the pane, NOT with
   justify-content. A centred flex item that outgrows its container overflows
   equally in both directions and the top is then unreachable — which is what
   clipped the "Welcome back" eyebrow off the top of the form. An auto margin
   only ever distributes *positive* free space, so it centres when there is
   room and quietly becomes zero when there is not. */
.auform {
  display: flex; flex-direction: column; align-items: center;
  padding: var(--sp-7) clamp(20px, 3vw, 52px);
  background: var(--surface);
  overflow-y: auto;                 /* the escape hatch described above */
}
/* The pane is the card. No border or shadow: the brand canvas beside it
   already supplies the edge, and a second box inside a full-bleed split
   reads as a card inside a card. */
.aupane { width: min(410px, 100%); margin-block: auto; }

.auhead { margin-bottom: var(--sp-6); }
.auhead__eyebrow {
  display: block; margin-bottom: 7px;
  font-size: 12px; font-weight: 700; letter-spacing: 1.1px;
  text-transform: uppercase; color: var(--brand-500);
}
.auhead__title { margin: 0; font-size: 28px; line-height: 1.15; letter-spacing: -.6px; }
.auhead__sub { margin: 7px 0 0; font-size: 14px; color: var(--ink-500); }

/* ---------- floating-label field ------------------------------------- */
/* The label starts inside the box and rises when the field is focused or
   filled, so the old label-above-plus-placeholder pair ("Email ID" over
   "Enter your email") collapses into one piece of text. Pure CSS off
   :placeholder-shown — every input carries placeholder=" " to drive it,
   and the <label for> stays a real label, so nothing depends on script. */
.aufield { margin-bottom: var(--sp-4); }
/* Two fields on one line. Not .setrow — that is the admin settings row and
   brings a 230px label column and a bottom rule with it, which is where the
   stray line under register's mobile/password pair came from. */
.aupair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-3); }
.aff { position: relative; }
.aff__input {
  height: 58px; padding: 24px 14px 8px;
  border-radius: var(--r-md); font-size: 15px;
}
.aff__input::placeholder { color: transparent; }
.aff__label {
  position: absolute; left: 15px; top: 18px;
  font-size: 15px; color: var(--ink-500);
  pointer-events: none; transform-origin: 0 0;
  transition: transform .17s cubic-bezier(.22, .8, .3, 1), color .17s ease;
}
.aff__input:focus + .aff__label,
.aff__input:not(:placeholder-shown) + .aff__label {
  transform: translateY(-12px) scale(.76);
  color: var(--brand-600); font-weight: 600;
}
.aff__input.is-invalid:not(:placeholder-shown) + .aff__label,
.aff__input.is-invalid:focus + .aff__label { color: var(--bad-500); }
.aff__label .req { color: var(--bad-500); }

/* Chrome autofill.
   Two separate problems, both visible the moment a saved password is filled
   in: the browser paints its own pale-blue field background over ours, and a
   value restored at page load does not always flip :placeholder-shown, so the
   label stays sitting on top of the dots. Kept in its own rule rather than
   merged into the selector lists above — an unknown -webkit- pseudo would
   invalidate the whole list for every other browser.
   The inset shadow is the only way to repaint an autofilled background. */
.aff__input:-webkit-autofill,
.aff__input:-webkit-autofill:hover,
.aff__input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ink-900);
  -webkit-box-shadow: 0 0 0 40px var(--surface) inset;
  caret-color: var(--ink-900);
}
.aff__input:-webkit-autofill + .aff__label {
  transform: translateY(-12px) scale(.76);
  color: var(--brand-600); font-weight: 600;
}

/* Sits on the shared .pwfield toggle, which app.js already binds. The
   base rule centres it on the box; these taller fields need no change. */
.aff .pwfield__toggle { right: 14px; }

/* ---------- role picker (register) ----------------------------------- */
/* Its own classes rather than the shared .rolepick, which the import
   wizards and admin settings also use and must keep their look. */
.aurole { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); margin-bottom: var(--sp-5); }
.aurole__opt { position: relative; }
.aurole__opt input { position: absolute; opacity: 0; pointer-events: none; }
.aurole__box {
  display: grid; gap: 3px; height: 100%; cursor: pointer;
  padding: var(--sp-4) var(--sp-3);
  border: 1.5px solid var(--line-strong); border-radius: var(--r-lg);
  background: var(--surface);
  transition: border-color .16s ease, background .16s ease, transform .16s ease;
}
.aurole__box:hover { border-color: var(--brand-300); transform: translateY(-1px); }
.aurole__ico {
  width: 30px; height: 30px; border-radius: 9px; margin-bottom: 3px;
  display: grid; place-items: center;
  background: var(--surface-sunk); color: var(--ink-500);
  transition: background .16s ease, color .16s ease;
}
.aurole__ico svg { width: 17px; height: 17px; }
.aurole__box b { font-size: 14px; color: var(--ink-900); font-weight: 600; }
.aurole__box span { font-size: 12.5px; color: var(--ink-500); }
.aurole__opt input:checked + .aurole__box {
  border-color: var(--brand-500); background: var(--brand-50);
}
.aurole__opt input:checked + .aurole__box .aurole__ico { background: var(--brand-500); color: #fff; }
.aurole__opt input:focus-visible + .aurole__box { outline: 2px solid var(--brand-400); outline-offset: 2px; }

/* ---------- small parts ---------------------------------------------- */
.auforgot { display: flex; justify-content: flex-end; margin: calc(var(--sp-2) * -1) 0 var(--sp-4); }
.auforgot a { font-size: 13px; font-weight: 600; }
.aualt { margin: var(--sp-5) 0 0; text-align: center; font-size: 13.5px; color: var(--ink-600); }
.aualt a { font-weight: 600; }

/* Staggered entrance for the form rows. An entrance runs once, so a delay
   is safe here in a way it is not for the looping auras above. */
.aurise { animation: auRise .5s cubic-bezier(.22, .8, .3, 1) backwards; animation-delay: calc(var(--rise, 1) * 65ms); }
@keyframes auRise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- illustration scenes -------------------------------------- */
/* Kept from the previous design — the scenes are accurate to what each
   page buys you, and only their frame has changed. */
.ap-float { animation: apFloat 6.5s ease-in-out infinite; transform-origin: 77px 107px; }
@keyframes apFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-7px); }
}
/* Completeness meter fills once on arrival, then stays put. */
.ap-meter { transform-origin: 24px 160px; animation: apMeter 1.5s ease-out .5s backwards; }
@keyframes apMeter {
  from { transform: scaleX(.12); }
  to   { transform: scaleX(1); }
}
.ap-ring { animation: apRing 3.4s ease-out infinite; transform-origin: 42px 78px; }
@keyframes apRing {
  0%        { transform: scale(.82); opacity: .9; }
  70%, 100% { transform: scale(1.22); opacity: 0; }
}
/* Job cards slide in once, staggered, and remain — a looping entrance would
   leave the connector wires pointing at empty space every few seconds. */
.ap-job { animation: apJobIn .65s cubic-bezier(.22, .8, .3, 1) backwards; animation-delay: .2s; }
.ap-job--2 { animation-delay: .4s; }
.ap-job--3 { animation-delay: .6s; }
@keyframes apJobIn {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: none; }
}
/* Flowing dashes along the connector wires. These loop, so the three are
   offset by writing the offset into each keyframe set on a shared 2.6s
   duration — with animation-delay they slid out of phase permanently. */
.ap-wire   { stroke-dasharray: 5 7; animation: apFlow1 2.6s linear infinite; }
.ap-wire--2 { animation-name: apFlow2; }
.ap-wire--3 { animation-name: apFlow3; }
@keyframes apFlow1 { from { stroke-dashoffset: 96; } to { stroke-dashoffset: 0; } }
@keyframes apFlow2 { from { stroke-dashoffset: 84; } to { stroke-dashoffset: -12; } }
@keyframes apFlow3 { from { stroke-dashoffset: 72; } to { stroke-dashoffset: -24; } }

.ap-check { animation: apPop .55s cubic-bezier(.2, 1.5, .4, 1) 1s backwards; transform-origin: 295px 50px; }
@keyframes apPop {
  from { opacity: 0; transform: scale(.3); }
  to   { opacity: 1; transform: none; }
}

/* --- register scene: the CV is read and the profile writes itself ----
   One 6.4s cycle shared by every part. The beam sweeps the document, each
   field lands a beat after the beam passes the line it came from, the
   completeness meter climbs behind them and the badge confirms. Phases live
   in the keyframes, never in animation-delay, so nothing drifts. */
.rs-beam { animation: rsBeam 6.4s ease-in-out infinite; }
@keyframes rsBeam {
  0%       { transform: translateY(0);     opacity: 0; }
  5%       { transform: translateY(6px);   opacity: 1; }
  40%      { transform: translateY(142px); opacity: 1; }
  48%      { transform: translateY(142px); opacity: 0; }
  100%     { transform: translateY(0);     opacity: 0; }
}

/* fill-box keeps the origin on the bar itself, so each one grows from its
   own left edge without needing hand-written user-space coordinates. */
.rs-fill { transform: scaleX(0); transform-box: fill-box; transform-origin: left center; }
.rs-fill--1 { animation: rsFill1 6.4s ease-out infinite; }
.rs-fill--2 { animation: rsFill2 6.4s ease-out infinite; }
.rs-fill--3 { animation: rsFill3 6.4s ease-out infinite; }
.rs-fill--4 { animation: rsFill4 6.4s ease-out infinite; }
@keyframes rsFill1 {
  0%, 10%   { transform: scaleX(0); }
  20%, 92%  { transform: scaleX(1); }
  100%      { transform: scaleX(0); }
}
@keyframes rsFill2 {
  0%, 20%   { transform: scaleX(0); }
  30%, 92%  { transform: scaleX(1); }
  100%      { transform: scaleX(0); }
}
@keyframes rsFill3 {
  0%, 30%   { transform: scaleX(0); }
  40%, 92%  { transform: scaleX(1); }
  100%      { transform: scaleX(0); }
}
@keyframes rsFill4 {
  0%, 38%   { transform: scaleX(0); }
  52%, 92%  { transform: scaleX(1); }
  100%      { transform: scaleX(0); }
}

.rs-done { transform-box: fill-box; transform-origin: left center; animation: rsDone 6.4s ease-out infinite; }
@keyframes rsDone {
  0%, 52%   { opacity: 0; transform: scale(.6); }
  62%, 92%  { opacity: 1; transform: scale(1); }
  100%      { opacity: 0; transform: scale(.6); }
}

.rs-wire { stroke-dasharray: 5 7; animation: rsWire 2.6s linear infinite; }
@keyframes rsWire { from { stroke-dashoffset: 48; } to { stroke-dashoffset: 0; } }

/* ---------- demo one-click sign-in (non-production only) ------------- */
.demopanel {
  margin-top: var(--sp-5); padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
}
.demopanel__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.demopanel__hint { font-size: 12px; color: var(--ink-500); }

.demologin { display: grid; gap: 7px; }
.demologin__btn {
  width: 100%; display: grid; grid-template-columns: 30px minmax(0, 1fr) auto 14px;
  align-items: center; gap: var(--sp-3);
  padding: 9px 11px; text-align: left; cursor: pointer;
  font: inherit; font-size: 12.5px; color: var(--ink-800);
  background: var(--surface-alt); border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.demologin__btn:hover {
  border-color: var(--brand-300); background: var(--surface); transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(39, 93, 245, .14);
}
.demologin__btn:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }
.demologin__av {
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  font-size: 12px; font-weight: 700;
}
.demologin__av--violet { background: var(--violet-50); color: var(--violet-500); }
.demologin__av--teal   { background: var(--teal-50);   color: var(--teal-500); }
.demologin__av--amber  { background: var(--amber-50);  color: var(--amber-500); }
.demologin__meta  { min-width: 0; display: grid; gap: 1px; }
.demologin__role  { font-weight: 600; color: var(--ink-900); }
.demologin__email { color: var(--ink-500); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.demologin__pw    { color: var(--ink-600); }
.demologin__go    { color: var(--ink-400); display: grid; place-items: center; transition: transform .16s ease, color .16s ease; }
.demologin__go svg { width: 14px; height: 14px; }
.demologin__btn:hover .demologin__go { color: var(--brand-500); transform: translateX(2px); }

/* ---------- responsive ----------------------------------------------- */
@media (max-width: 940px) {
  /* Form first — the pitch is supporting content, not the task. The brand
     canvas keeps its full-bleed edge and becomes a banner underneath. */
  /* Stacked, a phone cannot hold both panes at once — so the one-screen rule
     is dropped here rather than clipping half the pitch, and the footer comes
     back because the page is a scrolling page again. */
  .austage { grid-template-columns: 1fr; height: auto; }
  .auform  { overflow-y: visible; }
  .auth-screen .footer { display: block; }
  .auform  { order: 1; padding: var(--sp-7) var(--sp-4) var(--sp-6); }
  .aubrand { order: 2; padding: var(--sp-7) var(--sp-5); }
  .aubrand__inner { width: min(560px, 100%); }
  .aubrand__title { font-size: clamp(26px, 6vw, 34px); }
  /* The scene is the one part that stops earning its height on a phone. */
  .aubrand__art { display: none; }
  /* Two 58px fields side by side in a 410px pane is cramped before it is
     compact, so the pair stacks as soon as the stage does. */
  .aupair { grid-template-columns: 1fr; }
}

/* Short viewport — a 13" laptop with the browser chrome taking its share.
   The scene SHRINKS rather than disappearing: it is the only moving thing on
   the brand side, and removing it left a wall of static text. Scaling keeps
   the animation on screen and still returns the height the layout needs. */
@media (min-width: 941px) and (max-height: 860px) {
  .aubrand { padding-block: var(--sp-6); }
  .aubrand__art { margin: var(--sp-4) 0; }
  .aubrand__art svg { max-width: 76%; margin-inline: auto; }
}
@media (min-width: 941px) and (max-height: 740px) {
  .aubrand__art svg { max-width: 58%; }
  .aubrand__title { font-size: clamp(26px, 2.6vw, 34px); }
  .aubrand__list li { font-size: 13.5px; }
}
@media (min-width: 941px) and (max-height: 640px) {
  .demopanel { display: none; }
  .aubrand__art svg { max-width: 46%; }
}

@media (max-width: 430px) {
  .demologin__btn { grid-template-columns: 30px minmax(0, 1fr) 14px; }
  .demologin__pw  { display: none; }
  .aurole { grid-template-columns: 1fr; }
}

/* Decorative motion only — honour the OS setting. */
@media (prefers-reduced-motion: reduce) {
  .aubrand__aura, .aubrand__pulse, .aurise, .btn--sheen::after,
  .aubrand__title em, .aubrand__spark--a, .aubrand__spark--b,
  .ap-float, .ap-meter, .ap-ring, .ap-job, .ap-wire, .ap-check,
  .rs-beam, .rs-fill, .rs-done, .rs-wire {
    animation: none !important;
  }
  /* The sheen parks at its first stop, which is solid white — the phrase
     stays legible with no animation to move the highlight along. */
  .aubrand__spark--a, .aubrand__spark--b { opacity: 1; transform: none; }
  .ap-job, .ap-check { opacity: 1; transform: none; }
  .ap-meter { transform: scaleX(1); }
  /* Both scenes rest in their finished state: the profile filled in and
     confirmed. A half-drawn illustration would just look broken. */
  .rs-fill { transform: scaleX(1); }
  .rs-done { opacity: 1; transform: none; }
  .rs-beam { opacity: 0; }
  .aurise   { opacity: 1; transform: none; }
  .aff__label { transition: none; }
  .aurole__box:hover, .demologin__btn:hover, .btn--sheen:hover { transform: none; }
}

/* ---------- progress ------------------------------------------------ */
.progress { height: 8px; background: var(--surface-sunk); border-radius: var(--r-pill); overflow: hidden; }
.progress__bar { height: 100%; background: var(--brand-500); border-radius: var(--r-pill); transition: width .4s ease; }
.progress__bar--ok  { background: var(--ok-500); }
.progress__bar--bad { background: var(--bad-500); }

.ring__track { stroke: var(--surface-sunk); }
.ring__text  { font-size: 12px; font-weight: 700; fill: var(--ink-800); }
.ring--ok   .ring__bar { stroke: var(--ok-500); }
.ring--warn .ring__bar { stroke: var(--warn-500); }
.ring--bad  .ring__bar { stroke: var(--bad-500); }

/* ---------- pagination ---------------------------------------------- */
.pager { display: flex; align-items: center; gap: var(--sp-1); justify-content: center; margin-top: var(--sp-5); flex-wrap: wrap; }
.pager__link {
  min-width: 36px; height: 36px; padding: 0 var(--sp-3);
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink-700); font-size: 13px;
}
.pager__link:hover { border-color: var(--brand-400); color: var(--brand-500); text-decoration: none; }
.pager__link.is-current { background: var(--brand-500); border-color: var(--brand-500); color: #fff; font-weight: 600; }
.pager__link.is-disabled { opacity: .45; pointer-events: none; }
.pager__gap { padding: 0 var(--sp-1); color: var(--ink-400); }

/* ---------- empty state --------------------------------------------- */
.empty { text-align: center; padding: var(--sp-7) var(--sp-4); color: var(--ink-600); }
.empty__art { font-size: 40px; margin-bottom: var(--sp-3); opacity: .45; }
.empty__title { font-size: 16px; font-weight: 600; color: var(--ink-800); margin-bottom: var(--sp-2); }

/* ---------- steps (import wizard) ----------------------------------- */
.steps { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-5); flex-wrap: wrap; }
.step { display: flex; align-items: center; gap: var(--sp-2); color: var(--ink-500); font-size: 13px; }
.step__num {
  width: 24px; height: 24px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  background: var(--surface-sunk); color: var(--ink-500); border: 1px solid var(--line);
}
.step.is-current { color: var(--brand-600); font-weight: 600; }
.step.is-current .step__num { background: var(--brand-500); color: #fff; border-color: var(--brand-500); }
.step.is-done .step__num { background: var(--ok-500); color: #fff; border-color: var(--ok-500); }
.step.is-done { color: var(--ok-500); }
.step__line { width: 28px; height: 1px; background: var(--line-strong); }

/* ---------- footer -------------------------------------------------- */
.footer {
  background: var(--ink-900); color: var(--ink-400);
  padding: var(--sp-6) 0 var(--sp-5); margin-top: var(--sp-7); font-size: 13px;
}
.footer a { color: var(--ink-400); }
.footer a:hover { color: #fff; }
.footer__grid { display: grid; grid-template-columns: 2fr repeat(3, 1fr); gap: var(--sp-5); }
.footer__title { color: #fff; font-size: 13px; font-weight: 700; margin-bottom: var(--sp-3); text-transform: uppercase; letter-spacing: .5px; }
.footer__links { display: flex; flex-direction: column; gap: var(--sp-2); }
.footer__bar { border-top: 1px solid rgba(255,255,255,.1); margin-top: var(--sp-5); padding-top: var(--sp-4); display: flex; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap; }

/* ---------- auth pages ---------------------------------------------- */
.auth { min-height: calc(100vh - var(--topbar-h)); display: grid; place-items: center; padding: var(--sp-6) var(--sp-4); }
.auth__card { width: min(430px, 100%); }
.auth__head { text-align: center; margin-bottom: var(--sp-5); }
.auth__divider { display: flex; align-items: center; gap: var(--sp-3); color: var(--ink-500); font-size: 12.5px; margin: var(--sp-4) 0; }
.auth__divider::before, .auth__divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* role picker on the register screen */
.rolepick { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.rolepick__opt { position: relative; }
.rolepick__opt input { position: absolute; opacity: 0; pointer-events: none; }
.rolepick__box {
  display: block; padding: var(--sp-4); text-align: center; cursor: pointer;
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  transition: border-color .15s ease, background .15s ease;
}
.rolepick__opt input:checked + .rolepick__box { border-color: var(--brand-500); background: var(--brand-50); box-shadow: 0 0 0 1px var(--brand-500) inset; }
.rolepick__opt input:focus-visible + .rolepick__box { outline: 2px solid var(--brand-400); outline-offset: 2px; }
.rolepick__box b { display: block; color: var(--ink-900); }
.rolepick__box span { font-size: 12.5px; color: var(--ink-600); }

/* ---------- dropzone ------------------------------------------------ */
.dropzone {
  /* Applied to a <label>, which is inline by default — without this the
     dashed border wraps the inline text instead of forming a box, and the
     block-level children spill outside it. */
  display: block;
  border: 2px dashed var(--line-strong); border-radius: var(--r-lg);
  padding: var(--sp-7) var(--sp-5); text-align: center;
  background: var(--surface-alt); cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.dropzone:hover, .dropzone.is-over { border-color: var(--brand-400); background: var(--brand-50); }
.dropzone__art { font-size: 34px; opacity: .5; margin-bottom: var(--sp-2); color: var(--ink-500); }
.dropzone__art svg { width: 30px; height: 30px; display: block; margin: 0 auto; }
.dropzone__hint { font-size: 12.5px; color: var(--ink-500); }
.dropzone input[type=file] { display: none; }

/* ---------- misc ---------------------------------------------------- */
.divider { height: 1px; background: var(--line); border: 0; margin: var(--sp-5) 0; }
.kv { display: grid; grid-template-columns: 150px 1fr; gap: var(--sp-2) var(--sp-4); font-size: 13.5px; }
.kv dt { color: var(--ink-600); }
.kv dd { margin: 0; color: var(--ink-900); }
.mono { font-family: var(--mono); font-size: 12.5px; }
.code-block {
  background: var(--ink-900); color: #d8e0ee; padding: var(--sp-4);
  border-radius: var(--r-md); overflow-x: auto; font-family: var(--mono); font-size: 12.5px;
}

/* ---------- deterministic accent tones ------------------------------
   Applied to avatars and company logos via tone_of(). Decorative only —
   initials and the adjacent name always carry the identity, so the hue
   never has to be distinguishable to be usable. Tinted background with a
   matching darker ink keeps every pairing readable. */
.t1 { background: var(--brand-50)  !important; color: var(--brand-600)  !important; }
.t2 { background: var(--violet-50) !important; color: var(--violet-500) !important; }
.t3 { background: var(--teal-50)   !important; color: var(--teal-500)   !important; }
.t4 { background: var(--amber-50)  !important; color: var(--amber-500)  !important; }
.t5 { background: var(--pink-50)   !important; color: var(--pink-500)   !important; }
.t6 { background: var(--lime-50)   !important; color: var(--lime-500)   !important; }
.t7 { background: var(--sky-50)    !important; color: var(--sky-500)    !important; }
.t8 { background: var(--cta-50)    !important; color: var(--cta-500)    !important; }

/* Solid variants for larger avatars, where a tint reads as washed out. */
.ts1 { background: var(--brand-500)  !important; color:#fff !important; }
.ts2 { background: var(--violet-500) !important; color:#fff !important; }
.ts3 { background: var(--teal-500)   !important; color:#fff !important; }
.ts4 { background: var(--amber-500)  !important; color:#fff !important; }
.ts5 { background: var(--pink-500)   !important; color:#fff !important; }
.ts6 { background: var(--lime-500)   !important; color:#fff !important; }
.ts7 { background: var(--sky-500)    !important; color:#fff !important; }
.ts8 { background: var(--cta-500)    !important; color:#fff !important; }

/* ---------- tinted stat tiles ---------------------------------------
   A soft wash of the tile's own hue rather than plain white — the whole
   dashboard row reads as colour at a glance instead of a grey grid. */
/* Flat fills straight from the palette's own -50 tints. An earlier pass used
   hand-mixed gradients (#cdeccf, #ffeec2 …) that sat outside the token set,
   which is how a design system quietly grows a second, unmanaged palette.
   Every value below is a token this file already defines. */
.tile--brand  { background: var(--brand-50); }
.tile--ok     { background: var(--ok-50); }
.tile--warn   { background: var(--warn-50); }
.tile--bad    { background: var(--bad-50); }
.tile--violet { background: var(--violet-50); }
.tile--teal   { background: var(--teal-50); }

/* The number takes the tile's own hue, darkened to the -600/-700 step so it
   clears AA on the wash behind it. The label stays neutral, so hue is never
   the only thing telling the four tiles apart. */
.tile--brand  .tile__value { color: var(--brand-700); }
.tile--ok     .tile__value { color: var(--ok-600); }
.tile--warn   .tile__value { color: var(--warn-600); }
.tile--bad    .tile__value { color: var(--bad-600); }
.tile--violet .tile__value { color: var(--violet-600); }
.tile--teal   .tile__value { color: #0a7b74; }

/* ---------- coloured side navigation -------------------------------- */
.sidenav__icon {
  display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: 7px;
  font-size: 12.5px; opacity: 1;
  background: var(--surface-sunk); color: var(--ink-500);
  transition: background .15s ease, color .15s ease;
}
.sidenav__link:hover .sidenav__icon,
.sidenav__link.is-active .sidenav__icon { background: var(--brand-500); color: #fff; }
.sidenav__link .sidenav__icon.n1 { background: var(--brand-50);  color: var(--brand-500); }
.sidenav__link .sidenav__icon.n2 { background: var(--violet-50); color: var(--violet-500); }
.sidenav__link .sidenav__icon.n3 { background: var(--teal-50);   color: var(--teal-500); }
.sidenav__link .sidenav__icon.n4 { background: var(--amber-50);  color: var(--amber-500); }
.sidenav__link .sidenav__icon.n5 { background: var(--pink-50);   color: var(--pink-500); }
.sidenav__link .sidenav__icon.n6 { background: var(--sky-50);    color: var(--sky-500); }
.sidenav__link .sidenav__icon.n7 { background: var(--lime-50);   color: var(--lime-500); }
.sidenav__link .sidenav__icon.n8 { background: var(--cta-50);    color: var(--cta-500); }

/* ---------- coloured card headers ------------------------------------ */
.card__head--tinted {
  background: linear-gradient(90deg, var(--brand-50), transparent);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}

/* ---------- multi-hue chips ------------------------------------------ */
.chip--t1 { background: var(--brand-50);  border-color: var(--brand-100);  color: var(--brand-600); }
.chip--t2 { background: var(--violet-50); border-color: #e2d4ff;           color: var(--violet-500); }
.chip--t3 { background: var(--teal-50);   border-color: #c4ece9;           color: var(--teal-500); }
.chip--t4 { background: var(--amber-50);  border-color: #f5e2b0;           color: var(--amber-500); }
.chip--t5 { background: var(--pink-50);   border-color: #fbd2e0;           color: var(--pink-500); }
.chip--t6 { background: var(--lime-50);   border-color: #d9edc0;           color: var(--lime-500); }
.chip--t7 { background: var(--sky-50);    border-color: #c6e6fa;           color: var(--sky-500); }
.chip--t8 { background: var(--cta-50);    border-color: #fbd3c7;           color: var(--cta-500); }

/* ---------- campaign builder ----------------------------------------- */

/* Audience switch. Links, not tabs — each one loads its own builder with a
   different recipient query, placeholder set and default template. */
.segbar {
  display: inline-flex; gap: 3px; padding: 3px; margin-bottom: 22px;
  background: var(--surface-sunk); border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
.segbar__item {
  padding: 7px 18px; border-radius: var(--r-pill);
  font-size: 13.5px; font-weight: 600; color: var(--ink-600);
}
.segbar__item:hover { color: var(--ink-900); text-decoration: none; }
.segbar__item.is-on { background: var(--surface); color: var(--brand-500); box-shadow: var(--shadow-sm); }

/* Recipient picker. Scrolls internally so a 300-row audience can't push the
   Queue button off the bottom of a very long page. */
.picklist { max-height: 340px; overflow-y: auto; margin: 0 -6px; padding: 0 6px; }
.picklist__row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 8px 9px; border-radius: var(--r-md); cursor: pointer;
}
.picklist__row:hover { background: var(--surface-sunk); }
.picklist__row:has(input:checked) { background: var(--brand-50); }
.picklist__row input { margin-top: 3px; accent-color: var(--brand-500); flex: none; }
.picklist__name { display: block; font-size: 13.5px; color: var(--ink-900); font-weight: 500; }
.picklist__meta { display: block; font-size: 12px; color: var(--ink-500); overflow-wrap: anywhere; }

/* Message preview.
   The body is admin-authored HTML with its own <html>, inline styles and a
   dark header bar. Rendered in a sandboxed iframe it cannot inherit this
   page's CSS, reach the admin session, or escape its box — and it is what
   the recipient actually receives, not an approximation. */
.mailprev__frame {
  display: block; width: 100%; height: 460px; border: 0;
  border-top: 1px solid var(--line); background: #f4f6fa;
}
.mailprev__text { border-top: 1px solid var(--line); }
.mailprev__text summary {
  padding: 11px var(--sp-4); cursor: pointer;
  font-size: 13px; font-weight: 600; color: var(--ink-700);
}
.mailprev__text summary:hover { color: var(--brand-500); }
.mailprev__text pre {
  margin: 0; padding: 0 var(--sp-4) var(--sp-4);
  font-family: var(--mono); font-size: 12px; line-height: 1.6;
  color: var(--ink-700); white-space: pre-wrap; overflow-wrap: anywhere;
}

/* A role choice is a consequential decision, so each option is a full card
   with its consequence spelled out rather than a bare radio and one word. */
.check--role {
  align-items: flex-start; gap: var(--sp-3);
  padding: 12px var(--sp-4); border: 1px solid var(--line);
  border-radius: var(--r-md); background: var(--surface);
  transition: border-color .15s ease, background .15s ease;
}
.check--role:hover { border-color: var(--brand-300); background: var(--brand-50); }
.check--role:has(input:checked) {
  border-color: var(--brand-500); background: var(--brand-50);
  box-shadow: 0 0 0 1px var(--brand-500);
}
.check--role:focus-within { box-shadow: 0 0 0 3px var(--brand-100); }
.check--role input { margin-top: 2px; }
.check--role strong { font-size: 14px; color: var(--ink-900); }

/* password field with a Show/Hide affordance */
.pwfield { position: relative; }
.pwfield .input { padding-right: 62px; }
.pwfield__toggle {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  border: 0; background: none; cursor: pointer; font: inherit;
  font-size: 13px; font-weight: 600; color: var(--brand-500); padding: 4px;
}
.pwfield__toggle:hover { text-decoration: underline; }

/* =====================================================================
   Seeker profile — a profile that reads before it edits.

   Each card carries one accent hue, set once here as --pt / --pt-50 /
   --pt-line and consumed by every rule below, so a card's icon, wash,
   rule and Edit control can never drift apart. Colour is decoration: the
   tick, the "Incomplete" chip and the "Not added" wording each state the
   same fact in text.
   ===================================================================== */
.pcard--brand,  .pfacts__i--brand,  .ptodo__i--brand,  .proflink--brand
  { --pt: var(--brand-500);  --pt-50: var(--brand-50);  --pt-line: var(--brand-100); }
.pcard--violet, .pfacts__i--violet, .ptodo__i--violet, .proflink--violet
  { --pt: var(--violet-600); --pt-50: var(--violet-50); --pt-line: #e2d4ff; }
.pcard--teal,   .pfacts__i--teal,   .ptodo__i--teal,   .proflink--teal
  { --pt: var(--teal-500);   --pt-50: var(--teal-50);   --pt-line: #c4ece9; }
.pcard--amber,  .pfacts__i--amber,  .ptodo__i--amber,  .proflink--amber
  { --pt: var(--amber-500);  --pt-50: var(--amber-50);  --pt-line: #f5e2b0; }
.pcard--pink,   .pfacts__i--pink,   .ptodo__i--pink,   .proflink--pink
  { --pt: var(--pink-500);   --pt-50: var(--pink-50);   --pt-line: #fbd2e0; }
.pcard--lime,   .pfacts__i--lime,   .ptodo__i--lime,   .proflink--lime
  { --pt: var(--lime-500);   --pt-50: var(--lime-50);   --pt-line: #d9edc0; }
.pcard--sky,    .pfacts__i--sky,    .ptodo__i--sky,    .proflink--sky
  { --pt: var(--sky-600);    --pt-50: var(--sky-50);    --pt-line: #c6e6fa; }

/* ---------- header -------------------------------------------------- */
.profhead {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
  overflow: hidden; margin-bottom: var(--sp-4);
}
.profhead__band {
  height: 92px;
  background:
    radial-gradient(460px 180px at 8% 120%,  rgba(224, 65, 122, .55), transparent 70%),
    radial-gradient(520px 200px at 92% -20%, rgba(137, 81, 255, .65), transparent 70%),
    radial-gradient(420px 160px at 50% 140%, rgba(14, 155, 147, .45), transparent 70%),
    linear-gradient(110deg, var(--brand-600), var(--brand-400) 60%, var(--brand-300));
}
.profhead__body { position: relative; padding: 0 var(--sp-5) var(--sp-5); }

/* The avatar is placed, not laid out: it is the one element meant to overlap
   the band, so it says so directly.

   Bottom-aligning the text to the avatar instead made the name's top edge
   `avatarBottom - textHeight` — arithmetic that landed 4px inside the
   coloured band, and that a headline wrapping to two lines would have
   driven further in. The row now reserves the avatar's width as padding
   and starts its own text a fixed distance below the band, so no amount of
   text can climb into it. */
.profhead__avatar {
  position: absolute; left: var(--sp-5); top: -42px;
  width: 96px; height: 96px; border-radius: 50%; overflow: hidden;
  display: grid; place-items: center; font-size: 32px; font-weight: 700;
  font-family: var(--font-display); letter-spacing: -.02em;
  background: var(--surface); color: var(--brand-600);
  border: 4px solid var(--surface); box-shadow: var(--shadow-md);
}
.profhead__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.profhead__row {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-4) 0 0 120px;   /* 96px avatar + 24px gutter */
  min-height: 74px;                 /* clears the avatar's 54px below the band */
}
.profhead__id { min-width: 0; }
.profhead__name { margin: 0 0 4px; font-size: 24px; line-height: 1.25; }
.profhead__role { margin: 0; color: var(--ink-600); font-size: 14px; line-height: 1.45; }
.profhead__role--todo { color: var(--ink-400); font-style: italic; }
.profhead__cta { display: flex; gap: var(--sp-2); flex: none; flex-wrap: wrap; }
.profhead__cta .btn svg { width: 13px; height: 13px; flex: none; }

/* key facts — one tinted chip per fact, each in its own hue */
.pfacts {
  list-style: none; margin: var(--sp-4) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--sp-2);
}
.pfacts__i {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 13px 7px 8px; border-radius: var(--r-pill);
  background: var(--pt-50); border: 1px solid var(--pt-line);
  font-size: 13px; color: var(--ink-800); min-width: 0;
}
.pfacts__ic {
  width: 24px; height: 24px; border-radius: 50%; flex: none;
  display: grid; place-items: center; background: var(--pt); color: #fff;
}
.pfacts__ic svg { width: 12px; height: 12px; }
.pfacts__k { display: block; font-size: 10.5px; font-weight: 700; color: var(--pt);
  text-transform: uppercase; letter-spacing: .05em; line-height: 1.3; }
.pfacts__i > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* strength strip */
.pstrength {
  display: flex; align-items: center; gap: var(--sp-4);
  margin-top: var(--sp-4); padding: var(--sp-4);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: linear-gradient(100deg, var(--brand-50), var(--violet-50) 55%, var(--pink-50));
}
.pstrength .ring { flex: none; }
.pstrength__top { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: 9px; }
.pstrength__top strong { font-size: 14.5px; color: var(--ink-900); }
.pstrength__count { margin-left: auto; }
.pstrength__note { margin: 9px 0 0; font-size: 12.5px; color: var(--ink-600); }

/* completeness meter */
.meter { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; }
.meter__bar {
  flex: 1 1 220px; height: 10px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .75); overflow: hidden; min-width: 160px;
  box-shadow: inset 0 1px 2px rgba(16, 21, 31, .07);
}
.meter__fill {
  height: 100%; border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--brand-500), var(--violet-500), var(--pink-500));
  transition: width .5s ease;
}
.meter__fill--low  { background: linear-gradient(90deg, var(--bad-500), #f0855f); }
.meter__fill--mid  { background: linear-gradient(90deg, var(--warn-500), #f2c14e); }
.meter__pct { font-size: 22px; font-weight: 700; color: var(--ink-900); }

/* ---------- two-column page ----------------------------------------- */
.proflayout { display: flex; align-items: flex-start; gap: 18px; }
.proflayout__main { flex: 1 1 0%; min-width: 0; }
.proflayout__rail { width: 304px; flex: none; }
/* Sticks as a unit so the rail tracks the form instead of stranding a
   short card beside a very long one. */
.profrail { position: sticky; top: 76px; display: flex; flex-direction: column; gap: var(--sp-3); }

/* ---------- one profile card ---------------------------------------- */
.pcard {
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--pt);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
  margin-bottom: var(--sp-3); scroll-margin-top: 76px;
  transition: box-shadow .18s ease, border-color .18s ease;
}
.pcard:hover { box-shadow: var(--shadow-md); }
.pcard.is-editing { box-shadow: 0 0 0 3px var(--pt-50), var(--shadow-md); }
.pcard__head {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 13px var(--sp-4);
  background: linear-gradient(95deg, var(--pt-50), transparent 62%);
  border-radius: 0 var(--r-lg) 0 0;
  border-bottom: 1px solid var(--line);
}
.pcard__icon {
  width: 36px; height: 36px; border-radius: 10px; flex: none;
  display: grid; place-items: center;
  background: var(--pt); color: #fff;
  box-shadow: 0 4px 10px rgba(16, 21, 31, .16);
}
.pcard__icon svg { width: 17px; height: 17px; }
.pcard__title { font-size: 15px; font-weight: 700; color: var(--ink-900); margin: 0;
  font-family: var(--font-display); letter-spacing: -.02em; }
.pcard__sub { font-size: 12.5px; color: var(--ink-600); margin: 2px 0 0; }
.pcard__flag {
  flex: none; padding: 3px 10px; border-radius: var(--r-pill);
  background: var(--warn-50); color: var(--warn-600);
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
}
.pcard__edit {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid var(--pt-line);
  color: var(--pt); font-size: 13px; font-weight: 600;
}
.pcard__edit:hover { background: var(--pt); border-color: var(--pt); color: #fff; text-decoration: none; }
.pcard__edit svg { width: 12px; height: 12px; }
.pcard.is-editing .pcard__edit { display: none; }

.pcard__view { padding: var(--sp-4); }
.pcard__body { padding: var(--sp-4); }
.pcard__foot {
  display: flex; gap: var(--sp-2); align-items: center;
  padding: 11px var(--sp-4);
  border-top: 1px solid var(--line); background: var(--surface-alt);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* read-only rows */
.pkv { margin: 0; display: grid; gap: 10px var(--sp-4); }
.pkv--top { margin-top: var(--sp-4); padding-top: var(--sp-4); border-top: 1px dashed var(--line); }
.pkv__row { display: grid; grid-template-columns: 170px 1fr; gap: var(--sp-3); align-items: baseline; }
.pkv__k { font-size: 12.5px; color: var(--ink-500); font-weight: 500; }
.pkv__v { margin: 0; font-size: 14px; color: var(--ink-900); font-weight: 500; min-width: 0; overflow-wrap: anywhere; }
.pkv__v--empty { color: var(--ink-400); font-weight: 400; font-style: italic; }
.pkv__hint { display: block; font-size: 12px; color: var(--ink-500); font-weight: 400; font-style: normal; margin-top: 2px; }

.psummary { margin: var(--sp-3) 0 0; font-size: 14px; line-height: 1.65; color: var(--ink-700); }
.pempty {
  margin: 0; padding: 14px var(--sp-4); border-radius: var(--r-md);
  background: var(--pt-50); border: 1px dashed var(--pt-line);
  font-size: 13px; color: var(--ink-700);
}
.pskills { margin-bottom: 0; }

/* the uploaded-resume row */
.pfile {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 12px var(--sp-3); border-radius: var(--r-md);
  background: var(--pt-50); border: 1px solid var(--pt-line);
}
.pfile__ic {
  width: 34px; height: 34px; border-radius: var(--r-md); flex: none;
  display: grid; place-items: center; background: var(--pt); color: #fff;
}
.pfile__ic svg { width: 16px; height: 16px; }
.pfile__name { display: block; font-size: 14px; color: var(--ink-900); overflow-wrap: anywhere; }

.pstate { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.pstate svg { width: 12px; height: 12px; }
.pstate--on  { color: var(--ok-600); }
.pstate--off { color: var(--ink-500); }

/* ---------- right rail ---------------------------------------------- */
.ptodo { border: 1px solid var(--warn-500); }
.ptodo__head { background: linear-gradient(95deg, var(--warn-50), transparent); }
.ptodo__i {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 10px; border-radius: var(--r-md); color: var(--ink-800);
}
.ptodo__i + .ptodo__i { margin-top: 2px; }
.ptodo__i:hover { background: var(--pt-50); text-decoration: none; color: var(--ink-900); }
.ptodo__ic {
  width: 22px; height: 22px; border-radius: 50%; flex: none; margin-top: 1px;
  display: grid; place-items: center; background: var(--pt); color: #fff;
}
.ptodo__ic svg { width: 10px; height: 10px; }
.ptodo__t { display: block; font-size: 13.5px; font-weight: 600; }
.ptodo__s { display: block; font-size: 12px; color: var(--ink-500); margin-top: 1px; }

/* nav that jumps between profile cards */
.proflinks { display: flex; flex-direction: column; gap: 2px; }
.proflink {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: var(--r-md);
  font-size: 13.5px; color: var(--ink-700);
}
.proflink:hover { background: var(--pt-50); text-decoration: none; color: var(--ink-900); }
.proflink.is-current { background: var(--pt-50); color: var(--ink-900); font-weight: 600; }
.proflink__ic {
  width: 24px; height: 24px; border-radius: 7px; flex: none;
  display: grid; place-items: center;
  background: var(--pt-50); color: var(--pt); border: 1px solid var(--pt-line);
}
.proflink.is-current .proflink__ic { background: var(--pt); color: #fff; border-color: var(--pt); }
.proflink__ic svg { width: 12px; height: 12px; }
.proflink__state { flex: none; font-size: 13px; line-height: 1; }
.proflink__state svg { width: 13px; height: 13px; display: block; }
.proflink__state--done { color: var(--ok-500); }
.proflink__state--todo { color: var(--ink-400); }

/* visibility card */
.pvis .card__body { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.pvis__ic {
  width: 32px; height: 32px; border-radius: var(--r-md); flex: none;
  display: grid; place-items: center; color: #fff;
}
.pvis__ic svg { width: 15px; height: 15px; }
.pvis--on  .pvis__ic { background: var(--ok-500); }
.pvis--off .pvis__ic { background: var(--ink-400); }
.pvis__t { display: block; font-size: 13.5px; color: var(--ink-900); }
.pvis--on  { border-left: 3px solid var(--ok-500); }
.pvis--off { border-left: 3px solid var(--ink-400); }

/* ---------- richer stat tiles --------------------------------------- */
.tile { position: relative; overflow: hidden; }
.tile__icon {
  position: absolute; right: 14px; top: 14px;
  width: 34px; height: 34px; border-radius: var(--r-md);
  display: grid; place-items: center; font-size: 15px;
}
/* Solid badge, white glyph. A tint-on-tint chip disappeared against the
   warmer card behind it. */
.tile__icon { color: #fff; box-shadow: 0 4px 12px rgba(16, 21, 31, .18); }
.tile--brand  .tile__icon { background: var(--brand-500); }
.tile--ok     .tile__icon { background: var(--ok-500); }
.tile--warn   .tile__icon { background: var(--warn-500); }
.tile--bad    .tile__icon { background: var(--bad-500); }
.tile--violet .tile__icon { background: var(--violet-500); }
.tile--violet { border-left: 3px solid var(--violet-500); }
.tile--teal   .tile__icon { background: var(--teal-500); }
.tile--teal   { border-left: 3px solid var(--teal-500); }

/* ---------- simple bar chart (dashboards) ---------------------------
   Values are always printed as text beside the bar, so the chart adds
   comparison at a glance without being the only way to read the data. */
.bars { display: flex; flex-direction: column; gap: var(--sp-3); }
.bars__row { display: grid; grid-template-columns: 116px 1fr 56px; gap: var(--sp-3); align-items: center; }
.bars__label { font-size: 13px; color: var(--ink-700); }
.bars__track { height: 9px; background: var(--surface-sunk); border-radius: var(--r-pill); overflow: hidden; }
.bars__fill  { height: 100%; border-radius: var(--r-pill); background: var(--brand-500); }
/* Chart status hues.
   NOT the same as the UI status colours: the UI pair (green #2e9b31 /
   amber #b57b00) collapses to ΔE 4.5 under deuteranopia, so in a chart —
   where the fill is doing the comparing — green and amber are
   indistinguishable to a red-green colourblind reader even though they
   separate fine in normal vision (ΔE 17.5).
   This set was checked with the palette validator and passes lightness,
   chroma, CVD separation and contrast. Every bar also carries a text
   label and its value, so colour is never the only encoding. */
.bars__fill--c1 { background: #0e9b93; }   /* teal   — active   */
.bars__fill--c2 { background: #d99400; }   /* amber  — pending  */
.bars__fill--c3 { background: #6f7fd4; }   /* indigo — inactive */
.bars__fill--c4 { background: #d93a22; }   /* red    — blocked  */
.bars__value { font-size: 13px; font-weight: 600; color: var(--ink-900); text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- settings page ------------------------------------------- */
.setrow {
  display: grid; grid-template-columns: 230px 1fr; gap: var(--sp-4);
  padding: 16px 0; border-bottom: 1px solid var(--line);
}
.setrow:last-child { border-bottom: 0; }
.setrow__label { font-weight: 600; color: var(--ink-900); font-size: 14px; }
.setrow__help { font-size: 12.5px; color: var(--ink-500); margin-top: 4px; }

/* ---------- responsive ---------------------------------------------- */
@media (max-width: 1024px) {
  .shell { flex-direction: column; }
  .sidenav { width: 100%; position: static; }
  .sidenav__group { display: flex; flex-wrap: wrap; gap: var(--sp-1); }
  .sidenav__label { width: 100%; }
  .filters { width: 100%; }
  .footer__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 900px) {
  .setrow { grid-template-columns: 1fr; gap: var(--sp-2); }
}

/* Stacked, the rail moves above the cards — it is wayfinding for the column
   below it, and the old layout stranded it at the very bottom of the page
   where it could not be acted on.

   The jump-nav is dropped at this width: with the cards stacked it lists the
   same seven headings in the same order as the page immediately under it, so
   it is pure duplication. "What's left" and the visibility state are not, and
   both stay. */
@media (max-width: 1080px) {
  .proflayout { flex-direction: column; }
  .proflayout__rail { width: 100%; order: -1; }
  .profrail { position: static; }
  .pnav { display: none; }
}

@media (max-width: 720px) {
  .container, .container--narrow, .container--wide { width: calc(100% - 24px); }
  .hero { padding: var(--sp-6) 0; }
  /* hero__trio already scales with clamp(); this just tightens the floor. */
  .hero__trio { font-size: 26px; letter-spacing: -.6px; }
  /* Stacked, there is no column beside the avatar to reserve — it returns to
     the flow and simply hangs off the band above the name. */
  .profhead__avatar { position: static; width: 76px; height: 76px; font-size: 26px; margin-top: -38px; }
  .profhead__row {
    flex-direction: column; align-items: flex-start; gap: var(--sp-3);
    padding: 0; min-height: 0;
  }
  .profhead__body { padding: 0 var(--sp-4) var(--sp-4); }
  .profhead__name { font-size: 21px; }
  .profhead__cta { width: 100%; }
  .profhead__cta .btn { flex: 1 1 auto; }
  .pstrength { flex-direction: column; align-items: stretch; gap: var(--sp-3); }
  .pstrength .ring { align-self: flex-start; }
  .pstrength__count { margin-left: 0; width: 100%; }
  .pkv__row { grid-template-columns: 1fr; gap: 2px; }
  .pcard__head { flex-wrap: wrap; }
  .pcard__head .grow { flex-basis: 60%; }
  .bars__row { grid-template-columns: 96px 1fr 48px; }
  .searchbar { flex-direction: column; border-radius: var(--r-lg); padding: var(--sp-3); gap: var(--sp-2); }
  .searchbar__seg + .searchbar__seg { border-left: 0; border-top: 1px solid var(--line); }
  .searchbar .btn { width: 100%; }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .topnav { gap: 0; }
  .topnav__link { padding: var(--sp-2); font-size: 13px; }
  .footer__grid { grid-template-columns: 1fr; }
  .kv { grid-template-columns: 1fr; gap: 2px var(--sp-4); }
  .kv dd { margin-bottom: var(--sp-2); }
  .jobcard__top { flex-direction: column; gap: var(--sp-3); }
}

@media print {
  .topbar, .sidenav, .footer, .btn, .pager { display: none !important; }
  body { background: #fff; }
  .card, .jobcard { box-shadow: none; border-color: #ccc; }
}

/* =====================================================================
   QuickProfile — the "reading your résumé" panel.
   Shown after the form is really posted, so the stages describe work that
   is genuinely under way rather than a decorative wait.
   ===================================================================== */
.reading { padding: var(--sp-6) var(--sp-4); text-align: center; border-top: 1px solid var(--line); }
.reading[hidden] { display: none; }

.reading__scan {
  position: relative; width: 96px; height: 120px; margin: 0 auto var(--sp-4);
}
.reading__doc {
  position: absolute; inset: 0; border-radius: 8px;
  background: #fff; border: 2px solid var(--brand-200);
  box-shadow: var(--shadow-md);
  /* Text lines drawn with a repeating gradient — no extra markup. */
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0 16px,
    var(--brand-50) 16px 22px,
    transparent 22px 30px);
}
.reading__beam {
  position: absolute; left: -4px; right: -4px; height: 14px; border-radius: 8px;
  background: linear-gradient(90deg, transparent, var(--brand-400), transparent);
  box-shadow: 0 0 18px 5px rgba(39, 93, 245, .45);
  animation: readScan 1.5s ease-in-out infinite;
}
@keyframes readScan {
  0%, 100% { top: 4px; }
  50%      { top: 100px; }
}

.reading__now { margin: 0 0 var(--sp-3); font-size: 15px; font-weight: 700; color: var(--ink-900); }
.reading__steps {
  list-style: none; margin: 0 auto; padding: 0; max-width: 22em; text-align: left;
}
.reading__steps li {
  position: relative; padding: 5px 0 5px 26px;
  font-size: 13px; color: var(--ink-400);
  transition: color .3s ease;
}
.reading__steps li::before {
  content: "○"; position: absolute; left: 0; top: 4px; font-size: 13px;
}
.reading__steps li.is-doing { color: var(--brand-600); font-weight: 600; }
.reading__steps li.is-doing::before { content: "◍"; }
.reading__steps li.is-done { color: var(--ok-600); }
.reading__steps li.is-done::before { content: "✓"; font-weight: 700; }

@media (prefers-reduced-motion: reduce) {
  .reading__beam { animation: none; top: 52px; }
}

/* ---------- upload guidance (ResumeRead) ------------------------------
   Two columns, works / won't work. Colour is support only — each column is
   labelled in words and carries a ✓ or ✕ glyph, so the distinction survives
   both colour blindness and a greyscale print.
   -------------------------------------------------------------------- */
.upguide {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.upguide__col {
  padding: var(--sp-4); border-radius: var(--r-lg);
  border: 1px solid var(--line); background: var(--surface);
}
.upguide__col--ok { background: linear-gradient(170deg, var(--ok-50), #fff 70%); border-color: #cce8cd; }
.upguide__col--no { background: linear-gradient(170deg, var(--bad-50), #fff 70%); border-color: #f4cfc9; }
.upguide__head {
  display: flex; align-items: center; gap: 8px; margin-bottom: 10px;
  font-size: 13.5px; font-weight: 700; color: var(--ink-900);
}
.upguide__ico {
  width: 20px; height: 20px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-size: 11px; font-weight: 800; color: #fff;
}
.upguide__col--ok .upguide__ico { background: var(--ok-500); }
.upguide__col--no .upguide__ico { background: var(--bad-500); }
.upguide ul { margin: 0; padding-left: 18px; }
.upguide li { font-size: 13px; color: var(--ink-700); margin-bottom: 5px; }
.upguide__note {
  margin: 10px 0 0; padding-top: 10px; border-top: 1px dashed var(--line);
  font-size: 12.5px; color: var(--ink-600);
}

@media (max-width: 700px) { .upguide { grid-template-columns: 1fr; } }

/* ---------- hero entrance -------------------------------------------
   One utility, one custom property for the delay: --d is a step index, not a
   duration, so the whole cascade can be retimed from a single multiplier.

   `backwards` fill is what stops the flash of un-animated content — without it
   each element paints at its final position for one frame before starting.
   -------------------------------------------------------------------- */
.rise {
  animation: riseIn .62s cubic-bezier(.22, .84, .3, 1) backwards;
  animation-delay: calc(var(--d, 0) * 90ms);
}
@keyframes riseIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
/* The product frame comes in from its own side, so the two columns read as
   arriving together rather than everything sliding the same way. */
.rise--right { animation-name: riseInRight; animation-duration: .78s; }
@keyframes riseInRight {
  from { opacity: 0; transform: translateX(34px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

/* The three headline words are inline flex items, so they need to keep
   their layout box while animating. */
.hero__trio > .rise { display: inline-block; }

@media (prefers-reduced-motion: reduce) {
  .rise { animation: none; opacity: 1; transform: none; }
}

/* =====================================================================
   ResumeRead hero demo - one 16s timeline, absolute percentages.

   No animation-delay anywhere: delays keep an element's period but shift its
   phase for good, so on loop two the cursor would be clicking Browse while
   the last run's fields were still up. Every element gets its own keyframes
   on the shared duration instead.

   Timeline: 0-9% cursor travels | 9-12% click | 12-17% file lands
             17-28% upload | 28-48% read | 48-74% fields fill | 74-92% done
   ===================================================================== */
/* min-height reserves the tallest state so the frame never resizes mid-loop.
   Trimmed with the stage and rows below — this frame sets the hero's height. */
/* --t must match the value on .shotwrap, which the caption lines under the
   frame run on. Declared literally rather than inherited: the 16 rules below
   use var(--t) with no fallback, so this partial has to stand on its own if
   it is ever rendered outside that wrapper.
   (Self-referencing it as var(--t, 16s) would be a cycle, not a fallback —
   the property would go invalid and every duration below with it.) */
.demo { --t: 16s; min-height: 208px; }

.demo__stage { position: relative; height: 68px; margin-bottom: var(--sp-2); }

/* ---- stage 1: the picker the cursor operates ---- */
.demo__pick {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  border-radius: var(--r-md); border: 2px dashed var(--brand-200);
  background: linear-gradient(165deg, var(--brand-50), #fff 72%);
  animation: demoPick var(--t) ease-in-out infinite;
}
.demo__picktext { font-size: 12px; color: var(--ink-500); }
.demo__browse {
  position: relative; overflow: hidden;
  padding: 6px 16px; border-radius: var(--r-pill);
  background: var(--brand-500); color: #fff;
  font-size: 12.5px; font-weight: 700;
  box-shadow: 0 4px 12px rgba(39, 93, 245, .34);
  animation: demoPress var(--t) ease-in-out infinite;
}
/* Ripple from the click, so the press has a consequence. */
.demo__ripple {
  position: absolute; left: 50%; top: 50%; width: 10px; height: 10px;
  margin: -5px 0 0 -5px; border-radius: 50%; background: rgba(255, 255, 255, .6);
  opacity: 0; animation: demoRipple var(--t) ease-out infinite;
}

/* ---- the cursor ---- */
.demo__cursor {
  position: absolute; left: 0; top: 0; width: 22px; height: 22px;
  filter: drop-shadow(0 2px 4px rgba(8, 14, 30, .45));
  animation: demoCursor var(--t) cubic-bezier(.4, .1, .3, 1) infinite;
}
.demo__cursor svg { width: 100%; height: 100%; display: block; }

/* ---- stage 2: the file, uploading then read ---- */
.demo__file {
  position: absolute; inset: 0; overflow: hidden;
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 12px 14px; border-radius: var(--r-md);
  background: var(--surface-sunk); border: 1px solid var(--line-strong);
  opacity: 0; animation: demoFile var(--t) ease-in-out infinite;
}
.demo__fileicon {
  flex: none; width: 34px; height: 34px; border-radius: 7px;
  display: grid; place-items: center;
  background: var(--bad-50); color: var(--bad-500);
  font-size: 9.5px; font-weight: 800; letter-spacing: .3px;
}
.demo__filemeta { display: grid; gap: 6px; min-width: 0; flex: 1 1 auto; }
.demo__filename {
  font-size: 12.5px; font-weight: 700; color: var(--ink-900);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.demo__bar { height: 5px; border-radius: 3px; background: var(--line); overflow: hidden; }
.demo__barfill {
  display: block; height: 100%; width: 0; border-radius: 3px;
  background: linear-gradient(90deg, var(--brand-400), var(--violet-500));
  animation: demoBar var(--t) ease-in-out infinite;
}
/* The read: a light bar crossing the card twice. */
.demo__beam {
  position: absolute; left: 0; right: 0; height: 20px; top: -24px;
  background: linear-gradient(180deg, transparent, rgba(39, 93, 245, .30), transparent);
  box-shadow: 0 0 16px 4px rgba(39, 93, 245, .30);
  animation: demoBeam var(--t) linear infinite;
}

/* ---- status line: four states, one slot ---- */
.demo__status {
  display: flex; align-items: center; gap: 8px;
  margin: 0; height: 20px; font-size: 12.5px; font-weight: 600; opacity: 0;
}
.demo__status + .demo__status { margin-top: -20px; }
.demo__status--up   { color: var(--ink-600);    animation: demoUp   var(--t) ease-in-out infinite; }
.demo__status--read { color: var(--brand-600);  animation: demoRead var(--t) ease-in-out infinite; }
.demo__status--make { color: var(--violet-600); animation: demoMake var(--t) ease-in-out infinite; }
.demo__status--done { color: var(--ok-600);     animation: demoDone var(--t) ease-in-out infinite; }
.demo__spin {
  width: 13px; height: 13px; flex: none; border-radius: 50%;
  border: 2px solid var(--brand-200); border-top-color: var(--brand-500);
  animation: demoSpin .8s linear infinite;
}
.demo__ok {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  display: grid; place-items: center; font-size: 9px; font-weight: 800;
  background: var(--ok-500); color: #fff;
}

/* ---- the filled fields ---- */
.demo__fields { margin-top: var(--sp-2); display: grid; gap: 5px; }
.demo__row {
  display: grid; grid-template-columns: 78px minmax(0, 1fr) 18px;
  align-items: center; gap: var(--sp-2);
  padding: 6px 10px; border-radius: var(--r-sm);
  background: var(--brand-50); opacity: 0;
}
.demo__label { font-size: 11px; color: var(--ink-500); }
.demo__value {
  font-size: 12.5px; font-weight: 700; color: var(--ink-900);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.demo__tick { font-size: 11px; font-weight: 800; color: var(--ok-500); text-align: right; }
.demo__row--1 { animation: demoRow1 var(--t) ease-in-out infinite; }
.demo__row--2 { animation: demoRow2 var(--t) ease-in-out infinite; }
.demo__row--3 { animation: demoRow3 var(--t) ease-in-out infinite; }
.demo__row--4 { animation: demoRow4 var(--t) ease-in-out infinite; }

/* ---- the timeline ---- */
@keyframes demoCursor {
  0%        { transform: translate(210px, 60px); opacity: 0; }
  4%        { transform: translate(196px, 52px); opacity: 1; }
  9%, 13%   { transform: translate(150px, 38px); opacity: 1; }
  16%       { transform: translate(160px, 46px); opacity: 0; }
  100%      { opacity: 0; }
}
@keyframes demoPress {
  0%, 8%    { transform: none; }
  10%       { transform: scale(.94); }
  12%, 100% { transform: none; }
}
@keyframes demoRipple {
  0%, 9%    { opacity: 0; transform: scale(1); }
  10%       { opacity: .8; transform: scale(1); }
  15%, 100% { opacity: 0; transform: scale(9); }
}
@keyframes demoPick {
  0%, 12%   { opacity: 1; }
  16%, 100% { opacity: 0; }
}
@keyframes demoFile {
  0%, 12%   { opacity: 0; transform: translateY(-10px) scale(.98); }
  17%, 88%  { opacity: 1; transform: none; }
  94%, 100% { opacity: 0; }
}
@keyframes demoBar {
  0%, 17%   { width: 0; opacity: 1; }
  28%       { width: 100%; opacity: 1; }
  33%, 100% { width: 100%; opacity: 0; }
}
@keyframes demoBeam {
  0%, 29%   { opacity: 0; top: -24px; }
  30%       { opacity: 1; top: -24px; }
  38%       { opacity: 1; top: 58px; }
  38.5%     { opacity: 1; top: -24px; }
  47%       { opacity: 1; top: 58px; }
  48%, 100% { opacity: 0; top: -24px; }
}
@keyframes demoUp   { 0%, 17% { opacity: 0; } 19%, 27% { opacity: 1; } 29%, 100% { opacity: 0; } }
@keyframes demoRead { 0%, 29% { opacity: 0; } 31%, 46% { opacity: 1; } 48%, 100% { opacity: 0; } }
@keyframes demoMake { 0%, 48% { opacity: 0; } 50%, 72% { opacity: 1; } 74%, 100% { opacity: 0; } }
@keyframes demoDone { 0%, 74% { opacity: 0; } 77%, 90% { opacity: 1; } 94%, 100% { opacity: 0; } }

@keyframes demoRow1 { 0%, 52% { opacity: 0; transform: translateY(8px); } 56%, 88% { opacity: 1; transform: none; } 94%, 100% { opacity: 0; } }
@keyframes demoRow2 { 0%, 58% { opacity: 0; transform: translateY(8px); } 62%, 88% { opacity: 1; transform: none; } 94%, 100% { opacity: 0; } }
@keyframes demoRow3 { 0%, 64% { opacity: 0; transform: translateY(8px); } 68%, 88% { opacity: 1; transform: none; } 94%, 100% { opacity: 0; } }
@keyframes demoRow4 { 0%, 70% { opacity: 0; transform: translateY(8px); } 74%, 88% { opacity: 1; transform: none; } 94%, 100% { opacity: 0; } }
@keyframes demoSpin { to { transform: rotate(360deg); } }

/* Reduced motion: show the end state - the filled profile is the point. */
@media (prefers-reduced-motion: reduce) {
  .demo__file, .demo__row, .demo__status--done { animation: none; opacity: 1; transform: none; }
  .demo__pick, .demo__cursor, .demo__beam, .demo__bar,
  .demo__status--up, .demo__status--read, .demo__status--make, .demo__spin { display: none; }
}

/* caption under the hero demo frame */
/* ---------- caption strip on the demo frame --------------------------
   The line sits ON the mock rather than under it: a strip across the bottom
   of the frame, the way a product's own UI would label what it is doing.

   Grid-stacked so all three lines share one cell — the strip keeps a fixed
   height as the sentence changes, instead of the frame growing and shrinking
   every few seconds next to an already-moving demo.
   -------------------------------------------------------------------- */
.shotline {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  margin: 0;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 16px 20px;
  /* The frame's own surface, not a dark bar. A black strip laid across a
     white product shot reads as a letterbox stuck on the picture — this way
     the frame stays one continuous surface and the line belongs to it. */
  background: var(--surface);
  border-top: 1px solid var(--line);
  font-size: clamp(15px, 1.45vw, 21px); font-weight: 800;
  letter-spacing: -.5px; line-height: 1.25; color: var(--ink-900);
  text-align: center;
}
/* Same blue→violet→pink sweep the "read in seconds" headline uses further
   down this page, so the two AI phrases read as one voice. Mint is reserved
   for the dark panels — it is nowhere near readable on white. */
.shotline em {
  font-style: normal;
  background: linear-gradient(92deg, var(--brand-600), var(--violet-500) 62%, var(--pink-500));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.shotline__spark { flex: none; display: block; width: 17px; height: 17px; color: var(--brand-500); }
.shotline__spark svg { width: 17px; height: 17px; display: block; }
/* Loops, so its phase lives in the keyframes rather than in a delay. */
.shotline__spark { animation: shotSpark 4.2s ease-in-out infinite; }
@keyframes shotSpark {
  0%, 100% { opacity: 1;   transform: scale(1); }
  40%      { opacity: .45; transform: scale(.82); }
}
@media (prefers-reduced-motion: reduce) {
  .shotline__spark { animation: none !important; opacity: 1; transform: none; }
}

/* =====================================================================
   Capability band — the three claims in big type.
   ===================================================================== */
.capband { padding: var(--sp-8) 0; background: var(--surface-sunk); border-top: 1px solid var(--line); }
.capband__eyebrow {
  margin: 0 0 6px; text-align: center;
  font-size: 11.5px; font-weight: 700; letter-spacing: .7px;
  text-transform: uppercase; color: var(--ink-500);
}
.capband__title {
  margin: 0 0 var(--sp-6); text-align: center;
  font-size: clamp(26px, 3.4vw, 38px); font-weight: 800;
  letter-spacing: -.9px; color: var(--ink-900);
}
.capband__title em {
  font-style: normal;
  background: linear-gradient(92deg, var(--brand-600), var(--violet-500) 60%, var(--pink-500));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.capband__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); }

.cap {
  --ct: var(--brand-500);
  --cw: var(--brand-50);
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  padding: var(--sp-5); border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.cap:hover { transform: translateY(-3px); border-color: var(--ct); box-shadow: var(--shadow-lg); }
/* A wash of the card's own hue in the corner, so the three read as a set of
   related capabilities rather than three identical white boxes. */
.cap::before {
  content: ""; position: absolute; top: -60px; right: -60px;
  width: 150px; height: 150px; border-radius: 50%;
  background: var(--cw);
}
.cap--brand  { --ct: var(--brand-500);  --cw: var(--brand-50); }
.cap--violet { --ct: var(--violet-500); --cw: var(--violet-50); }
.cap--teal   { --ct: var(--teal-500);   --cw: var(--teal-50); }

.cap__icon {
  position: relative; width: 44px; height: 44px; border-radius: 12px;
  display: grid; place-items: center; font-size: 20px;
  background: var(--cw); color: var(--ct); margin-bottom: var(--sp-4);
}
.cap__head {
  position: relative; margin: 0 0 8px;
  font-size: 19px; font-weight: 700; letter-spacing: -.3px; color: var(--ink-900);
}
.cap__body { position: relative; margin: 0 0 var(--sp-4); font-size: 13.5px; color: var(--ink-600); line-height: 1.6; }
.cap__cta {
  position: relative; margin-top: auto;
  font-size: 13px; font-weight: 700; color: var(--ct);
}
.cap__cta:hover { text-decoration: none; }
.cap__cta:hover span { display: inline-block; transform: translateX(3px); transition: transform .15s ease; }

@media (max-width: 940px) { .capband__grid { grid-template-columns: 1fr; } }

/* =====================================================================
   AI band — the differentiator, stated once and prominently.
   ===================================================================== */
.aiband {
  position: relative; overflow: hidden; isolation: isolate;
  padding: var(--sp-7) 0;
  background: linear-gradient(160deg, #f4f7ff 0%, #f7f4ff 52%, #f3fbfa 100%);
  border-bottom: 1px solid var(--line);
}
.aiband__glow {
  position: absolute; border-radius: 50%; filter: blur(80px); z-index: -1; opacity: .5;
}
.aiband__glow--a { width: 380px; height: 380px; top: -180px; left: -80px;  background: rgba(39, 93, 245, .26); }
.aiband__glow--b { width: 340px; height: 340px; bottom: -200px; right: -60px; background: rgba(137, 81, 255, .22); }
.aiband__inner { position: relative; }

.aiband__head { text-align: center; max-width: 44em; margin: 0 auto var(--sp-6); }
.aiband__tag {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 13px 5px 10px; margin-bottom: var(--sp-3);
  border-radius: var(--r-pill); background: #fff;
  border: 1px solid var(--brand-100);
  font-size: 11.5px; font-weight: 800; letter-spacing: .5px;
  text-transform: uppercase; color: var(--brand-600);
  box-shadow: var(--shadow-sm);
}
.aiband__tagdot {
  width: 7px; height: 7px; border-radius: 50%;
  background: linear-gradient(135deg, var(--brand-500), var(--violet-500));
  box-shadow: 0 0 0 0 rgba(39, 93, 245, .55);
  animation: apPulse 2.6s ease-out infinite;
}
.aiband__title {
  margin: 0 0 8px; font-size: clamp(25px, 3.3vw, 37px); font-weight: 800;
  letter-spacing: -.9px; color: var(--ink-900);
}
.aiband__title em {
  font-style: normal;
  background: linear-gradient(92deg, var(--brand-600), var(--violet-500) 62%, var(--pink-500));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.aiband__sub { margin: 0; font-size: 15px; color: var(--ink-600); }

/* Three steps, joined by a rule so they read as a sequence. */
.aisteps {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4);
  position: relative;
}
.aistep {
  position: relative; display: flex; gap: var(--sp-3);
  padding: var(--sp-4); border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .82); border: 1px solid var(--line);
  backdrop-filter: blur(4px);
}
/* The connector is drawn between cards, not through them. */
.aistep:not(:last-child)::after {
  content: ""; position: absolute; top: 50%; right: calc(var(--sp-4) * -1);
  width: var(--sp-4); height: 2px; background: var(--brand-200);
}
.aistep__num {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center; font-size: 13px; font-weight: 800; color: #fff;
  background: linear-gradient(135deg, var(--brand-500), var(--violet-500));
}
.aistep__body { display: grid; gap: 3px; }
.aistep__head { font-size: 15px; font-weight: 700; color: var(--ink-900); }
.aistep__text { font-size: 13px; color: var(--ink-600); line-height: 1.55; }

.aiband__cta {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  margin-top: var(--sp-6);
}
.aiband__note { font-size: 12.5px; color: var(--ink-500); }

@media (max-width: 940px) {
  .aisteps { grid-template-columns: 1fr; }
  .aistep:not(:last-child)::after { display: none; }
}
@media (prefers-reduced-motion: reduce) { .aiband__tagdot { animation: none; } }

/* =====================================================================
   ResumeRead upload screen — coloured header, brighter dropzone.
   ===================================================================== */
.qphero {
  position: relative; overflow: hidden; isolation: isolate;
  padding: var(--sp-7) 0 var(--sp-6); text-align: center;
  background: linear-gradient(150deg, #eef3ff 0%, #f6f0ff 48%, #eafaf7 100%);
  border-bottom: 1px solid var(--line);
}
.qphero__glow { position: absolute; border-radius: 50%; filter: blur(72px); z-index: -1; opacity: .55; }
.qphero__glow--a { width: 320px; height: 320px; top: -150px; left: -60px;   background: rgba(39, 93, 245, .30); }
.qphero__glow--b { width: 300px; height: 300px; bottom: -170px; right: -50px; background: rgba(137, 81, 255, .26); }
.qphero__inner { position: relative; }

.qphero__tag {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 13px 5px 10px; margin-bottom: var(--sp-3);
  border-radius: var(--r-pill); background: #fff; border: 1px solid var(--brand-100);
  font-size: 11.5px; font-weight: 800; letter-spacing: .5px;
  text-transform: uppercase; color: var(--brand-600); box-shadow: var(--shadow-sm);
}
.qphero__tagdot {
  width: 7px; height: 7px; border-radius: 50%;
  background: linear-gradient(135deg, var(--brand-500), var(--violet-500));
  animation: apPulse 2.6s ease-out infinite;
}
.qphero__title {
  margin: 0 0 8px; font-size: clamp(26px, 3.6vw, 38px);
  font-weight: 800; letter-spacing: -.9px; color: var(--ink-900); line-height: 1.15;
}
.qphero__title em {
  font-style: normal;
  background: linear-gradient(92deg, var(--brand-600), var(--violet-500) 62%, var(--pink-500));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.qphero__sub { margin: 0 auto; max-width: 40em; font-size: 15px; color: var(--ink-600); }

/* Step rail: shows how short the process is before it starts. */
.qpsteps {
  list-style: none; display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--sp-2); margin: var(--sp-5) 0 0; padding: 0;
}
.qpstep {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 14px 6px 8px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .8); border: 1px solid var(--line);
  font-size: 12.5px; font-weight: 600; color: var(--ink-500);
}
.qpstep span {
  width: 20px; height: 20px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-size: 11px; font-weight: 800;
  background: var(--surface-sunk); color: var(--ink-500);
}
.qpstep.is-now { color: var(--brand-700); border-color: var(--brand-200); background: #fff; }
.qpstep.is-now span {
  color: #fff; background: linear-gradient(135deg, var(--brand-500), var(--violet-500));
}

/* Dropzone: colour it, so the one thing to do on the page looks like it. */
.qpform .dropzone {
  background: linear-gradient(165deg, var(--brand-50), #fff 72%);
  border: 2px dashed var(--brand-200);
}
.qpform .dropzone:hover,
.qpform .dropzone.is-over { border-color: var(--brand-500); background: linear-gradient(165deg, var(--brand-100), #fff 72%); }
.qpform .dropzone__art {
  width: 52px; height: 52px; margin: 0 auto 10px; border-radius: 50%;
  display: grid; place-items: center; font-size: 22px; color: #fff;
  background: linear-gradient(135deg, var(--brand-500), var(--violet-500));
  box-shadow: 0 8px 20px rgba(39, 93, 245, .34);
}

@media (prefers-reduced-motion: reduce) { .qphero__tagdot { animation: none; } }
