/* ==========================================================================
   Seyco Group — Recruiting Platform Design System
   One shared visual language across the whole product: the public site, the
   admin panel and the Candidate Database tool (templates/archive_database.html)
   all use these tokens, so a change here lands everywhere at once.

   The look: warm coral-red brand colour on a slow-drifting gradient field,
   frosted-glass surfaces, fully rounded pill controls, and light motion
   throughout so the product feels alive rather than static.
   ========================================================================== */

:root{
  --accent-1: #E0221F;      /* primary brand red                       */
  --accent-1-dark: #B31A17; /* pressed / hover-deep                    */
  --accent-1-light: #FF3B30;/* highlight / gradient partner            */
  --accent-2: #1C1F26;      /* ink navy - secondary / text accents     */
  --accent-3: #E0221F;      /* danger reuses brand red                 */
  --accent-4: #30D158;      /* success green                           */
  --accent-warn: #FF9F0A;   /* amber                                   */

  --radius-lg: 22px;
  --radius-md: 16px;
  --radius-sm: 12px;
  --radius-pill: 100px;     /* buttons, chips, selects, badges         */

  /* Golos Text carries the whole product. Its Cyrillic is drawn as the primary
     alphabet rather than fitted around a Latin design, and Cyrillic is what
     nearly every screen here is read in. One variable family spans 400-900, so
     a heading and a body line differ by weight and tracking rather than by
     typeface; the system stack behind it is what shows while the web font is
     still arriving, or on a machine that never reaches Google Fonts. */
  --font-display: 'Golos Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-body: 'Golos Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  /* Small uppercase labels, badges, table headers, timestamps. These were set
     in a monospace face, which read as a terminal stamp dropped onto an HR
     tool rather than as part of the page. They now use the same family with
     wider tracking to stay distinct, plus tabular figures wherever a column of
     numbers has to line up — which is the one thing the fixed-width face was
     genuinely doing for them. */
  --font-label: var(--font-body);
  /* Code samples and raw dumps only. Nothing in the chrome is monospaced, so
     this no longer needs a downloaded face. */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, 'Consolas', monospace;

  --shadow-soft: 0 1px 2px rgba(30,30,45,.04), 0 8px 24px -12px rgba(30,30,45,.10);
  --shadow-lift: 0 4px 10px rgba(30,30,45,.05), 0 20px 44px -16px rgba(30,30,45,.16);
  --shadow-red: 0 10px 26px rgba(224,34,31,.30);
  --transition: 200ms cubic-bezier(.4,0,.2,1);
  --transition-slow: 420ms cubic-bezier(.16,1,.3,1);
  --spring: 180ms cubic-bezier(.34,1.56,.64,1);
}

/* ---------- Light theme ---------- */
/* `color-scheme` has to say which theme is on, because the glass surfaces are
   translucent — `--input-bg` is 38% white, and what shows through it is the
   background the browser paints for a native control. iPadOS/iOS Safari picks
   that from the *system* setting unless the page declares otherwise, so with
   the tablet in dark mode a light page came out with charcoal input pills and
   labels that faded into them. Declared here, it follows `data-theme`. */
:root, [data-theme="light"]{
  color-scheme: light;
  --bg-a: #EEF2FB;
  --bg-b: #F7EEF5;
  --bg-c: #EEFAF6;
  --bg: var(--bg-b);
  --bg-elevated: #FFFFFF;
  --surface: rgba(255,255,255,.26);        /* frosted glass            */
  --surface-strong: rgba(255,255,255,.38); /* pills, inputs            */
  --surface-solid: #FFFFFF;                /* menus, popovers, tables  */
  --border: rgba(255,255,255,.35);
  --border-strong: rgba(255,255,255,.45);
  --line: rgba(60,60,67,.13);              /* hairlines on solid areas */
  --text: #1C1C1E;
  --text-muted: #6E6E73;
  --text-faint: #9A9AA0;
  --input-bg: rgba(255,255,255,.38);
  --chart-bar-a: #2E333C;   /* graphite, dark end   */
  --chart-bar-b: #79808C;   /* graphite, light end  */
  --chart-track: rgba(60,60,67,.10);
  /* Четыре пятна света на фоне страницы. Держатся здесь, а не в body, потому
     что тема — это прежде всего воздух вокруг плашек, а не сами плашки. */
  --glow-1: rgba(224,34,31,.13);
  --glow-2: rgba(255,122,61,.09);
  --glow-3: rgba(255,159,10,.07);
  --glow-4: rgba(255,55,95,.06);
}

/* ---------- Dark theme ---------- */
[data-theme="dark"]{
  color-scheme: dark;
  --bg-a: #121016;
  --bg-b: #181219;
  --bg-c: #0F1614;
  --bg: var(--bg-b);
  --bg-elevated: #1C1A1F;
  --surface: rgba(28,28,32,.30);
  --surface-strong: rgba(30,30,35,.44);
  --surface-solid: #1C1A1F;
  --border: rgba(255,255,255,.07);
  --border-strong: rgba(255,255,255,.11);
  --line: rgba(255,255,255,.11);
  --text: #F1F1F3;
  --text-muted: #A7A7AD;
  --text-faint: #75757B;
  --input-bg: rgba(30,30,35,.44);
  --accent-1: #FF3B30;
  --accent-1-light: #FF5B63;
  --shadow-soft: 0 1px 2px rgba(0,0,0,.20), 0 8px 24px -12px rgba(0,0,0,.5);
  --shadow-lift: 0 4px 10px rgba(0,0,0,.25), 0 20px 44px -16px rgba(0,0,0,.6);
  --chart-bar-a: #D6D9DE;   /* inverted for dark UI */
  --chart-bar-b: #6E747E;
  --chart-track: rgba(255,255,255,.08);
  --glow-1: rgba(224,34,31,.17);
  --glow-2: rgba(255,122,61,.10);
  --glow-3: rgba(255,159,10,.07);
  --glow-4: rgba(255,55,95,.07);
}

/* ---------- Ocean: светлая, холодная ----------
   Вторая светлая тема существует не ради другого оттенка серого: фирменный
   красный на ней уступает место бирюзе, и страница, на которой весь день
   сводят таблицы, перестаёт быть тревожной. Опасное действие остаётся
   красным — --accent-3 не трогаем. */
[data-theme="ocean"]{
  color-scheme: light;
  --bg-a: #E9F2FA;
  --bg-b: #EDF6F6;
  --bg-c: #E6F5EF;
  --bg: var(--bg-b);
  --bg-elevated: #FFFFFF;
  --surface: rgba(255,255,255,.30);
  --surface-strong: rgba(255,255,255,.44);
  --surface-solid: #FFFFFF;
  --border: rgba(255,255,255,.42);
  --border-strong: rgba(255,255,255,.55);
  --line: rgba(20,60,70,.13);
  --text: #10242B;
  --text-muted: #5C7078;
  --text-faint: #91A3AA;
  --input-bg: rgba(255,255,255,.44);
  --accent-1: #0E7C86;
  --accent-1-dark: #0A5C64;
  --accent-1-light: #17A5B2;
  --accent-2: #12303A;
  --shadow-red: 0 10px 26px rgba(14,124,134,.26);
  --chart-bar-a: #14535C;
  --chart-bar-b: #6FA0A8;
  --chart-track: rgba(20,60,70,.10);
  --glow-1: rgba(10,132,255,.13);
  --glow-2: rgba(14,165,164,.11);
  --glow-3: rgba(48,209,88,.06);
  --glow-4: rgba(94,92,230,.06);
}

/* ---------- Midnight: тёмная, индиговая ----------
   Тёмная тема здесь одна и «красная»: на ней акцент горит так же, как на
   светлой. Эта — холодная и тише: тот же контраст текста, но индиго вместо
   алого, для тех, кто сидит в панели вечерами. */
[data-theme="midnight"]{
  color-scheme: dark;
  --bg-a: #0D1019;
  --bg-b: #11141F;
  --bg-c: #0B111B;
  --bg: var(--bg-b);
  --bg-elevated: #171B29;
  --surface: rgba(26,30,46,.34);
  --surface-strong: rgba(28,33,50,.48);
  --surface-solid: #171B29;
  --border: rgba(255,255,255,.08);
  --border-strong: rgba(255,255,255,.13);
  --line: rgba(255,255,255,.11);
  --text: #EDEFF6;
  --text-muted: #A2A8BE;
  --text-faint: #717890;
  --input-bg: rgba(28,33,50,.48);
  --accent-1: #4C5BD4;
  --accent-1-dark: #3A48B4;
  --accent-1-light: #8A97FF;
  --accent-2: #C7CCE4;
  --shadow-soft: 0 1px 2px rgba(0,0,0,.20), 0 8px 24px -12px rgba(0,0,0,.5);
  --shadow-lift: 0 4px 10px rgba(0,0,0,.25), 0 20px 44px -16px rgba(0,0,0,.6);
  --shadow-red: 0 10px 26px rgba(76,91,212,.34);
  --chart-bar-a: #C9CEE4;
  --chart-bar-b: #6A7290;
  --chart-track: rgba(255,255,255,.08);
  --glow-1: rgba(124,140,255,.16);
  --glow-2: rgba(90,200,250,.10);
  --glow-3: rgba(191,90,242,.09);
  --glow-4: rgba(48,209,88,.05);
}

*{ box-sizing: border-box; }
html{ scroll-behavior: smooth; }

body{
  margin:0;
  font-family: var(--font-body);
  color: var(--text);
  background:
    radial-gradient(1100px 620px at 8% -10%, var(--glow-1), transparent 60%),
    radial-gradient(950px 560px at 100% 0%, var(--glow-2), transparent 55%),
    radial-gradient(1000px 700px at 50% 110%, var(--glow-3), transparent 55%),
    radial-gradient(800px 500px at 85% 85%, var(--glow-4), transparent 55%),
    linear-gradient(160deg, var(--bg-a), var(--bg-b) 55%, var(--bg-c));
  background-size: 160% 160%, 160% 160%, 160% 160%, 160% 160%, 140% 140%;
  background-attachment: fixed;
  animation: bodyfade .5s ease, appBgDrift 42s ease-in-out infinite alternate;
  transition: background-color var(--transition), color var(--transition);
  min-height: 100vh;
  position: relative;
  font-size: 15px;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
@keyframes bodyfade{ from{ opacity:0; } to{ opacity:1; } }
@keyframes appBgDrift{
  0%{   background-position: 0% 0%, 100% 0%, 50% 100%, 100% 100%, 50% 50%; }
  50%{  background-position: 20% 15%, 75% 25%, 35% 75%, 70% 65%, 55% 45%; }
  100%{ background-position: 5% 30%, 90% 5%, 60% 90%, 55% 80%, 50% 55%; }
}

::selection{ background: rgba(224,34,31,.22); }

a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, .btn:focus-visible, [tabindex]:focus-visible{
  outline: 2px solid var(--accent-1);
  outline-offset: 2px;
}

/* Floating blurred aurora blobs behind everything (same three as the tool) */
.aurora-bg{ position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events:none; }
.aurora-bg span{
  position:absolute; border-radius:50%; filter: blur(90px);
}
.aurora-bg span:nth-child(1){
  width:560px; height:560px; top:-180px; left:-140px;
  background: rgba(224,34,31,.20); animation: aurora1 24s ease-in-out infinite;
}
.aurora-bg span:nth-child(2){
  width:520px; height:520px; bottom:-200px; right:-140px;
  background: rgba(255,122,61,.16); animation: aurora2 28s ease-in-out infinite;
}
.aurora-bg span:nth-child(3){
  width:420px; height:420px; top:40%; left:50%;
  background: rgba(255,159,10,.14); animation: aurora3 32s ease-in-out infinite;
}
@keyframes aurora1{ 0%,100%{ transform: translate(0,0) scale(1);} 50%{ transform: translate(80px,60px) scale(1.2);} }
@keyframes aurora2{ 0%,100%{ transform: translate(0,0) scale(1);} 50%{ transform: translate(-70px,-50px) scale(1.15);} }
@keyframes aurora3{ 0%,100%{ transform: translate(-50%,0) scale(1);} 50%{ transform: translate(-50%,-60px) scale(1.25);} }
@media (max-width: 700px){ .aurora-bg span{ display:none; } }

h1,h2,h3,h4,h5,h6{ font-family: var(--font-display); font-weight:700; letter-spacing: -0.01em; margin: 0 0 .4em; }
a{ color: inherit; text-decoration:none; }
p{ color: var(--text-muted); line-height:1.65; }
code{ font-family: var(--font-mono); background: var(--input-bg); padding:2px 6px; border-radius:4px; border:1px solid var(--border); }

.container-narrow{ max-width: 1180px; margin: 0 auto; padding: 0 24px; }

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font-family: var(--font-body); font-weight: 700; font-size: 14px;
  padding: 12px 22px; border-radius: var(--radius-pill); border: 1px solid transparent;
  cursor: pointer; transition: transform var(--spring), box-shadow var(--transition), opacity var(--transition), background var(--transition), border-color var(--transition), filter var(--transition);
  white-space: nowrap; position: relative; overflow: hidden; -webkit-tap-highlight-color: transparent;
  /* Never let a flex parent shrink a button — `overflow:hidden` (needed for the
     ripple) would clip the label instead of wrapping, which bites on long
     Kazakh/Turkish strings. */
  flex: none;
}
.btn::after{
  content:''; position:absolute; inset:0; border-radius:inherit;
  background: radial-gradient(circle, rgba(255,255,255,.55) 0%, transparent 60%);
  opacity:0; transform: scale(0); transition: transform .5s ease, opacity .5s ease;
  pointer-events:none;
}
/* Light sweep that runs across the button on hover */
.btn::before{
  content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,.4), transparent);
  transform: translateX(-120%); transition: transform .5s ease;
}
.btn:hover::before{ transform: translateX(120%); }
.btn:active::after{ opacity:.7; transform: scale(2.4); transition: 0s; }
.btn:active{ transform: scale(.95); }

.btn-primary{
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1));
  color: #fff;
  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset, var(--shadow-red);
  border-color: rgba(0,0,0,.06);
}
.btn-primary:hover{ filter: brightness(1.06); box-shadow: 0 1px 0 rgba(255,255,255,.25) inset, 0 16px 32px rgba(224,34,31,.38); transform: translateY(-2px) scale(1.03); }

.btn-ghost{
  background: var(--surface-strong); color: var(--text); border-color: var(--border-strong);
  backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%);
  box-shadow: var(--shadow-soft);
}
.btn-ghost:hover{ border-color: var(--accent-1); color: var(--accent-1); transform: translateY(-2px) scale(1.03); box-shadow: var(--shadow-lift); }

/* Copy-to-clipboard button: icon + label. On a successful copy main.js adds
   .is-copied, which swaps the sheets icon for a tick and turns the button
   green for a moment — the confirmation lands on the button that was pressed,
   so nothing has to move or pop up elsewhere on the page. */
.btn-copy{ display:inline-flex; align-items:center; gap:7px; }
.btn-copy .btn-copy-label{ white-space:nowrap; }
.btn-copy .btn-copy-ok{ display:none; }
.btn-copy.is-copied .btn-copy-ico{ display:none; }
.btn-copy.is-copied .btn-copy-ok{ display:inline; }
.btn-copy.is-copied,
.btn-copy.is-copied:hover{ color: var(--accent-4); border-color: var(--accent-4); }
.btn-copy.is-copy-failed,
.btn-copy.is-copy-failed:hover{ color: var(--accent-3); border-color: var(--accent-3); }

/* Apply-on-WhatsApp button (landing hero) — WhatsApp green, so it reads as
   "message us" next to the red brand buttons rather than competing with them. */
.btn-whatsapp{
  background: linear-gradient(135deg, #34d36a, #1faa53);
  color:#fff; border-color: rgba(0,0,0,.06);
  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset, 0 10px 24px rgba(31,170,83,.32);
}
.btn-whatsapp:hover{
  filter: brightness(1.06); transform: translateY(-2px) scale(1.03);
  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset, 0 16px 32px rgba(31,170,83,.4);
}
.btn-whatsapp svg{ width:18px; height:18px; flex:none; }

.btn-sm{ padding: 8px 15px; font-size: 12.5px; }
/* Safety net: a button stretched to fill its container wraps its label instead
   of having it clipped by `overflow:hidden`. Long labels in kk/tr/ru hit this. */
.btn[style*="width:100%"], .btn[style*="width: 100%"]{
  white-space: normal; line-height: 1.35; text-align: center;
}
.btn-danger{ background: transparent; color:var(--accent-3); border-color: var(--accent-3); }
.btn-danger:hover{ background: var(--accent-3); color:#fff; }

.btn-submit{
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1-dark));
  color:#fff;
  box-shadow: 0 1px 0 rgba(255,255,255,.2) inset, var(--shadow-red);
  border-color: rgba(0,0,0,.08);
  animation: pulseglow 2.2s ease-in-out infinite;
}
.btn-submit:hover{ filter: brightness(1.08); box-shadow: 0 1px 0 rgba(255,255,255,.2) inset, 0 16px 34px rgba(224,34,31,.45); transform: translateY(-2px) scale(1.03); animation: none; }
@keyframes pulseglow{
  0%, 100%{ box-shadow: 0 1px 0 rgba(255,255,255,.2) inset, 0 6px 16px rgba(224,34,31,.28); }
  50%{ box-shadow: 0 1px 0 rgba(255,255,255,.2) inset, 0 10px 26px rgba(224,34,31,.48); }
}
.btn-icon{ width:40px; height:40px; padding:0; border-radius: var(--radius-pill); }
.btn:disabled{ opacity:.5; cursor:not-allowed; animation:none; }

/* ---------- Cards ---------- */
.glass{
  background: var(--surface);
  backdrop-filter: blur(42px) saturate(200%);
  -webkit-backdrop-filter: blur(42px) saturate(200%);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  position: relative;
  transition: transform var(--transition-slow), box-shadow var(--transition-slow), border-color var(--transition);
}
.glass.card, .glass.stat-card, .glass.benefit-card, .glass.job-card, .glass.auth-card,
.glass.tab-panel, form.glass{
  padding: 26px;
}
.card{ padding: 26px; }

/* Every glass surface floats in on load, staggered by its position so a page
   assembles itself top-to-bottom instead of appearing all at once. */
.glass{ animation: cardin .5s cubic-bezier(.16,1,.3,1) both; }
.glass:nth-of-type(1){ animation-delay: .03s; }
.glass:nth-of-type(2){ animation-delay: .09s; }
.glass:nth-of-type(3){ animation-delay: .15s; }
.glass:nth-of-type(4){ animation-delay: .21s; }
.glass:nth-of-type(5){ animation-delay: .27s; }
.glass:nth-of-type(6){ animation-delay: .33s; }
.glass:nth-of-type(7){ animation-delay: .39s; }
.glass:nth-of-type(n+8){ animation-delay: .45s; }
@keyframes cardin{ from{ opacity:0; transform: translateY(16px) scale(.985);} to{ opacity:1; transform: translateY(0) scale(1);} }

/* Кроме тех стеклянных поверхностей, которые сами ездят.
   `cardin` объявлена с fill-mode: both, а заполненный кадр анимации
   перебивает обычный каскад — и делает это навсегда, а не только пока идёт
   анимация. Панель на телефоне уезжает за экран через transform, и этот
   заполненный `translateY(0) scale(1)` его стирал: панель стояла на месте
   при любом классе, а ✕ снимал `.open` и не двигал ничего. Всё, чей
   transform что-то значит, из float-in исключено. Шапка сайта тут не при
   делах: у неё своя анимация floatIn, объявленная ниже .glass. */
.sidebar.glass{ animation: none; }

.glass.card:hover, .glass.benefit-card:hover, .glass.job-card:hover, .glass.stat-card:hover{
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
  border-color: var(--border-strong);
}

/* Top accent bar instead of punch-hole motif */
.glass.card::before, .glass.benefit-card::before, .glass.job-card::before, .glass.auth-card::before, .glass.stat-card::before{
  content:''; position:absolute; top:0; left:18px; right:18px; height:3px; border-radius:0 0 4px 4px;
  background: linear-gradient(90deg, var(--accent-1), var(--accent-1-light));
  opacity:0; transform: scaleX(.4); transform-origin:left; transition: opacity var(--transition), transform var(--transition-slow);
}
.glass.card:hover::before, .glass.benefit-card:hover::before, .glass.job-card:hover::before{ opacity:1; transform: scaleX(1); }

/* ---------- Navbar (public) ---------- */
.navbar{
  position: sticky; top:16px; z-index: 50;
  display:flex; align-items:center; justify-content:space-between;
  padding: 15px 22px; margin: 16px auto 0; max-width: 1180px;
  border-radius: var(--radius-lg);
  backdrop-filter: blur(42px) saturate(200%);
  -webkit-backdrop-filter: blur(42px) saturate(200%);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-soft);
  animation: floatIn .5s cubic-bezier(.16,1,.3,1) both;
}
@keyframes floatIn{ from{ opacity:0; transform: translateY(-12px);} to{ opacity:1; transform: translateY(0);} }
.brand{ display:flex; align-items:center; gap:10px; font-family:var(--font-display); font-weight:800; font-size:18px; }
.brand-logo{ height:44px; width:auto; display:block; }
/* The logo is a link now, so it needs the affordance a link has and
   none of the underline an <a> brings with it. Nothing moves on hover:
   a brand mark that shifts under the pointer reads as broken. */
.brand-home{ display:block; line-height:0; text-decoration:none; }
.brand-home:hover{ opacity:.85; }

/* The file chooser is a <label> wrapping a hidden <input>, so it has to
   carry the button's own cursor — a control that looks like a button and
   does not answer the pointer reads as disabled. */
.photo-upload{ margin:0; }
.photo-upload label{ cursor:pointer; }
/* Sits under the list it adds to, with a rule between: the form is the
   end of the list, not another row in it. */
.doc-add{ display:flex; gap:10px; align-items:center; flex-wrap:wrap;
          margin-top:14px; padding-top:14px; border-top:1px solid var(--border); }
.doc-add input[type=file]{ flex:1; min-width:200px; font-size:13px; }
.brand-logo-dark{ display:none; }
[data-theme="dark"] .brand-logo-light{ display:none; }
[data-theme="dark"] .brand-logo-dark{ display:block; }

/* The full lockup carries its own wordmark, so no text sits beside it. It is a
   stacked mark — DEPARTMENT over HR over SEYCO GROUP — so its height buys far
   less presence than a horizontal one: two thirds of it is the "HR", and the
   two lettered lines are thin tracked capitals about 7% of the height each.

   It sat at 66px to keep those lines readable. That is no longer what it is
   being asked to do. On the login card the mark is an anchor above a title,
   not something anyone reads, and at 66px it filled a third of a 400px card
   while the card had one button in it. At 48px "HR" still carries the
   identification and the card reads as a form again. */
.brand-lockup{ gap:0; }
.brand-lockup .brand-logo{ height:48px; }
@media (max-width: 640px){ .brand-lockup .brand-logo{ height:42px; } }
/* В шапке лендинга — меньше. Там знак не главный герой, а подпись слева от
   меню: 66px давали полосу почти в сто пикселей, в которой логотип был вдвое
   крупнее всего остального и перетягивал на себя весь ряд. Теперь 42px —
   ровно та высота, на которой «HR» встаёт вровень с пунктами меню, а не над
   ними, и шапка садится с 96 до 62 пикселей.

   Плата за это известна и принята: «DEPARTMENT» и «SEYCO GROUP» набраны
   тонким разряженным шрифтом ростом в 7% высоты знака, то есть здесь около
   трёх пикселей — они читаются как фактура под монограммой, а не как слова.
   Узнаётся знак по «HR», и в шапке этого достаточно. На карточке входа
   лого по-прежнему в полный рост: там оно и есть содержимое, и обе строки
   там видно. */
.navbar{ padding:10px 22px; }
.navbar .brand-lockup .brand-logo{ height:42px; }
@media (max-width: 640px){ .navbar .brand-lockup .brand-logo{ height:36px; } }
.brand .logo-dot{
  width:28px; height:28px; border-radius: 8px;
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1-dark));
  box-shadow: 0 4px 10px rgba(224,34,31,.35);
  position: relative;
}
.brand .logo-dot::after{
  content:''; position:absolute; inset:6px; border-radius:3px; background: #fff; opacity:.9;
  clip-path: polygon(0 0, 100% 0, 100% 40%, 40% 40%, 40% 100%, 0 100%);
}
.nav-links{ display:flex; gap:26px; align-items:center; }
.nav-links a{ color: var(--text-muted); font-weight:600; font-size:14px; transition: color var(--transition); position:relative; }
.nav-links a::after{ content:''; position:absolute; left:0; right:0; bottom:-4px; height:2px; background:var(--accent-1); transform:scaleX(0); transition: transform var(--transition); transform-origin:left; }
.nav-links a:hover{ color: var(--accent-1); }
.nav-links a:hover::after{ transform:scaleX(1); }

.theme-toggle{
  width:38px; height:38px; border-radius: var(--radius-pill); display:flex; align-items:center; justify-content:center;
  background: var(--surface-strong); border:1px solid var(--border-strong); cursor:pointer;
  box-shadow: var(--shadow-soft); font-size:15px; flex:none;
  backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%);
  transition: transform .3s cubic-bezier(.34,1.56,.64,1), box-shadow var(--transition), border-color var(--transition);
}
.theme-toggle:hover{ border-color: var(--accent-1); transform: rotate(25deg) scale(1.12); box-shadow: var(--shadow-lift); }
.theme-toggle:active{ transform: rotate(25deg) scale(.9); }

/* ---------- Language switcher ---------- */
.lang-switch{ position:relative; }
.lang-switch-btn{
  display:flex; align-items:center; gap:6px; height:38px; padding:0 14px;
  border-radius: var(--radius-pill); background: var(--surface-strong); border:1px solid var(--border-strong);
  cursor:pointer; font-weight:700; font-size:12.5px; color: var(--text); box-shadow: var(--shadow-soft);
  backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%);
  transition: transform var(--spring), box-shadow var(--transition), border-color var(--transition);
}
.lang-switch-btn:hover{ border-color: var(--accent-1); transform: translateY(-2px) scale(1.03); box-shadow: var(--shadow-lift); }
.lang-switch-btn:active{ transform: scale(.96); }
.lang-caret{ font-size:10px; color: var(--text-faint); transition: transform var(--transition); }
.lang-switch.open .lang-caret{ transform: rotate(180deg); }
.lang-switch-menu{
  position:absolute; right:0; top:calc(100% + 8px); min-width:160px;
  background: var(--surface-solid); border:1px solid var(--line); border-radius: var(--radius-md);
  box-shadow: var(--shadow-lift); padding:6px; display:flex; flex-direction:column; gap:2px;
  opacity:0; visibility:hidden; transform: translateY(-8px) scale(.96); z-index:80;
  transition: opacity var(--transition), visibility var(--transition), transform var(--spring);
}
.lang-switch.open .lang-switch-menu{ opacity:1; visibility:visible; transform: translateY(0) scale(1); }
.lang-switch-menu a{
  padding:9px 11px; border-radius:7px; font-size:13.5px; font-weight:600; color:var(--text-muted); display:flex; align-items:center; gap:8px;
  transition: var(--transition);
}
.lang-switch-menu a:hover{ background: var(--input-bg); color: var(--text); }
.lang-switch-menu a.active{ color: var(--accent-1); background: rgba(224,34,31,.08); }

/* ---------- Hero ---------- */
/* No entrance animation on the wrapper itself: the scroll parallax in main.js
   writes an inline transform here, and a filled `animation` would outrank it
   forever and freeze the hero in place. The pieces inside animate instead. */
.hero{ padding: 92px 24px 60px; text-align:center; position:relative; }
.eyebrow{
  display:inline-flex; align-items:center; gap:8px; font-family: var(--font-display); font-size:12.5px; font-weight:800;
  text-transform:uppercase; letter-spacing:.12em;
  padding:8px 15px; border-radius:999px; background: rgba(224,34,31,.08); border:1px solid rgba(224,34,31,.22);
  color: var(--accent-1); margin-bottom:26px;
}
.eyebrow .dot{ width:7px; height:7px; border-radius:50%; background: var(--accent-1); animation: blink 1.6s ease-in-out infinite; }
@keyframes blink{ 0%,100%{ opacity:1; } 50%{ opacity:.3; } }
.hero h1{
  font-size: clamp(2.3rem, 4.8vw, 3.8rem); font-weight:800; max-width: 840px; margin: 0 auto .5em;
  color: var(--text); line-height:1.1;
}
.hero p.lead{ font-size:17.5px; max-width:600px; margin:0 auto 34px; }
.hero-actions{ display:flex; gap:12px; justify-content:center; flex-wrap:wrap; }

.section{ padding: 66px 24px; }
.section-title{ text-align:center; max-width:640px; margin:0 auto 46px; }
/* The kicker is a label, not a line of code: a monospace face here read as a
   terminal stamp pasted onto the page rather than as part of the heading
   under it. Same family as that heading, with the tracking a bit wider to
   hold the presence the fixed-width letters used to give it. */
.section-title .kicker{ color: var(--accent-1); font-family:var(--font-display); font-weight:800; font-size:12.5px; text-transform:uppercase; letter-spacing:.14em; }
.section-title h2{ font-size: clamp(1.8rem, 2.9vw, 2.4rem); margin-top:.3em; }

.grid-3{ display:grid; grid-template-columns: repeat(auto-fit, minmax(240px,1fr)); gap:20px; max-width:1180px; margin:0 auto; }
.benefit-card{ text-align:left; }

/* ---------- Benefits board ------------------------------------------------
   The six reasons to join are one panel split by hairlines rather than six
   separate glass cards. Fixed columns, so both rows always fill: on the old
   auto-fit grid a wide screen fitted four across and left the second row
   half empty. All the chrome belongs to the panel, so a cell carries nothing
   but its number, icon and words. */
.benefits-board{
  max-width:1180px; margin:0 auto; padding:0; overflow:hidden;
  display:grid; grid-template-columns: repeat(3, 1fr);
}
.benefit-cell{
  position:relative; padding:34px 32px 36px;
  border-top:1px solid var(--line); border-left:1px solid var(--line);
  transition: background var(--transition);
}
/* Inner edges only — the outside is drawn by the panel's own border. */
.benefit-cell:nth-child(-n+3){ border-top:0; }
.benefit-cell:nth-child(3n+1){ border-left:0; }
.benefit-cell:hover{ background: var(--surface-strong); }

/* Icon and number share one line: stacked, they left a slack column of empty
   space above every heading and the cell lost its top edge. */
.benefit-cell .cell-head{
  display:flex; align-items:center; justify-content:space-between;
  margin-bottom:20px;
}
.benefit-cell .num{
  font-family: var(--font-label); font-size:11.5px; font-weight:700;
  letter-spacing:.14em; font-variant-numeric: tabular-nums; color: var(--text-faint);
  transition: color var(--transition);
}
.benefit-cell:hover .num{ color: var(--accent-1); }
.benefit-cell .icon{
  font-size:30px; line-height:1;
  transition: transform var(--spring);
}
.benefit-cell:hover .icon{ transform: translateY(-3px) scale(1.12); }
.benefit-cell h4{ margin:0 0 8px; font-size:16.5px; letter-spacing:-.01em; }
.benefit-cell p{ margin:0; color: var(--text-muted); font-size:14px; line-height:1.62; }

/* Marks the hovered cell without moving it — a lift would tear one cell out
   of a surface the whole point of which is that it is continuous. */
.benefit-cell::after{
  content:''; position:absolute; left:0; top:0; bottom:0; width:2px;
  background: linear-gradient(180deg, var(--accent-1), var(--accent-1-light));
  transform: scaleY(0); transform-origin: top; opacity:0;
  transition: transform var(--transition-slow), opacity var(--transition);
}
.benefit-cell:hover::after{ transform: scaleY(1); opacity:1; }

/* Which edges are "inner" changes with the column count, and the rules above
   are :nth-child, so a plain `.benefit-cell` here would lose to them on
   specificity — hence the :nth-child(n) that matches everything. */
@media (max-width: 980px){
  .benefits-board{ grid-template-columns: repeat(2, 1fr); }
  .benefit-cell:nth-child(n){
    border-top:1px solid var(--line); border-left:1px solid var(--line);
  }
  .benefit-cell:nth-child(-n+2){ border-top:0; }
  .benefit-cell:nth-child(2n+1){ border-left:0; }
}
@media (max-width: 560px){
  .benefits-board{ grid-template-columns: 1fr; }
  .benefit-cell:nth-child(n){
    padding:26px 22px 28px;
    border-top:1px solid var(--line); border-left:0;
  }
  .benefit-cell:first-child{ border-top:0; }
}
.job-card{ display:flex; justify-content:space-between; align-items:center; padding:20px 24px; gap:12px; }
.job-card h4{ margin:0 0 4px; font-size:16px; }
.job-card .meta{ color:var(--text-faint); font-size:13px; font-family:var(--font-label); }
.job-list{ max-width:820px; margin:0 auto; display:flex; flex-direction:column; gap:12px; }

/* ---------- Company video (landing) ----------
   A glass plate holding a 16:9 poster. Until it is clicked there is no player
   on the page at all, so the frame has to look like one on its own: a warm
   glow underneath, the brand-red play button and the title reading out of the
   bottom gradient. The click swaps the button for an <iframe> of the same
   size, which is why both share the inner radius. */
.video-frame{
  max-width: 940px; margin: 0 auto; padding: 10px;
  /* The warm cast under the plate is a second shadow rather than a glowing
     pseudo-element: a child at z-index:-1 would paint over the glass
     background instead of behind the whole card. */
  box-shadow: var(--shadow-lift), 0 26px 58px -26px rgba(224,34,31,.5);
}
.video-poster{
  display:block; position:relative; width:100%; aspect-ratio:16/9;
  padding:0; border:0; cursor:pointer; overflow:hidden;
  background: var(--accent-2);
  border-radius: calc(var(--radius-lg) - 10px);
}
.video-frame img, .video-frame iframe{
  display:block; width:100%; height:100%; border:0;
  border-radius: calc(var(--radius-lg) - 10px);
}
.video-frame img{ object-fit:cover; transition: transform var(--transition-slow), filter var(--transition-slow); }
.video-poster:hover img{ transform: scale(1.045); filter: brightness(.82); }
.video-frame iframe{ aspect-ratio:16/9; height:auto; }
/* Keeps the white caption legible over whichever frame YouTube picked. */
.video-poster::after{
  content:''; position:absolute; inset:0; pointer-events:none; border-radius:inherit;
  background: linear-gradient(to top, rgba(10,10,14,.78), rgba(10,10,14,.10) 46%, rgba(10,10,14,.22));
}
.video-play{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); z-index:1;
  width:86px; height:86px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  padding-left:5px;                        /* optical centring of the triangle */
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1));
  color:#fff; box-shadow: var(--shadow-red);
  transition: transform var(--spring), box-shadow var(--transition);
}
/* A ring leaving the button, so the poster reads as playable at a glance. */
.video-play::before{
  content:''; position:absolute; inset:0; border-radius:50%;
  border:2px solid var(--accent-1);
  animation: videoPulse 2.4s ease-out infinite;
}
@keyframes videoPulse{
  0%{ transform:scale(1); opacity:.55; }
  70%,100%{ transform:scale(1.75); opacity:0; }
}
.video-poster:hover .video-play{ transform: translate(-50%,-50%) scale(1.09); box-shadow: 0 14px 34px rgba(224,34,31,.44); }
.video-poster:active .video-play{ transform: translate(-50%,-50%) scale(.98); }
.video-caption{
  position:absolute; left:0; right:0; bottom:0; z-index:1;
  display:flex; flex-direction:column; gap:4px;
  padding:20px 26px 22px; text-align:left; color:#fff;
}
.video-caption-title{ font-family:var(--font-display); font-weight:700; font-size:17px; letter-spacing:-.01em; }
.video-caption-hint{ font-family:var(--font-label); font-size:11px; text-transform:uppercase; letter-spacing:.12em; opacity:.72; }
.video-actions{ text-align:center; margin-top:20px; }
@media (max-width: 560px){
  .video-play{ width:64px; height:64px; padding-left:4px; }
  .video-play svg{ width:24px; height:24px; }
  .video-caption{ padding:14px 18px 16px; }
  .video-caption-title{ font-size:15px; }
}

.partners-strip{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center;
  gap:36px 56px; margin-top:8px;
}
/* The partner PNGs have transparent backgrounds (the white plates were flood-
   filled out; originals kept in static/images/partners/_original/). So both
   themes only need a tone treatment, no background trickery. */
.partner-logo{
  display:flex; align-items:center; justify-content:center;
  height:46px;
  animation: cardin .5s cubic-bezier(.16,1,.3,1) both;
}
.partner-logo:nth-child(1){ animation-delay:.02s; } .partner-logo:nth-child(2){ animation-delay:.06s; }
.partner-logo:nth-child(3){ animation-delay:.10s; } .partner-logo:nth-child(4){ animation-delay:.14s; }
.partner-logo:nth-child(5){ animation-delay:.18s; } .partner-logo:nth-child(6){ animation-delay:.22s; }
.partner-logo:nth-child(7){ animation-delay:.26s; } .partner-logo:nth-child(8){ animation-delay:.30s; }
.partner-logo:nth-child(9){ animation-delay:.34s; } .partner-logo:nth-child(10){ animation-delay:.38s; }
.partner-logo:nth-child(11){ animation-delay:.42s; } .partner-logo:nth-child(n+12){ animation-delay:.46s; }
.partner-logo img{
  max-height:46px; max-width:154px; width:auto; height:auto;
  object-fit:contain;
  filter: grayscale(1) opacity(.5);
  transition: filter var(--transition-slow), transform var(--spring);
}
.partner-logo img:hover{
  filter: grayscale(0) opacity(1);
  transform: scale(1.1) translateY(-3px);
}
/* On dark, invert so dark-ink wordmarks read as light ink; brightness lifts the
   mid-greys off the near-black background. */
[data-theme="dark"] .partner-logo img{
  filter: grayscale(1) invert(1) brightness(1.35) opacity(.62);
}
[data-theme="dark"] .partner-logo img:hover{
  filter: grayscale(1) invert(1) brightness(1.65) opacity(1);
}

.footer{ padding:48px 24px 32px; text-align:center; color: var(--text-faint); font-size:13px; border-top:1px solid var(--border); margin-top:20px; }
.footer a{ color: var(--text-muted); }
.footer a:hover{ color: var(--accent-1); }

/* ---------- Closing photograph ----------
   A wide, shallow strip of the yard between the partner logos and the footer:
   edge to edge across the window, but only a few hundred pixels tall, so it
   reads as a horizon the page passes through rather than a picture it stops
   for.

   The height is set here and the picture is cropped to it — the earlier
   versions let the picture set the height instead, once by carrying its own
   16:9 ratio and once by being pinned to the viewport with
   `background-attachment: fixed`, and both came out far too big. Pinning is
   also what made the frame read as zoomed: a pinned background is sized to the
   VIEWPORT, so a window that is not itself 16:9 — a browser sharing the screen
   with an editor, say — has to blow the picture up until it covers the
   window's height, and the whole yard becomes one truck. */
.site-photo{
  width: 100%;
  height: clamp(190px, 32vh, 380px);
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center 56%;   /* the yard, not the sky */
  /* Masked at the top only. The page above is a drifting gradient that differs
     between the two themes, so no border colour could meet it without showing
     a seam — a third of the height is given over to the fade instead, and the
     logos hand over to the photograph without the eye finding an edge. The
     bottom stays solid: it is the end of the picture and it may as well look
     like one. */
  -webkit-mask-image: linear-gradient(to bottom,
      transparent 0, #000 32%, #000 100%);
          mask-image: linear-gradient(to bottom,
      transparent 0, #000 32%, #000 100%);
}
/* Laptops get the whole photograph rather than a slice of it. Edge to edge the
   picture would stand 690px tall on a laptop, so it is held to a plate a little
   over half the window wide and carries its own 1167x551 shape at that width —
   small enough to sit above the footer in the same screenful, and complete, so
   the yard is a yard and not a wall of truck. `contain` keeps every pixel of it
   inside that box; the top fade is shortened to a tenth because it now falls on
   the picture itself instead of on the part being cropped away. */
@media (min-width: 1000px) and (max-width: 1700px){
  .site-photo{
    width: min(720px, 88vw);
    margin-inline: auto;
    height: auto;
    aspect-ratio: 1167 / 551;
    background-size: contain;
    background-position: center;
    -webkit-mask-image: linear-gradient(to bottom,
        transparent 0, #000 10%, #000 100%);
            mask-image: linear-gradient(to bottom,
        transparent 0, #000 10%, #000 100%);
  }
}
@media (max-width: 640px){
  .site-photo{ height: clamp(150px, 26vh, 260px); }
}

/* ---------- Forms ---------- */
label{ font-size:12.5px; font-weight:700; color: var(--text-muted); text-transform:uppercase; letter-spacing:.03em; display:block; margin-bottom:6px; }
input, select, textarea{
  width:100%; padding:11px 16px; border-radius: var(--radius-pill);
  border:1px solid var(--border-strong); background: var(--input-bg); color: var(--text);
  box-shadow: var(--shadow-soft);
  backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%);
  font-family: var(--font-body); font-size:14.5px;
  transition: border-color var(--transition), box-shadow var(--transition), transform var(--spring);
}
/* Multi-line and native pickers keep a rounded-rect so the text still fits. */
textarea, select[multiple], input[type="file"]{ border-radius: var(--radius-md); }
textarea{ padding:12px 16px; }
input:hover, select:hover, textarea:hover{ border-color: var(--accent-1); }
input:focus, select:focus, textarea:focus{
  outline: none; border-color: var(--accent-1); box-shadow: 0 0 0 4px rgba(224,34,31,.14), var(--shadow-soft);
  transform: translateY(-1px);
}
/* ---------- 3x4 passport photo field ---------- */
.photo-3x4{ display:flex; gap:18px; align-items:flex-start; flex-wrap:wrap; }
.photo-3x4-frame{
  flex:none; width:120px; aspect-ratio:3/4; border-radius:var(--radius-md);
  border:1.5px dashed var(--border-strong); background:var(--input-bg);
  display:flex; align-items:center; justify-content:center; overflow:hidden;
  position:relative; text-align:center;
  box-shadow: var(--shadow-soft);
  transition: border-color var(--transition), transform var(--spring), box-shadow var(--transition);
}
.photo-3x4-frame:hover{ transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.photo-3x4-frame.has-photo{ border-style:solid; border-color:var(--accent-1); }
.photo-3x4-frame img{
  width:100%; height:100%; object-fit:cover; display:none;
  animation: photoIn .4s cubic-bezier(.16,1,.3,1) both;
}
.photo-3x4-frame.has-photo img{ display:block; }
.photo-3x4-frame.has-photo .photo-3x4-placeholder{ display:none; }
@keyframes photoIn{ from{ opacity:0; transform: scale(1.08);} to{ opacity:1; transform: scale(1);} }
.photo-3x4-placeholder{
  font-size:12px; line-height:1.7; color:var(--text-faint); padding:8px;
  text-transform:none; letter-spacing:0;
}
.photo-3x4-body{ flex:1; min-width:200px; }
.photo-3x4-hint{ font-size:12.5px; color:var(--text-muted); margin-bottom:12px; line-height:1.55; text-transform:none; letter-spacing:0; }
.photo-3x4-btn{ display:inline-flex; width:auto; cursor:pointer; margin-bottom:8px; text-transform:none; letter-spacing:0; }
.photo-3x4 input[type="file"]{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); border:0;
}
.photo-3x4 .file-name{ font-size:12px; color:var(--text-faint); text-transform:none; letter-spacing:0; }

/* Under the frame: the camera first, the file chooser second and smaller, and
   one line saying what became of the photograph. The panel of sliders that
   used to live here is gone — the portrait is framed, lit and whitened on the
   way in, so there is nothing left for anybody to set. */
.photo-3x4-shoot{
  display:inline-flex; width:auto; cursor:pointer; margin-bottom:8px;
  text-transform:none; letter-spacing:0;
}
/* The way in for a laptop with no camera, or for a candidate who said no to
   the one it has. A link and not a button: it is the second answer, and it
   should not compete with the first. */
.photo-3x4-alt{
  display:block; margin:0 0 8px; padding:0; border:none; background:none;
  font:inherit; font-size:12px; color:var(--text-muted); cursor:pointer;
  text-decoration:underline; text-transform:none; letter-spacing:0;
}
.photo-3x4-alt:hover{ color:var(--text); }
.photo-3x4-state{
  font-size:12px; line-height:1.5; margin-top:6px; color:var(--text-muted);
  text-transform:none; letter-spacing:0;
}
.photo-3x4-state.is-ok{ color:var(--accent-4); font-weight:600; }
.photo-3x4-state.is-warn{ color:var(--accent-warn); }
.photo-3x4-frame.is-busy{ opacity:.55; }

/* ---------- The camera ----------
   A window over the form, the shape of the portrait, with the composition
   drawn on it: the oval is where photo-bg.js puts the head, so a candidate
   who fills it is framed before the shutter rather than cropped after it. */
.cam-overlay{
  position:fixed; inset:0; z-index:90; padding:20px;
  display:flex; align-items:center; justify-content:center;
  background:rgba(10,10,14,.72); backdrop-filter:blur(6px);
}
.cam-overlay[hidden]{ display:none; }
.cam-box{
  background:var(--surface-solid); border-radius:var(--radius-lg);
  width:100%; max-width:400px; max-height:92vh;
  border:1px solid var(--border-strong); box-shadow:var(--shadow-lift);
  display:flex; flex-direction:column; overflow:hidden;
  animation: camIn .32s cubic-bezier(.16,1,.3,1) both;
}
@keyframes camIn{ from{ opacity:0; transform:translateY(14px) scale(.98);} to{ opacity:1; transform:none;} }
.cam-head{
  display:flex; align-items:center; justify-content:space-between;
  padding:14px 18px; border-bottom:1px solid var(--line);
}
.cam-head b{ font-size:15px; color:var(--text); }
.cam-head .modal-close{
  background:none; border:none; font-size:22px; line-height:1; color:var(--text-faint);
  cursor:pointer; padding:2px 8px; border-radius:var(--radius-sm); width:auto; box-shadow:none;
}
.cam-head .modal-close:hover{ background:rgba(118,118,128,.12); color:var(--text); }
.cam-stage{ position:relative; aspect-ratio:3/4; background:#101014; overflow:hidden; }
/* Mirrored, because a person expects a mirror. The photograph itself is taken
   from the video element unmirrored — see grab() in photo-camera.js. */
.cam-stage video{
  width:100%; height:100%; object-fit:cover; display:block; transform:scaleX(-1);
}
.cam-stage img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  background:#fff; animation: photoIn .4s cubic-bezier(.16,1,.3,1) both;
}
.cam-stage img[hidden]{ display:none; }
.cam-guide{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; }
.cam-guide[hidden]{ display:none; }
.cam-guide ellipse{
  fill:none; stroke:rgba(255,255,255,.82); stroke-width:2; stroke-dasharray:9 8;
}
.cam-veil{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  background:rgba(10,10,14,.45);
}
.cam-veil[hidden]{ display:none; }
.cam-veil i{
  display:block; width:34px; height:34px; border-radius:50%;
  border:3px solid rgba(255,255,255,.28); border-top-color:#fff;
  animation: camSpin .8s linear infinite;
}
@keyframes camSpin{ to{ transform:rotate(360deg);} }
.cam-note{
  padding:12px 18px; min-height:46px; font-size:12.5px; line-height:1.55;
  color:var(--text-muted);
}
.cam-note.is-ok{ color:var(--accent-4); font-weight:600; }
.cam-note.is-warn{ color:var(--accent-warn); }
.cam-foot{ padding:0 18px 16px; }
.cam-foot .btn{ width:100%; }

/* ---------- Согласие перед отправкой анкеты ----------
   Отдельная карточка, а не строка мелким шрифтом внизу: человек ставит
   отметку, которая потом может понадобиться в споре, и она должна читаться
   как решение, а не как формальность, которую пролистывают. */
.consent{
  margin-top:26px; padding:18px 20px 16px; border-radius:var(--radius-md);
  border:1px solid var(--border-strong); background:var(--input-bg);
}
.consent.has-error{ border-color:var(--accent-1); }
.consent-head{
  font-size:11px; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--text-faint); margin-bottom:14px;
}
/* Отметка о согласии в карточке кандидата. Отсутствие показывается так же
   заметно, как наличие: анкета без согласия — это факт, который кадровик
   должен видеть сразу, а не выяснять. */
.consent-row{
  display:flex; align-items:flex-start; gap:11px; margin-top:20px;
  padding:12px 15px; border-radius:var(--radius-sm);
  background:rgba(48,209,88,.08); border:1px solid rgba(48,209,88,.3);
}
.consent-row.is-off{ background:rgba(224,34,31,.06); border-color:rgba(224,34,31,.3); }
.consent-badge{
  flex:none; width:22px; height:22px; border-radius:50%; display:flex;
  align-items:center; justify-content:center; font-size:12px; font-weight:700;
  background:var(--accent-4); color:#fff;
}
.consent-row.is-off .consent-badge{ background:var(--accent-1); }
.consent-row b{ display:block; font-size:13px; color:var(--text); }
.consent-row span{ font-size:11.5px; color:var(--text-muted); font-family:var(--font-label); }
.consent-why{
  font-size:12.5px; line-height:1.55; color:var(--text-muted);
  margin:-8px 0 14px; text-transform:none; letter-spacing:0;
}
.consent-item{
  display:flex; gap:12px; align-items:flex-start; cursor:pointer; margin:0 0 14px;
  text-transform:none; letter-spacing:0;
}
.consent-item:last-of-type{ margin-bottom:0; }
/* Родной квадратик не красится и по-разному выглядит в каждой системе, а
   этот экран — единственный, который кандидат обязан прочитать. Поэтому
   настоящий чекбокс делается прозрачным, но НЕ схлопывается в ноль и не
   выносится за экран: браузер отказывается показывать подсказку «отметьте
   это поле» на элементе нулевого размера и просто молча не отправляет форму.
   Со стороны это выглядит как сломанная кнопка. Он лежит поверх нарисованного
   квадратика, ловит клик и остаётся фокусируемым. */
.consent-item{ position:relative; }
.consent-item input{
  position:absolute; left:0; top:1px; width:21px; height:21px;
  margin:0; opacity:0; cursor:pointer;
}
.consent-mark{
  flex:none; width:21px; height:21px; margin-top:1px; border-radius:7px;
  border:1.5px solid var(--border-strong); background:var(--surface-solid);
  position:relative; transition:background var(--transition), border-color var(--transition);
}
.consent-item input:checked + .consent-mark{ background:var(--accent-1); border-color:var(--accent-1); }
.consent-item input:checked + .consent-mark::after{
  content:''; position:absolute; left:7px; top:3px; width:5px; height:10px;
  border:solid #fff; border-width:0 2px 2px 0; transform:rotate(45deg);
}
.consent-item input:focus-visible + .consent-mark{ outline:2px solid var(--accent-1); outline-offset:2px; }
.consent-text{ font-size:12.6px; line-height:1.6; color:var(--text-muted); font-weight:400; }
.consent-text b{
  display:block; font-size:13.5px; font-weight:700; color:var(--text); margin-bottom:4px;
}
.consent-note{
  font-size:11.5px; color:var(--text-faint); line-height:1.5;
  margin:14px 0 0 33px; text-transform:none; letter-spacing:0;
}
@media (max-width:520px){ .consent-note{ margin-left:0; } }

/* «Опыта работы нет» — на шаге про опыт. Та же механика, что и у согласия:
   настоящий флажок прозрачный, но с размером и поверх нарисованного квадратика,
   иначе браузеру негде показать подсказку. Отдельный вид у блока: это не
   очередное поле, а ответ, который убирает со страницы целую таблицу. */
.no-exp-toggle{
  position:relative; display:flex; gap:12px; align-items:center; cursor:pointer;
  margin:0 0 16px; padding:12px 14px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  transition: border-color var(--transition), background var(--transition);
}
.no-exp-toggle:hover{ border-color: var(--accent-1); }
.no-exp-toggle input{
  position:absolute; left:14px; top:50%; transform:translateY(-50%);
  width:21px; height:21px; margin:0; opacity:0; cursor:pointer;
}
.no-exp-mark{
  flex:none; width:21px; height:21px; border-radius:7px;
  border:1.5px solid var(--border-strong); background: var(--surface-solid);
  position:relative; transition:background var(--transition), border-color var(--transition);
}
.no-exp-toggle input:checked + .no-exp-mark{ background: var(--accent-1); border-color: var(--accent-1); }
.no-exp-toggle input:checked + .no-exp-mark::after{
  content:''; position:absolute; left:7px; top:3px; width:5px; height:10px;
  border:solid #fff; border-width:0 2px 2px 0; transform:rotate(45deg);
}
.no-exp-toggle input:focus-visible + .no-exp-mark{ outline:2px solid var(--accent-1); outline-offset:2px; }
.no-exp-text{ font-size:14px; font-weight:600; color: var(--text); }
.no-exp-note{
  margin:0 0 4px; font-size:12.5px; color: var(--text-faint); line-height:1.55;
}
/* Пояснение под заголовком раздела анкеты: что именно здесь ждут. Стоит
   между заголовком и полями, поэтому отступ снизу больше, чем сверху. */
.section-note{
  margin:-4px 0 12px; font-size:12.5px; color: var(--text-faint); line-height:1.55;
}
/* On the card and in the printed questionnaire: the section is empty because
   it was answered, not because it was skipped. */
.q-none{
  display:inline-block; padding:8px 14px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  font-size:13px; color: var(--text-muted);
}


/* Password input with a reveal toggle sitting inside the pill. */
.password-field{ position:relative; }
.password-field input{ padding-right:48px; }
.password-eye{
  position:absolute; right:6px; top:50%; transform:translateY(-50%);
  width:34px; height:34px; padding:0; border:none; border-radius:var(--radius-pill);
  background:transparent; cursor:pointer; font-size:16px; line-height:1;
  display:flex; align-items:center; justify-content:center; opacity:.6;
  transition: opacity var(--transition), transform var(--spring), background var(--transition);
}
.password-eye:hover{ opacity:1; background:var(--surface-strong); transform:translateY(-50%) scale(1.12); }
.password-eye:active{ transform:translateY(-50%) scale(.9); }
.password-eye.is-on{ opacity:1; }

.field{ margin-bottom:16px; }
.field-row{ display:grid; grid-template-columns: repeat(auto-fit, minmax(220px,1fr)); gap:16px; }
/* Repeatable "+" blocks — one box per vacancy in Settings. */
.position-boxes{ display:flex; flex-direction:column; gap:12px; margin-bottom:12px; }
.position-box{
  padding:14px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  box-shadow: var(--shadow-soft);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.position-box:focus-within{ border-color: var(--accent-1); box-shadow: var(--shadow-lift); }
.position-box-head{ display:flex; gap:10px; align-items:center; margin-bottom:10px; }
.position-box-head .pos-title{ flex:1; font-weight:700; }
.position-box textarea{ resize:vertical; min-height:52px; }
/* Per-vacancy location. Sits under the description rather than in the head
   row: the head already carries the title, the open/closed switch and the
   delete button, and a fourth control there squeezed the title to nothing. */
.position-box-foot{ display:flex; align-items:center; gap:8px; margin-top:10px; }
.position-box-pin{ font-size:14px; opacity:.6; flex:none; }
.position-box-foot .pos-location{ flex:1; font-size:13px; }
.position-box-remove{
  flex:none; width:30px; height:30px; border-radius:50%; border:1px solid var(--border-strong);
  background:transparent; color:var(--text-faint); font-size:19px; line-height:1; cursor:pointer;
  transition: background var(--transition), color var(--transition), transform var(--spring);
}
.position-box-remove:hover{ background:var(--accent-3); border-color:var(--accent-3); color:#fff; transform:scale(1.1); }
.position-box-new{ animation: cardin .3s cubic-bezier(.16,1,.3,1) both; }
.position-box-out{ opacity:0; transform:translateX(-12px); transition: opacity .18s, transform .18s; }

/* Open / closed switch. A closed vacancy stays in the panel but disappears
   from the public list and from the application form. */
.position-box-state{
  flex:none; display:inline-flex; align-items:center; gap:7px; white-space:nowrap;
  padding:7px 14px; border-radius:100px; cursor:pointer;
  font-size:12.5px; font-weight:700; letter-spacing:.01em;
  border:1px solid var(--border-strong); background:transparent; color:var(--text-muted);
  transition: background var(--transition), color var(--transition), border-color var(--transition), transform var(--spring);
}
.position-box-state::before{
  content:""; width:8px; height:8px; border-radius:50%; background:currentColor;
}
.position-box-state:hover{ transform:translateY(-1px); }
.position-box-state.is-open{ color:#1a9d47; border-color:rgba(26,157,71,.45); background:rgba(48,209,88,.12); }
.position-box.is-closed{ opacity:.62; }
.position-box.is-closed:focus-within{ opacity:1; }

.position-chip-list{ display:flex; flex-wrap:wrap; gap:8px; margin-bottom:10px; }
.position-chip{
  display:flex; align-items:center; gap:6px;
  background: var(--input-bg); border:1px solid var(--border);
  border-radius: 999px; padding:7px 8px 7px 14px;
  font-size:13px; font-weight:600; color: var(--text);
}
.position-chip button{
  background:none; border:none; cursor:pointer; color:var(--text-faint);
  width:20px; height:20px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:16px; line-height:1; padding:0; transition: var(--transition);
}
.position-chip button:hover{ background: var(--accent-3); color:#fff; }
.add-position-row{ display:flex; gap:8px; }
.add-position-row input{ flex:1; }
.position-empty-hint{ font-size:12.5px; color: var(--text-faint); margin-bottom:10px; }
.form-section-title{
  font-family:var(--font-display); font-size:18px; font-weight:700; margin: 32px 0 16px; padding-bottom:10px;
  border-bottom: 1px solid var(--border); display:flex; align-items:center; gap:10px;
}
.form-section-title .num{
  width:28px; height:28px; border-radius:8px; background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1));
  color:#fff; display:flex; align-items:center; justify-content:center; font-size:12.5px; font-weight:800;
  font-family: var(--font-label); font-variant-numeric: tabular-nums;
  box-shadow: 0 3px 8px rgba(224,34,31,.30);
}

/* One-shot greeting shown right after signing in, dismissed by its button. */
.welcome-gate{
  position:fixed; inset:0; z-index:300; display:flex; align-items:center; justify-content:center;
  padding:24px; backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  background: rgba(247,238,245,.72);
  animation: gateIn .35s ease both;
}
[data-theme="dark"] .welcome-gate{ background: rgba(24,18,25,.78); }
@keyframes gateIn{ from{ opacity:0; } to{ opacity:1; } }
.welcome-gate-out{ opacity:0; transform: scale(1.04); filter: blur(8px);
  transition: opacity .4s, transform .4s, filter .4s; pointer-events:none; }
.welcome-gate-card{
  text-align:center; max-width:440px; width:100%; padding:44px 34px;
  background: var(--surface-strong); border:1px solid var(--border-strong);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lift);
  backdrop-filter: blur(42px) saturate(200%); -webkit-backdrop-filter: blur(42px) saturate(200%);
  animation: cardin .5s cubic-bezier(.16,1,.3,1) both;
}
.welcome-gate-mascot{
  display:block; font-size:52px; line-height:1; margin-bottom:14px;
  animation: mascotBob 3s ease-in-out infinite;
}
@keyframes mascotBob{ 0%,100%{ transform: translateY(0) rotate(-4deg);} 50%{ transform: translateY(-8px) rotate(4deg);} }
.welcome-gate-card h2{ font-size:21px; line-height:1.35; color: var(--accent-1); margin:0 0 12px; }
.welcome-gate-card p{ font-size:14px; line-height:1.65; color: var(--text-muted); margin:0 0 24px; }
/* The gate can hold more than one card (the application link asks for a
   language first, then says hello); only the open one is in the flow. */
.welcome-gate-card[hidden]{ display:none; }
/* While a gate is open the page underneath must not scroll behind it. */
html.welcome-open, html.welcome-open body{ overflow:hidden; }

/* Language picker — the one screen shown before we know which language to
   greet someone in, so it is a grid of the languages themselves. */
.apply-lang-grid{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:4px; }
.apply-lang-btn{
  position:relative; overflow:hidden;
  display:flex; align-items:center; justify-content:center; gap:8px;
  padding:14px 12px; border-radius: var(--radius-sm, 14px);
  background: var(--input-bg); border:1px solid var(--border);
  color: var(--text); font-size:14.5px; font-weight:600; text-decoration:none;
  transition: transform .22s cubic-bezier(.34,1.56,.64,1), background .18s,
              border-color .18s, box-shadow .22s, opacity .3s;
  /* Dealt in, one after another, in the order they are read. */
  animation: langIn .55s cubic-bezier(.16,1,.3,1) both;
  animation-delay: calc(var(--i, 0) * .08s + .2s);
}
@keyframes langIn{
  from{ opacity:0; transform: translateY(14px) scale(.94); }
  to{ opacity:1; transform: none; }
}
.apply-lang-btn .lang-tag{
  flex:none; font-size:11px; font-weight:800; letter-spacing:.06em; line-height:1;
  padding:5px 7px; border-radius:7px; display:inline-block;
  background: rgba(224,34,31,.10); color: var(--accent-1);
  transition: transform .28s cubic-bezier(.34,1.56,.64,1), background .18s;
}
/* A sheen that crosses the button on hover — the one flourish on a screen
   whose whole job is to be pressed. */
.apply-lang-btn::after{
  content:''; position:absolute; inset:0; transform: translateX(-120%);
  background: linear-gradient(100deg, transparent 25%, rgba(255,255,255,.55) 50%, transparent 75%);
  transition: transform .6s ease; pointer-events:none;
}
[data-theme="dark"] .apply-lang-btn::after{
  background: linear-gradient(100deg, transparent 25%, rgba(255,255,255,.12) 50%, transparent 75%);
}
.apply-lang-btn:hover{
  background: var(--surface-strong); border-color: var(--accent-1);
  transform: translateY(-3px); box-shadow: 0 10px 22px rgba(224,34,31,.14);
}
.apply-lang-btn:hover::after{ transform: translateX(120%); }
.apply-lang-btn:hover .lang-tag{ transform: scale(1.12); background: rgba(224,34,31,.18); }
.apply-lang-btn:focus-visible{ outline:2px solid var(--accent-1); outline-offset:3px; }
.apply-lang-btn:active{ transform: translateY(-1px) scale(.98); }
/* The pick itself: the chosen language swells and lights up while the page
   reloads in it, the other three step back. */
.apply-lang-grid.is-picking .apply-lang-btn{ opacity:.35; transform: scale(.96); }
.apply-lang-grid.is-picking .apply-lang-btn.is-picked{
  opacity:1; border-color: var(--accent-1); color: var(--accent-1);
  transform: scale(1.04); box-shadow: 0 12px 26px rgba(224,34,31,.22);
}
.apply-lang-grid.is-picking .is-picked .lang-tag{ transform: scale(1.2); background: rgba(224,34,31,.22); }
@media (max-width:420px){ .apply-lang-grid{ grid-template-columns:1fr; } }

/* Greeting card extras: the role someone was invited for, and the one line of
   housekeeping (how long it takes, what to have ready) that keeps the card
   from being a wall of text. */
.welcome-role{
  display:inline-block; margin:-8px 0 14px; padding:7px 14px; border-radius:999px;
  background: rgba(224,34,31,.08); color: var(--accent-1); font-size:13px; font-weight:650;
}
.welcome-meta{
  font-size:12.5px; line-height:1.6; color: var(--text-muted); margin:0 0 22px;
}
@media (prefers-reduced-motion: reduce){
  .welcome-gate, .welcome-gate-card, .welcome-gate-mascot,
  .apply-lang-btn{ animation:none !important; }
  .apply-lang-btn::after{ display:none; }
  .apply-lang-btn:hover, .apply-lang-btn:hover .lang-tag{ transform:none; }
}

.auth-wrap{ min-height:100vh; display:flex; align-items:center; justify-content:center; padding:24px; }
.auth-card{ width:100%; max-width:400px; padding:40px 34px; animation: cardin .5s var(--transition-slow) both; }
.auth-card .brand{ justify-content:center; margin-bottom:22px; }
.checkbox-row{ display:flex; align-items:center; gap:8px; font-size:13px; color:var(--text-muted); text-transform:none; }
.checkbox-row input{ width:auto; }

.progress-bar-outer{ height:6px; border-radius:999px; background: var(--input-bg); overflow:hidden; margin-bottom:20px; border:1px solid var(--border); }
.progress-bar-inner{ height:100%; background: linear-gradient(90deg, var(--accent-1), var(--accent-1-light)); transition: width .4s var(--transition-slow); position:relative; }
.progress-bar-inner::after{
  content:''; position:absolute; inset:0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.45), transparent);
  width:60px; animation: shimmer 1.6s linear infinite;
}
@keyframes shimmer{ from{ transform: translateX(-80px); } to{ transform: translateX(240px); } }

.step-dots{ display:flex; gap:6px; justify-content:center; margin-bottom:24px; flex-wrap:wrap; }
.step-dot{
  width:28px; height:28px; border-radius:8px; border:1.5px solid var(--border-strong); background:var(--input-bg);
  display:flex; align-items:center; justify-content:center; font-family:var(--font-label); font-size:11.5px;
  font-weight:700; font-variant-numeric: tabular-nums; color:var(--text-faint); transition: var(--transition);
  /* Each dot jumps straight to its step, so it has to read as a control. */
  padding:0; cursor:pointer; font-family:var(--font-label);
}
.step-dot:hover{ border-color: var(--accent-1); color: var(--text); transform: translateY(-1px); }
.step-dot:focus-visible{ outline:2px solid var(--accent-1); outline-offset:2px; }
.step-dot.active:hover{ transform: scale(1.08); }
.step-dot.active{ border-color: var(--accent-1); color:#fff; background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1)); box-shadow: 0 4px 10px rgba(224,34,31,.35); transform: scale(1.08); }
.step-dot.done{ border-color: var(--accent-4); color:#fff; background: var(--accent-4); }

.upload-zone{
  border:1.5px dashed var(--border-strong); border-radius: var(--radius-md); padding:22px; text-align:center;
  cursor:pointer; transition: border-color var(--transition), background var(--transition), transform var(--transition); position:relative;
  font-size: 13.5px;
}
.upload-zone:hover{ transform: translateY(-1px); }
.upload-zone:hover, .upload-zone.dragover{ border-color: var(--accent-1); background: rgba(224,34,31,.05); }
.upload-zone input[type=file]{ position:absolute; inset:0; opacity:0; cursor:pointer; }
.upload-zone .file-name{ font-family: var(--font-label); font-size:12px; color:var(--accent-1); margin-top:6px; word-break:break-all; }

/* ---------- Admin layout ---------- */
.admin-shell{ display:flex; min-height:100vh; }
.sidebar{
  width: 248px; flex-shrink:0; padding: 20px 14px; position: sticky; top:0; height:100vh;
  display:flex; flex-direction:column; border-right:1px solid var(--border); border-radius:0;
}
.sidebar .brand{ padding: 6px 10px 22px; flex-shrink:0; }
/* The menu is the only part of the panel whose height depends on who is
   looking at it — an HR lead is given five entries a recruiter never sees — so
   it is the only part allowed to scroll. The panel is exactly one screen tall
   and cannot be scrolled itself, so on a short window the tail of the list and
   the account card under it used to run off the bottom with no way back.
   `min-height:0` is what lets a flex child shrink under its own content;
   without it the list refuses to shorten and there is nothing to scroll.
   The 4px of padding, handed straight back as negative margin, is room for the
   3px nudge an entry makes under the pointer: it keeps the entries as wide as
   they were while stopping that nudge from being clipped off. */
.side-nav{
  display:flex; flex-direction:column; gap:3px; flex:1; min-height:0;
  overflow-y:auto; overflow-x:hidden; overscroll-behavior: contain;
  padding-right:4px; margin-right:-4px;
  scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent;
  /* Both ends are square until something is actually scrolled past them, at
     which point main.js opens the fade on that side alone. */
  --fade-top:0px; --fade-bottom:0px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-top),
                      #000 calc(100% - var(--fade-bottom)), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-top),
                      #000 calc(100% - var(--fade-bottom)), transparent 100%);
}
/* Slimmer and quieter than the page's own bar — this one lives inside a 248px
   panel, and only says how far down the list you are. */
.side-nav::-webkit-scrollbar{ width:6px; }
.side-nav::-webkit-scrollbar-thumb{ background: var(--border); }
.side-nav:hover::-webkit-scrollbar-thumb{ background: var(--border-strong); }
.side-nav a{
  display:flex; align-items:center; gap:12px; padding:10px 13px; border-radius: var(--radius-sm);
  font-weight:600; font-size:13.5px; color: var(--text-muted); transition: all var(--transition);
  border-left: 2px solid transparent;
}
.side-nav a:hover{ background: var(--input-bg); color: var(--text); }
.side-nav a.active{
  background: rgba(224,34,31,.08); color: var(--accent-1); border-left-color: var(--accent-1);
}
.side-nav .icon{ font-size:16px; width:20px; text-align:center; }
/* A nav entry for a section that does not exist yet: greyed, desaturated and
   inert. Every hover affordance is switched back off, so nothing invites a
   click that would go nowhere. */
.side-nav a.locked{ color: var(--text-faint); cursor: default; border-left-color: transparent; }
.side-nav a.locked:hover{ background: transparent; color: var(--text-faint); transform: none; }
.side-nav a.locked .icon{ filter: grayscale(1); opacity:.7; }
.side-nav a.locked:hover .icon{ transform: none; }
.side-nav .nav-lock{ margin-left:auto; font-size:11px; opacity:.55; filter: grayscale(1); }
/* ---------- Направления в панели ----------
   Заголовок направления — кнопка, а не подпись: направление, которым сегодня
   не занимаешься, складывается. Подпись набрана мелко и в разрядку, чтобы
   делить список, но не спорить с самими пунктами за внимание; шеврон справа
   говорит, что по строке можно нажать, и показывает, сложено ли. */
.nav-group{ display:flex; flex-direction:column; }

.side-nav .nav-section{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  width:100%; margin:14px 0 4px; padding:6px 13px;
  background:none; border:0; border-radius: var(--radius-sm);
  font-family:inherit; font-size:10.5px; font-weight:700;
  letter-spacing:.12em; text-transform:uppercase; text-align:left;
  color: var(--text-faint); cursor:pointer;
  transition: color var(--transition), background var(--transition);
  -webkit-tap-highlight-color: transparent;
}
.side-nav .nav-section:hover{ background: var(--input-bg); color: var(--text-muted); }
.side-nav .nav-section:focus-visible{ outline:2px solid var(--accent-1); outline-offset:1px; }

/* Шеврон рисуется рамкой, а не глифом: он должен поворачиваться, и поворот
   должен быть плавным — глиф так не умеет. Открыто — смотрит вниз. */
.nav-chevron{
  flex:none; width:6px; height:6px; margin-right:2px;
  border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform var(--spring);
}
.nav-group.is-collapsed .nav-chevron{ transform: rotate(-45deg) translate(-1px, -1px); }

/* Высота ставится в js по факту содержимого: складывать в фиксированную
   величину значит гнать пустую часть анимации впустую. */
.nav-items{
  display:flex; flex-direction:column; gap:3px; overflow:hidden;
  /* visibility без задержки на открытии и с задержкой на закрытии: пункты
     появляются сразу, а исчезают доехав. Она здесь не ради вида — сложенный
     раздел не должен ловить Tab: обрезка по overflow прячет от мыши, но не от
     клавиатуры. */
  transition: max-height .28s cubic-bezier(.22,1,.36,1), opacity .2s ease,
              visibility 0s linear 0s;
}
.nav-group.is-collapsed .nav-items{
  opacity:0; visibility:hidden;
  transition: max-height .28s cubic-bezier(.22,1,.36,1), opacity .2s ease,
              visibility 0s linear .28s;
}
@media (prefers-reduced-motion: reduce){
  .nav-items{ transition:none; }
  .nav-chevron{ transition:none; }
}
.sidebar-footer{ border-top:1px solid var(--border); padding-top:14px; margin-top:14px; flex-shrink:0; }

/* ---------- A candidate's status: the step forward, and everything else ----
   The step is one or two ordinary buttons, because at that point there are
   only ever one or two honest answers. The six statuses that are not a step
   -- refused, on hold, gone quiet -- sit behind <details>, which opens them
   without a line of script and closes itself when the form navigates away. */
.status-step-label{
  font-size:11.5px; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color: var(--text-faint);
}
.status-more{ position:relative; }
/* Both lines are needed to lose the disclosure triangle: Safari draws it
   through a pseudo-element of its own, everyone else through list-style. */
.status-more > summary{ list-style:none; }
.status-more > summary::-webkit-details-marker{ display:none; }
.status-more > summary::after{ content:'▾'; font-size:11px; opacity:.75; }
.status-more[open] > summary::after{ content:'▴'; }
/* Opened, it takes the whole row and pushes the page down instead of hanging
   over it. A floating menu was the first shape this had, and the card it sits
   in clips its own overflow -- so half the list was cut off by the tab strip
   below. Six statuses that wrap are worth more than a menu with a shadow. */
.status-more{ position:relative; }
.status-more[open]{ flex-basis:100%; }
.status-more-menu{
  display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; padding:10px;
  background: var(--input-bg); border:1px solid var(--border);
  border-radius: var(--radius-md);
}
.status-more-item{
  display:flex; align-items:center; gap:8px;
  padding:5px 6px; border:0; border-radius: var(--radius-sm);
  background:none; cursor:pointer; font:inherit;
}
.status-more-item:hover{ background: var(--surface-strong); }
.status-more-item .badge{ cursor:pointer; }

/* The signed-in account, and on the same line the way out of it. The name
   column is the only part allowed to give ground: `min-width:0` lets the long
   pair of names clip instead of pushing the sign-out button off the panel. */
.account-chip{ display:flex; align-items:center; gap:10px; padding:8px; }
.account-chip-who{ min-width:0; flex:1; }
.account-chip-name{ font-weight:700; font-size:13.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.account-chip-role{ font-size:12px; color: var(--text-faint); }
.account-chip-out{ margin:0; flex-shrink:0; }
/* Smaller than the 40px topbar icon buttons: this one shares a line with the
   avatar and must not out-weigh it. Muted until pointed at, then red — ending
   a session is not a thing to click by accident. */
.account-chip-out .btn-icon{ width:32px; height:32px; color: var(--text-faint); }
.account-chip-out .btn-icon:hover{ color: var(--accent-1); }

.admin-main{ flex:1; min-width:0; }
.topbar{
  display:flex; align-items:center; justify-content:space-between; padding:16px 30px;
  border-bottom:1px solid var(--border); position: sticky; top:0; background: var(--bg); z-index:20;
}
.topbar h1{ font-size:20px; margin:0; }
.admin-content{ padding:26px 30px 60px; }

/* Seven cards on an auto-fit grid came out six-and-one, and the lone card on
   the second row read as a page that had lost five. Counting the first card
   as two cells makes eight, which fills 4- and 2-column layouts exactly — and
   the total, the number HR actually looks at first, gets the extra width. */
.stat-grid{ display:grid; grid-template-columns: repeat(4, 1fr); gap:16px; margin-bottom:26px; }
.stat-grid > :first-child{ grid-column: span 2; }
.stat-grid > :first-child .stat-value{ font-size:40px; }
@media (max-width: 1100px){ .stat-grid{ grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px){
  .stat-grid{ grid-template-columns: 1fr; }
  .stat-grid > :first-child{ grid-column: auto; }
}
/* Each tile links into the candidate list, pre-filtered by that status. */
a.stat-card{ display:block; cursor:pointer; text-decoration:none; }
a.stat-card:hover{ transform: translateY(-4px); box-shadow: var(--shadow-lift); border-color: var(--accent-1); }
a.stat-card:hover .stat-value{ color: var(--accent-1); }
a.stat-card:active{ transform: translateY(-1px) scale(.99); }
a.stat-card .stat-value{ transition: color var(--transition); }
a.stat-card .stat-icon{ transition: transform var(--spring); }
a.stat-card:hover .stat-icon{ transform: scale(1.18) rotate(-6deg); }
.stat-card{ padding:22px 20px; position:relative; overflow:hidden; }
.stat-card .stat-label{ font-size:11.5px; color:var(--text-muted); font-weight:700; text-transform:uppercase; letter-spacing:.08em; font-family:var(--font-label); }
.stat-card .stat-value{ font-family:var(--font-display); font-size:32px; font-weight:800; margin-top:4px; font-variant-numeric: tabular-nums; }
.stat-card .stat-icon{ position:absolute; right:16px; top:16px; font-size:18px; opacity:.4; }

/* Admin list: the edit panel stays collapsed until "Edit" is pressed. */
.admin-row{ margin-bottom:8px; }
/* Строка администратора: слева имя с почтой, справа метки роли и «Изменить».
   В одну линию это помещается только на широком экране. На узком метки
   наезжали на почту, а кнопка уезжала за край страницы — до неё нельзя было
   дотянуться вовсе. Теперь правая группа переносится под имя. */
.admin-row .doc-item{ flex-wrap:wrap; gap:10px 12px; }
/* Без min-width:0 флекс-элемент не сжимается меньше собственного текста:
   длинная почта распирала строку изнутри, и справа уже ничего не помещалось. */
.admin-row .doc-name{ min-width:0; flex:1 1 220px; }
.admin-row .doc-name > div:last-child{ min-width:0; overflow-wrap:anywhere; }
.admin-row .doc-name .avatar{ flex:none; }
.admin-marks{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-left:auto;
  min-width:0; max-width:100%;
}
/* Метка с длинным названием роли — «База сотрудников (актив/пассив)» — на
   узком экране переносится внутри себя, а не растягивает строку. */
.admin-marks .badge{ white-space:normal; text-align:center; }
@media (max-width: 640px){
  .admin-row .doc-item{ align-items:flex-start; }
  .admin-row .doc-name{ flex:1 1 100%; }
  .admin-marks{ margin-left:0; width:100%; }
  /* Кнопка уходит на свою строку. Пустышка во всю ширину перед ней ломает
     флекс-строку — это надёжнее, чем надеяться, что метка и кнопка сами
     разойдутся: при длинном названии роли они не расходились, и «Изменить»
     вылезала за край карточки, где до неё нельзя дотянуться. */
  .admin-marks::after{ content:""; flex-basis:100%; height:0; order:1; }
  .admin-marks > .btn{ order:2; }
}
.admin-edit{
  display:none; gap:10px; align-items:flex-end; flex-wrap:wrap;
  padding:14px; margin-top:6px;
  background: var(--surface-strong); border:1px solid var(--border-strong);
  border-radius: var(--radius-md);
  animation: cardin .28s cubic-bezier(.16,1,.3,1) both;
}
.admin-row.editing .admin-edit{ display:flex; }
.admin-edit-form{ display:flex; gap:10px; align-items:flex-end; flex-wrap:wrap; flex:1; }
.admin-edit .field{ margin-bottom:0; flex:1; min-width:130px; }
.admin-edit label{ font-size:11px; }

/* Open-position cards on the landing page carry an admin-written description. */
.job-desc{
  margin:6px 0 8px; font-size:13.5px; line-height:1.6; color: var(--text-muted);
  max-width: 62ch;
}
.job-card{ align-items:flex-start; }

/* Invitation form laid out horizontally so the table below gets the full width. */
.invite-form{
  display:grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap:14px; align-items:end;
}
.invite-form .field{ margin-bottom:0; }
/* The submit label is long in every language, so give it its own full row
   instead of squeezing it into a 190px track (where `overflow:hidden` on
   .btn would clip the text rather than wrap it). */
.invite-form .btn{ grid-column: 1 / -1; justify-self: start; width: auto; padding: 12px 28px; }

.two-col{ display:grid; grid-template-columns: 1.5fr 1fr; gap:20px; align-items:start; }
/* Grid children default to min-width:auto, so a wide table inside the left
   column stretches the track and pushes the right column off-screen. */
.two-col > *{ min-width: 0; }
@media (max-width: 980px){ .two-col{ grid-template-columns: 1fr; } }

.table-wrap{ overflow-x:auto; }
table{ width:100%; border-collapse: collapse; font-size:13.5px; }
th{ text-align:left; padding:10px 12px; color:var(--text-faint); font-weight:700; font-size:11px; text-transform:uppercase; letter-spacing:.08em; font-family: var(--font-label); border-bottom:1.5px solid var(--border-strong); }
td{ padding:13px 12px; border-bottom:1px solid var(--border); vertical-align:middle; }
tr:last-child td{ border-bottom:none; }
tr.row-link{ cursor:pointer; transition: background var(--transition); }
tr.row-link:hover{ background: var(--input-bg); }

.avatar{
  width:36px; height:36px; border-radius:9px; display:flex; align-items:center; justify-content:center;
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1)); color:#fff; font-weight:700; font-size:13px; font-family: var(--font-label);
  overflow:hidden; flex-shrink:0;
}
.avatar img{ width:100%; height:100%; object-fit:cover; }

/* ---------- Badges ---------- */
.badge{
  display:inline-flex; align-items:center; gap:5px; padding:5px 12px; border-radius: 999px;
  font-size:11px; font-weight:700; font-family: var(--font-label); text-transform:uppercase; letter-spacing:.08em;
  border: 1.5px solid currentColor; background: transparent;
}
.badge-gray{ color:#6B6E78; }
.badge-blue{ color:#2B5CA5; }
.badge-indigo{ color:#4B4FC4; }
.badge-violet{ color:#7A3FC9; }
.badge-amber{ color:#D98C1F; }
.badge-green{ color:#1E8E5A; }
.badge-red{ color:#C1121C; }

/* A revoked invitation is dead weight on the list, so its row carries one x
   that takes it off for good. It sits beside the badge rather than among the
   buttons in the actions column -- it belongs to the status it undoes -- and
   is sized off the badge, because a full .btn there would out-shout it. */
.badge-with-x{ display:inline-flex; align-items:center; gap:8px; }
.badge-with-x form{ display:flex; }
.badge-x{
  flex:none; width:24px; height:24px; padding:0; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  border:1.5px solid var(--border-strong); background:transparent;
  color:var(--text-faint); font-size:16px; line-height:1; cursor:pointer;
  transition: background var(--transition), color var(--transition),
              border-color var(--transition), transform var(--spring);
}
.badge-x:hover{ background:var(--accent-3); border-color:var(--accent-3); color:#fff; transform:scale(1.1); }

.activity-item{ display:flex; gap:12px; padding:11px 0; border-bottom:1px solid var(--border); }
.activity-item:last-child{ border-bottom:none; }
.activity-dot{ width:7px; height:7px; border-radius:50%; background: var(--accent-1); margin-top:7px; flex-shrink:0; }
.activity-time{ font-size:11.5px; color:var(--text-faint); font-family:var(--font-label); font-variant-numeric: tabular-nums; }

.filter-bar{ display:flex; flex-wrap:wrap; gap:10px; margin-bottom:20px; align-items:center; }
.filter-bar select, .filter-bar input{ width:auto; min-width:150px; }
/* "Only favourites" — a filter that reads and clicks like a button, and turns
   amber when it is on so the shortened list is never a surprise. */
.fav-filter{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer; user-select:none;
  padding:8px 15px; border-radius: var(--radius-pill); white-space:nowrap;
  border:1px solid var(--border-strong); background: var(--surface-strong);
  color: var(--text-muted); font-size:12.5px; font-weight:700;
  text-transform:none; letter-spacing:0; margin-bottom:0;
  transition: color var(--transition), border-color var(--transition),
              background var(--transition), transform var(--spring);
}
.fav-filter:hover{ color: var(--text); transform: translateY(-1px); }
.fav-filter input{ position:absolute; opacity:0; width:0; height:0; }
.fav-filter .star{ font-size:15px; line-height:1; filter:grayscale(1); opacity:.55; }
.fav-filter.on{
  color:#8a5a00; border-color:rgba(245,158,11,.55); background:rgba(245,158,11,.14);
}
.fav-filter.on .star{ filter:none; opacity:1; }
[data-theme="dark"] .fav-filter.on{ color:#f6c65b; }

.search-input-wrap{ position:relative; flex:1; min-width:220px; }
.search-input-wrap input{ padding-left:36px; }
.search-input-wrap .icon{ position:absolute; left:12px; top:50%; transform:translateY(-50%); color:var(--text-faint); }

.profile-header{ display:flex; gap:20px; align-items:center; flex-wrap:wrap; }
.profile-header .avatar{ width:72px; height:72px; font-size:26px; border-radius:16px; }
/* The portrait column of the profile header: the avatar, and under it the
   button that sends the photo through the white-background tool. */
.profile-photo{ display:flex; flex-direction:column; align-items:center; gap:8px; }
.profile-photo .btn{ width:auto; white-space:nowrap; font-size:11.5px; padding:6px 12px; }

/* The tool itself, as a dialog over the profile. The before/after pair is the
   whole point of it: the portrait is brought up to standard without anybody
   setting anything, and all that is left to do is look at the two of them and
   say yes. */
.photo-white-overlay{
  position:fixed; inset:0; z-index:80; padding:24px;
  display:flex; align-items:center; justify-content:center;
  background:rgba(10,10,14,.6); backdrop-filter:blur(4px);
}
.photo-white-overlay[hidden]{ display:none; }
.photo-white-box{
  background:var(--surface-solid); border-radius:var(--radius-lg); width:100%; max-width:560px;
  border:1px solid var(--border-strong); box-shadow:var(--shadow-lift);
  max-height:90vh; display:flex; flex-direction:column; overflow:hidden;
}
.photo-white-head{
  display:flex; align-items:center; justify-content:space-between;
  padding:16px 20px; border-bottom:1px solid var(--line);
}
.photo-white-head b{ font-size:15.5px; color:var(--text); }
.photo-white-head .modal-close{
  background:none; border:none; font-size:22px; line-height:1; color:var(--text-faint);
  cursor:pointer; padding:2px 8px; border-radius:var(--radius-sm); width:auto; box-shadow:none;
}
.photo-white-head .modal-close:hover{ background:rgba(118,118,128,.12); color:var(--text); }
.photo-white-body{ padding:18px 20px; overflow:auto; }
.photo-white-pair{ display:flex; gap:14px; justify-content:center; margin-bottom:16px; }
.photo-white-pair figure{ margin:0; text-align:center; }
.photo-white-pair figcaption{ font-size:11.5px; color:var(--text-faint); margin-top:6px; }
.photo-white-pair img{
  width:150px; aspect-ratio:3/4; object-fit:cover; border-radius:var(--radius-sm);
  border:1px solid var(--line); background:#fff; display:block;
}
.photo-white-note{ font-size:12.5px; color:var(--text-muted); line-height:1.55; margin-bottom:12px; }
.photo-white-foot{ display:flex; gap:10px; justify-content:flex-end; flex-wrap:wrap; }
.photo-white-foot .btn{ width:auto; }
.photo-white-busy{ opacity:.55; pointer-events:none; }
.tab-nav{ display:flex; gap:2px; border-bottom:1.5px solid var(--border-strong); margin-bottom:0; overflow-x:auto; }
.tab-nav button{
  background: var(--input-bg); border:1px solid var(--border); border-bottom:none; padding:11px 16px; font-weight:700; color:var(--text-muted); cursor:pointer;
  font-family: var(--font-body); font-size:13.5px; white-space:nowrap; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  position:relative; top:1.5px; transition: var(--transition);
}
.tab-nav button.active{ color: var(--accent-1); background: var(--surface-solid); border-color: var(--border-strong); border-bottom: 1.5px solid var(--surface-solid); }
.tab-panel{ display:none; border-radius: 0 var(--radius-lg) var(--radius-lg) var(--radius-lg); }
.tab-panel.active{ display:block; animation: fadein .3s ease; }

.info-grid{ display:grid; grid-template-columns: repeat(auto-fill, minmax(200px,1fr)); gap:16px; }
.info-item .info-label{ font-size:11px; color:var(--text-faint); text-transform:uppercase; letter-spacing:.08em; font-weight:700; font-family:var(--font-label); }
.info-item .info-value{ font-size:14.5px; margin-top:3px; font-weight:600; }

.doc-item{ display:flex; align-items:center; justify-content:space-between; padding:12px 16px; border:1px solid var(--border); border-radius: var(--radius-sm); margin-bottom:10px; background: var(--input-bg); transition: var(--transition); }
.doc-item:hover{ border-color: rgba(224,34,31,.3); }
.doc-item .doc-name{ display:flex; align-items:center; gap:10px; font-size:14px; font-weight:600; }

/* The rail runs down the centre of the icon column (32px wide, so x=16) and
   each event's own icon sits on it as a chip. A row of identical red dots said
   nothing about what happened; the emoji already differ, so they do the work
   and the chip stays neutral. */
.timeline{
  position:relative; padding-left:46px;
  /* --border-strong is white at 45%, which vanishes on the light theme's own
     near-white ground; the rail and the note's hairline need a colour that
     shows on both. */
  --hist-rail: rgba(0,0,0,.10);
}
[data-theme="dark"] .timeline{ --hist-rail: rgba(255,255,255,.13); }
.timeline::before{ content:''; position:absolute; left:15px; top:6px; bottom:6px; width:2px; background: var(--hist-rail); }
.timeline-item{ position:relative; padding-bottom:14px; }

.score-stars{ display:flex; gap:4px; }
.score-stars button{ background:none; border:none; font-size:19px; cursor:pointer; color: var(--border-strong); padding:0; transition: transform .15s ease; }
.score-stars button:hover{ transform: scale(1.2); }
.score-stars button.filled{ color: var(--accent-1); }
.score-stars label{ cursor:pointer; line-height:1; }
.score-stars .star{ display:inline-block; font-size:19px; color: var(--text-faint); opacity:.5; transition: color .12s ease, opacity .12s ease, transform .12s ease; }
.score-stars .star.filled{ opacity:1; }
.score-stars .star.filled{ color: var(--accent-1); }
.score-stars[data-role="manager"] .star.filled{ color:#2B5CA5; }
.score-stars label:hover .star{ transform: scale(1.2); }


.qr-box{ display:flex; align-items:center; justify-content:center; padding:14px; background:#fff; border-radius:var(--radius-md); border:1px solid var(--border); }

.flash-stack{ position: fixed; top:20px; right:20px; z-index:200; display:flex; flex-direction:column; gap:10px; max-width:340px; }
.flash{ padding:14px 17px; border-radius: var(--radius-sm); font-size:13.5px; font-weight:600; box-shadow: var(--shadow-lift); animation: slidein .3s var(--transition-slow); border:1px solid transparent; }
@keyframes slidein{ from{ transform: translateX(30px); opacity:0;} to{ transform:translateX(0); opacity:1;} }
.flash-success{ background:#1E8E5A; color:#fff; }
.flash-danger{ background:#C1121C; color:#fff; }
.flash-warning{ background:#B5751E; color:#fff; }
.flash-info{ background: var(--surface-solid); color:var(--text); border-color:var(--border-strong); }

.empty-state{ text-align:center; padding:56px 20px; color: var(--text-faint); }
.empty-state .icon{ font-size:38px; margin-bottom:12px; opacity:.5; }

.mobile-toggle{ display:none; }
.sidebar-backdrop{ display:none; }
.sidebar-close{ display:none; }

/* ---------- The panel on a phone ----------
   Open, it covers the ☰ that opened it — the button sits at the left of the
   topbar and the panel is painted over it. So it has to close by every other
   means a phone offers: the dimmed page behind it, a swipe back to the left,
   or tapping where you were going. Driven by `transform` rather than `left`,
   because a swipe follows the finger frame by frame and iOS only composites
   transforms on the GPU.                                                    */
@media (max-width: 880px){
  .sidebar{
    position: fixed; top:0; left:0; z-index:100;
    width: min(280px, 84vw);
    height: 100vh; height: 100dvh;        /* iOS: 100vh hides under the URL bar */
    background: var(--bg-elevated);
    transform: translateX(-102%);         /* -102%: the shadow goes off-screen too */
    transition: transform .28s cubic-bezier(.22,1,.36,1);
    /* The panel itself no longer scrolls — the menu inside it does. The logo
       and the account card hold their places while the sections run between
       them, so the way out of the panel and the way out of the account are
       both always on screen. */
    overflow: hidden;
    /* The notch must not eat the logo, nor the home strip the sign-out button. */
    padding-top: max(20px, env(safe-area-inset-top));
    padding-bottom: max(20px, env(safe-area-inset-bottom));
  }
  .sidebar.open{ transform: none; box-shadow: 0 0 46px rgba(0,0,0,.30); }
  /* While a finger is on it the transform is set per frame; animating it too
     would fight the drag and lag a frame behind. */
  .sidebar.dragging{ transition: none; }

  .sidebar-backdrop{
    display:block; position: fixed; inset:0; z-index:99;
    /* iOS scrolls the page behind an `overflow:hidden` body anyway; refusing
       the gesture on the backdrop is what actually holds it still. */
    touch-action: none;
    background: rgba(15,15,20,.42);
    -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
    opacity:0; pointer-events:none; transition: opacity .28s ease;
  }
  .sidebar-backdrop.show{ opacity:1; pointer-events:auto; }
  /* The way out that needs no button: a grab bar on the panel's edge, saying
     the thing can be pushed away with a thumb. Drawn on the backdrop, which
     never scrolls — on the panel itself it would slide off with the nav. It
     gets out of the way the moment a finger actually takes hold. */
  .sidebar-backdrop::before{
    content:''; position:absolute; top:50%; left: min(280px, 84vw);
    margin-left:7px; transform: translateY(-50%);
    width:5px; height:52px; border-radius:3px;
    background: rgba(255,255,255,.72);
    box-shadow: 0 1px 6px rgba(0,0,0,.28);
    transition: opacity .18s ease;
  }
  body.sidebar-dragging .sidebar-backdrop::before{ opacity:0; }
  /* The page behind must not scroll away under the open panel. */
  body.sidebar-open{ overflow:hidden; }

  /* Sits in the panel's own header, level with the logo. 40px keeps it inside
     Apple's 44pt tap target once the padding around it is counted. */
  .sidebar-close{
    display:flex; align-items:center; justify-content:center;
    margin-left:auto; flex-shrink:0;
    width:40px; height:40px; padding:0;
    border:1px solid var(--border-strong); border-radius:50%;
    background: var(--input-bg); color: var(--text);
    font-size:15px; line-height:1; cursor:pointer;
    -webkit-tap-highlight-color: transparent;
    /* Тап по ✕ — тап, а не начало жеста: без этого iOS ждёт двойного
       нажатия и отдаёт click на 300 мс позже, если отдаёт вообще. */
    touch-action: manipulation;
  }
  .sidebar-close:active{ background: var(--border); }

  .mobile-toggle{ display:flex; }
  .two-col{ grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce){
  .sidebar, .sidebar-backdrop{ transition: none; }
}

/* ---------- Tablet ---------- */
@media (max-width: 760px){
  body{ font-size:14.5px; }
  .navbar{ padding:12px 16px; margin:12px 12px 0; border-radius: var(--radius-md); }
  .nav-links{ display:none; }              /* links live in the hero CTAs on phones */
  .hero{ padding: 56px 18px 40px; }
  .section{ padding: 44px 18px; }
  .container-narrow{ padding: 0 16px; }
  .admin-content{ padding: 18px 16px 48px; }
  .topbar{ padding: 12px 16px; flex-wrap:wrap; gap:10px; }
  .topbar h1{ font-size:18px; }
  .card, .glass.card, .glass.auth-card, form.glass{ padding: 20px; }
  .partners-strip{ gap: 24px 32px; }
  /* Wide tables scroll inside their own box instead of stretching the page. */
  .table-wrap, .glass.card > table{ display:block; overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .flash-stack{ top:12px; right:12px; left:12px; max-width:none; }
}

/* ---------- Phone ---------- */
@media (max-width: 520px){
  .hero h1{ font-size: clamp(1.8rem, 8vw, 2.3rem); }
  .hero p.lead{ font-size:15.5px; }
  .hero-actions .btn{ width:100%; }
  .btn{ padding: 11px 18px; }
  .grid-3{ grid-template-columns: 1fr; }
  .stat-grid{ gap:12px; }   /* columns are set with the grid itself, above */
  .field-row{ grid-template-columns: 1fr; }
  .job-card{ flex-direction:column; align-items:flex-start; }
  .step-dots{ gap:4px; }
  .step-dot{ width:26px; height:26px; font-size:11.5px; }
  .photo-3x4{ gap:14px; }
  .photo-3x4-frame{ width:96px; }
  .auth-card{ padding: 28px 20px; }
  .lang-switch-btn .lang-code{ display:none; }   /* flag alone on narrow bars */
  .admin-content{ padding: 14px 12px 40px; }
  .partners-strip{ gap: 20px 24px; }
  .partner-logo, .partner-logo img{ max-width:120px; height:38px; max-height:38px; }
}

@keyframes fadein{ from{opacity:0; transform:translateY(6px);} to{opacity:1; transform:translateY(0);} }

@media (prefers-reduced-motion: reduce){
  *{ animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
  html{ scroll-behavior:auto; }
}

::-webkit-scrollbar{ width:9px; height:9px; }
::-webkit-scrollbar-thumb{ background: var(--border-strong); border-radius:999px; }
::-webkit-scrollbar-track{ background: transparent; }

/* ---------- Candidate skills test ---------- */
.test-head{ display:flex; justify-content:space-between; align-items:flex-start; gap:24px; flex-wrap:wrap; margin-bottom:18px; }
.test-meta{ display:flex; gap:14px; flex:none; }
.test-meta-item{
  text-align:center; padding:12px 18px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong); min-width:96px;
}
.test-meta-value{ display:block; font-size:20px; font-weight:800; color: var(--text); font-variant-numeric: tabular-nums; }
.test-meta-label{ display:block; font-size:11.5px; color: var(--text-faint); margin-top:2px; }
.test-timer-low{ color: var(--accent-1) !important; animation: blink 1s ease-in-out infinite; }

.test-progress{
  height:6px; border-radius:999px; background: var(--line);
  overflow:hidden; margin-bottom:6px; position:sticky; top:0; z-index:20;
}
.test-progress-fill{
  height:100%; width:0; border-radius:999px;
  background: linear-gradient(90deg, var(--accent-1), var(--accent-1-light));
  transition: width .3s var(--transition-slow);
}
.test-progress-text{
  font-size:12.5px; color: var(--text-faint); margin:0 0 18px;
  display:flex; justify-content:space-between; align-items:baseline; gap:12px;
}
.test-step-label{ font-weight:700; color: var(--text-muted); }

.test-q{ padding:22px 24px; margin-bottom:14px; }
.test-q.answered{ border-color: rgba(48,209,88,.45); }
.test-q-head{ display:flex; gap:12px; align-items:flex-start; margin-bottom:16px; }
.test-q-num{
  flex:none; width:28px; height:28px; border-radius:9px; font-size:12.5px; font-weight:800;
  display:flex; align-items:center; justify-content:center; color:#fff;
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1));
  box-shadow: 0 3px 8px rgba(224,34,31,.28);
}
.test-q-text{ margin:0; font-size:15.5px; line-height:1.5; font-weight:700; }
.test-options{ display:flex; flex-direction:column; gap:8px; }
.test-option{
  display:flex; align-items:center; gap:12px; cursor:pointer;
  padding:11px 14px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  font-size:14px; text-transform:none; letter-spacing:0; font-weight:500; color: var(--text);
  transition: border-color var(--transition), background var(--transition), transform var(--spring);
}
.test-option:hover{ border-color: var(--accent-1); transform: translateX(3px); }
.test-option input{ position:absolute; opacity:0; width:0; height:0; }
.test-option-key{
  flex:none; width:26px; height:26px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-size:12px; font-weight:800; color: var(--text-muted);
  border:1.5px solid var(--border-strong); background: var(--bg-elevated);
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.test-option:has(input:checked){ border-color: var(--accent-1); background: rgba(224,34,31,.07); }
.test-option:has(input:checked) .test-option-key{ background: var(--accent-1); border-color: var(--accent-1); color:#fff; }
.test-option-text{ line-height:1.45; }

/* Picture questions: several catalogue items are a photograph of a fitting
   and four names. The frame is plain white in both themes on purpose -- the
   photographs came off a white studio background, and a tinted card behind
   them reads as a border that is not there. */
.test-q-figure{
  margin:0 0 16px; padding:14px; border-radius: var(--radius-md);
  background:#fff; border:1px solid var(--line);
  display:flex; align-items:center; justify-content:center; min-height:150px;
}
.test-q-figure img{
  max-width:100%; max-height:320px; width:auto; height:auto;
  border-radius:8px; -webkit-user-drag:none; user-select:none;
}

/* Cards are hidden by JS one at a time; the one on screen arrives rather
   than appears, which is what makes a 98-question paper feel like a stack
   of cards instead of a form that keeps reloading. */
.test-q[hidden]{ display:none; }
.test-q:not([hidden]){ animation: testCardIn .34s cubic-bezier(.16,1,.3,1) both; }
@keyframes testCardIn{
  from{ opacity:0; transform: translateY(14px) scale(.985); }
  to{ opacity:1; transform:none; }
}

.test-nav{ display:flex; gap:10px; margin-top:6px; }
.test-nav .btn{ flex:1; }
.test-nav .btn:disabled{ opacity:.4; cursor:default; }

/* The screen after the last card: what is still blank, and one way in. */
.test-review{ padding:26px 24px; text-align:center; }
.test-review[hidden]{ display:none; }
.test-review-icon{ display:block; font-size:38px; line-height:1; margin-bottom:10px; }
.test-review h3{ margin:0 0 8px; font-size:19px; }
.test-review p{ margin:0 0 16px; color: var(--text-muted); font-size:14px; }
.test-review p.is-warning{ color: var(--accent-warn); font-weight:600; }
.test-review-grid{ display:flex; flex-wrap:wrap; gap:6px; justify-content:center; }
.test-review-chip{
  width:34px; height:34px; border-radius:10px; cursor:pointer;
  font-size:12.5px; font-weight:700; font-variant-numeric: tabular-nums;
  color: var(--accent-warn); background: rgba(255,159,10,.12);
  border:1px solid rgba(255,159,10,.4);
  transition: transform var(--spring), background var(--transition);
}
.test-review-chip:hover{ transform: translateY(-2px); }
.test-review-chip.is-done{
  color: var(--text-muted); background: var(--surface-strong);
  border-color: var(--border-strong);
}

/* Nothing on the test page is worth selecting, and what cannot be selected
   cannot be dragged into a search box in the next tab either. The options
   stay selectable-free too; the radio is the only thing to hit. */
body.proctor-noselect .test-q,
body.proctor-noselect .test-review{
  -webkit-user-select:none; user-select:none;
}

/* ---------- The three-stage ladder ---------- */
.stage-rail{
  display:flex; align-items:center; gap:6px; margin:0 0 16px;
  padding:12px 16px; border-radius: var(--radius-pill);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  overflow-x:auto; scrollbar-width:none;
}
.stage-rail::-webkit-scrollbar{ display:none; }
.stage-step{ display:flex; align-items:center; gap:8px; flex:none; }
.stage-dot{
  width:24px; height:24px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center;
  font-size:11.5px; font-weight:800;
  color: var(--text-faint); background: var(--bg-elevated);
  border:1.5px solid var(--border-strong);
  transition: background var(--transition), color var(--transition);
}
.stage-name{ font-size:12.5px; font-weight:600; color: var(--text-faint); white-space:nowrap; }
.stage-step.is-done .stage-dot{
  background: var(--accent-4); border-color: var(--accent-4); color:#fff;
}
.stage-step.is-done .stage-name{ color: var(--text-muted); }
.stage-step.is-now .stage-dot{
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1));
  border-color: var(--accent-1); color:#fff;
  box-shadow: 0 3px 10px rgba(224,34,31,.32);
}
.stage-step.is-now .stage-name{ color: var(--text); font-weight:700; }
.stage-link{ flex:1; min-width:14px; height:2px; border-radius:2px; background: var(--line); }
.stage-link.is-done{ background: var(--accent-4); }

/* ---------- Score dial, shared by both end screens ---------- */
.stage-result{ text-align:center; }
.stage-score{ position:relative; width:132px; height:132px; margin:0 auto 18px; }
.stage-score svg{ width:100%; height:100%; transform: rotate(-90deg); }
.stage-score circle{ fill:none; stroke-width:9; stroke-linecap:round; }
.stage-score-track{ stroke: var(--chart-track); }
.stage-score-arc{
  stroke: var(--accent-warn);
  stroke-dasharray: 326.7;                       /* 2 * pi * 52 */
  stroke-dashoffset: calc(326.7 - 326.7 * var(--pct) / 100);
  animation: stageArc 1s cubic-bezier(.16,1,.3,1) both;
}
@keyframes stageArc{ from{ stroke-dashoffset: 326.7; } }
.stage-result.is-passed .stage-score-arc{ stroke: var(--accent-4); }
.stage-result.is-failed .stage-score-arc{ stroke: var(--accent-1); }
.stage-score-mid{
  position:absolute; inset:0; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:2px;
}
.stage-score-pct{ font-size:30px; font-weight:800; font-variant-numeric: tabular-nums; }
.stage-score-raw{ font-size:12.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; }

.stage-next{
  margin-top:18px; padding:14px 16px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  display:flex; flex-direction:column; gap:3px; text-align:left;
}
.stage-next-eyebrow{
  font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color: var(--accent-1);
}
.stage-next strong{ font-size:15.5px; }
.stage-next-meta{ font-size:12.5px; color: var(--text-faint); }

.proctor-warn-left{
  margin:0 0 14px !important; font-size:13px; font-weight:700;
  color: var(--accent-warn) !important;
}
.proctor-warn-left.is-last{ color: var(--accent-1) !important; }
.proctor-rule-hard{ font-weight:700; color: var(--accent-1); }

/* ---------- Stage tags in the admin tables ---------- */
.stage-tag{
  display:inline-block; padding:3px 10px; border-radius: var(--radius-pill);
  font-size:11.5px; font-weight:700; white-space:nowrap;
  border:1px solid var(--border-strong); background: var(--surface-strong);
  color: var(--text-muted);
}
.stage-tag-trial{ color:#0B6BCB; background: rgba(11,107,203,.10); border-color: rgba(11,107,203,.28); }
.stage-tag-final{ color:#B31A17; background: rgba(224,34,31,.10); border-color: rgba(224,34,31,.28); }
.stage-tag-retake{ color:#9A6100; background: rgba(255,159,10,.12); border-color: rgba(255,159,10,.32); }
.cell-sub{ display:block; font-size:11.5px; color: var(--text-faint); }

/* ---------- The next exam, on the candidate's card ----------
   A failed trial is not the end of the hiring, so the card carries the rung
   that follows it and the address to send. The link is the candidate's own —
   it opens whatever stage their results say is due — so it is shown in full
   and copyable rather than hidden behind a button. */
/* Handing a candidate a named test. One line, and it sits directly above the
   card that shows the link it produces, so the answer appears where the
   question was asked. The picker takes the slack: on a narrow screen the row
   wraps rather than squeezing the button off the card. */
.send-test{ display:flex; align-items:center; flex-wrap:wrap; gap:10px; margin-bottom:14px; }
.send-test-label{ font-weight:700; font-size:14px; }
.send-test-pick{ flex:1; min-width:240px; width:auto; }

.next-exam{ margin-bottom:22px; }
.next-exam-head{ display:flex; align-items:center; flex-wrap:wrap; gap:10px; }
.next-exam-eyebrow{
  font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color: var(--accent-1);
}
.next-exam-head b{ font-size:15px; }
.next-exam-meta{ font-size:12.5px; color: var(--text-faint); }
.next-exam-row{
  display:flex; align-items:center; flex-wrap:wrap; gap:8px; margin-top:12px;
}
.next-exam-url{
  flex:1; min-width:220px; font-size:12px; padding:8px 10px;
  border-radius: var(--radius-md); background: var(--surface-strong);
  border:1px solid var(--border-strong); color: var(--text-muted);
  overflow-wrap:anywhere;
}
.next-exam-note{ margin:10px 0 0; font-size:12px; color: var(--text-faint); }

.result-pass{ color: var(--accent-4); }
.result-fail{ color: var(--accent-1); }
.test-answer-img{ display:block; margin:8px 0; max-height:120px; border-radius:8px; background:#fff; padding:6px; border:1px solid var(--line); }

/* A question in the editor that nobody has marked an answer for. It stays in
   the bank and stays visible -- it is simply never served -- so the editor
   has to make it findable rather than hide it. */
.question-box.is-unanswered{ border-color: rgba(255,159,10,.55); }
.question-flag{
  display:inline-flex; align-items:center; gap:6px; margin-bottom:10px;
  padding:4px 10px; border-radius: var(--radius-pill);
  font-size:11.5px; font-weight:700;
  color: var(--accent-warn); background: rgba(255,159,10,.12);
  border:1px solid rgba(255,159,10,.35);
}
.question-figure{
  margin:0 0 12px; padding:10px; border-radius: var(--radius-sm);
  background:#fff; border:1px solid var(--line);
  display:inline-flex; align-items:center; justify-content:center;
}
.question-figure img{ max-height:150px; max-width:100%; border-radius:6px; }
.question-toolbar{
  display:flex; gap:8px; align-items:center; flex-wrap:wrap;
  margin-bottom:14px; position:sticky; top:0; z-index:15;
  padding:10px 14px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  backdrop-filter: blur(14px);
}
.question-toolbar .count{ margin-left:auto; font-size:12.5px; color: var(--text-faint); }

@media (max-width: 520px){
  .test-head{ flex-direction:column; }
  .test-meta{ width:100%; }
  .test-meta-item{ flex:1; min-width:0; padding:12px 10px; }
  .test-q{ padding:18px 16px; }
  .stage-name{ display:none; }
  .stage-rail{ padding:10px 14px; }
  .test-q-figure{ padding:10px; min-height:120px; }
}

/* ---------- "+" repeatable blocks in the applicant form ---------- */
.repeat-blocks{ display:flex; flex-direction:column; gap:12px; margin:4px 0 12px; }
.repeat-block{
  position:relative; padding:16px 44px 16px 16px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  box-shadow: var(--shadow-soft);
  animation: cardin .3s cubic-bezier(.16,1,.3,1) both;
}
.repeat-block:focus-within{ border-color: var(--accent-1); }
.repeat-grid{ display:grid; grid-template-columns: repeat(auto-fit, minmax(150px,1fr)); gap:12px; }
.repeat-field{ display:flex; flex-direction:column; gap:5px; margin:0; }
.repeat-field span{
  font-size:11.5px; font-weight:700; color: var(--text-muted);
  text-transform:uppercase; letter-spacing:.03em;
}
.repeat-remove{
  position:absolute; top:12px; right:12px;
  width:28px; height:28px; border-radius:50%; border:1px solid var(--border-strong);
  background:transparent; color: var(--text-faint); font-size:18px; line-height:1; cursor:pointer;
  transition: background var(--transition), color var(--transition), transform var(--spring);
}
.repeat-remove:hover{ background: var(--accent-3); border-color: var(--accent-3); color:#fff; transform: scale(1.1); }
.repeat-add{ margin-bottom:8px; }

/* Skills-test outcome shown on the candidate profile. */
.test-result-strip{ display:flex; gap:12px; flex-wrap:wrap; margin-top:18px; }
.test-result{
  display:flex; align-items:center; gap:14px;
  padding:12px 18px 12px 14px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  box-shadow: var(--shadow-soft);
}
.test-result-score{ font-size:22px; font-weight:800; font-variant-numeric: tabular-nums; line-height:1; }
.test-result-score span{ font-size:14px; font-weight:600; color: var(--text-faint); }
.test-result-title{ font-weight:700; font-size:14px; }
.test-result-meta{ font-size:12px; color: var(--text-faint); margin-top:2px; }
.test-result-good{ border-color: rgba(48,209,88,.5); }
.test-result-good .test-result-score{ color: var(--accent-4); }
.test-result-mid{ border-color: rgba(255,159,10,.5); }
.test-result-mid .test-result-score{ color: var(--accent-warn); }
.test-result-low{ border-color: rgba(224,34,31,.45); }
.test-result-low .test-result-score{ color: var(--accent-1); }

/* Per-question breakdown under a test score (collapsed by default). */
.test-result-strip{ flex-direction:column; }
.test-result{ width:100%; }
.test-answers{ display:none; flex-direction:column; gap:8px; width:100%; margin-top:-4px; }
.test-result.open + .test-answers{ display:flex; animation: cardin .3s cubic-bezier(.16,1,.3,1) both; }
.test-answer{
  display:flex; gap:12px; align-items:flex-start;
  padding:11px 14px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
}
.test-answer.ok{ border-left:3px solid var(--accent-4); }
.test-answer.bad{ border-left:3px solid var(--accent-1); }
.test-answer-num{
  flex:none; width:24px; height:24px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-size:11.5px; font-weight:800; color: var(--text-muted);
  background: var(--bg-elevated); border:1px solid var(--border-strong);
}
.test-answer-q{ font-size:13.5px; font-weight:600; line-height:1.45; }
.test-answer-given{ font-size:12.5px; color: var(--text-muted); margin-top:3px; }
.test-answer.bad .test-answer-given{ color: var(--accent-1); }
.test-answer-right{ font-size:12.5px; color: var(--accent-4); margin-top:2px; }

/* ---------- Test builder ---------- */
.question-box{ position:relative; padding:20px 46px 20px 20px; margin-bottom:12px; }
.question-num{
  position:absolute; top:18px; left:-11px;
  width:26px; height:26px; border-radius:9px; font-size:12px; font-weight:800; color:#fff;
  display:flex; align-items:center; justify-content:center;
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1));
  box-shadow: 0 3px 8px rgba(224,34,31,.3);
}
.question-options{ display:flex; flex-direction:column; gap:8px; }
.question-option{
  display:flex; align-items:center; gap:10px; margin:0;
  text-transform:none; letter-spacing:0; font-weight:500;
}
.question-option input[type="radio"]{ position:absolute; opacity:0; width:0; height:0; }
.question-option-key{
  flex:none; width:30px; height:30px; border-radius:50%; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  font-size:12.5px; font-weight:800; color: var(--text-muted);
  border:1.5px solid var(--border-strong); background: var(--bg-elevated);
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.question-option:has(input:checked) .question-option-key{
  background: var(--accent-4); border-color: var(--accent-4); color:#fff;
}
.question-option input[type="text"]{ flex:1; }

/* ---------- Ready-made message to a candidate ---------- */
.msg-panel{
  margin-top:18px; padding:14px 16px; border-radius: var(--radius-md);
  background: var(--surface-strong); border:1px solid var(--border-strong);
}
.msg-head{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.msg-head strong{ font-size:14px; }
.msg-select{ width:auto; min-width:190px; flex:1; max-width:300px; }
.msg-body{ display:none; margin-top:12px; }
.msg-panel.open .msg-body{ display:block; animation: cardin .28s cubic-bezier(.16,1,.3,1) both; }
.msg-body textarea{ resize:vertical; font-size:13.5px; line-height:1.6; }
.msg-actions{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:10px; }
.msg-hint{ font-size:12.5px; color: var(--accent-1); }
/* Where to come, and when — filled in above the message rather than inside it,
   so the invitation is ready to send instead of ready to edit. Both are hidden
   for the templates that name neither. */
.msg-fields{ display:flex; gap:12px; flex-wrap:wrap; margin-bottom:12px; }
.msg-field{ display:flex; flex-direction:column; gap:5px; flex:1; min-width:220px; }
.msg-field[hidden]{ display:none; }
.msg-field > span{
  font-size:11.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  color: var(--text-faint);
}
.msg-field select, .msg-field input{ width:100%; }

/* Settings > Branches and interview places. One box per place, laid out the way
   the message reads it: what it is called, then where and who. */
.site-box{
  border:1px solid var(--border); border-radius: var(--radius-md);
  padding:14px; margin-bottom:12px; background: var(--surface);
}
.site-box-head{ display:flex; gap:8px; align-items:center; margin-bottom:10px; }
.site-box-head .site-label{ flex:1; font-weight:700; }
.site-box-remove{
  flex:none; width:30px; height:30px; border-radius:50%; cursor:pointer;
  border:1px solid var(--border-strong); background:transparent;
  color: var(--text-muted); font-size:18px; line-height:1;
}
.site-box-remove:hover{ border-color: var(--accent-3); color: var(--accent-3); }
.site-box-grid{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.site-box-grid .site-wide{ grid-column:1 / -1; }
.site-box-grid label{ display:flex; flex-direction:column; gap:4px; }
.site-box-grid label > span{
  font-size:11.5px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  color: var(--text-faint);
}
@media (max-width: 640px){ .site-box-grid{ grid-template-columns:1fr; } }

/* Language tabs above the open-positions editor. */
.lang-tabs{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:12px; }
.lang-tab{
  padding:7px 14px; border-radius: var(--radius-pill); cursor:pointer;
  font-size:12.5px; font-weight:700; color: var(--text-muted);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  transition: background var(--transition), color var(--transition), transform var(--spring);
}
.lang-tab:hover{ transform: translateY(-1px); color: var(--text); }
.lang-tab.active{
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1));
  border-color: transparent; color:#fff; box-shadow: 0 4px 12px rgba(224,34,31,.3);
}

/* ---------- Site texts editor (Settings) ---------- */
/* One collapsible section per part of the landing page — 50-odd fields per
   language only work if the page can be scanned by section first. */
.st-group{
  border:1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface-strong); margin-bottom:10px; overflow:hidden;
}
.st-group > summary{
  display:flex; align-items:center; gap:8px; cursor:pointer; list-style:none;
  padding:11px 14px; font-size:12px; font-weight:800; letter-spacing:.07em;
  text-transform:uppercase; color: var(--text-muted);
  transition: color var(--transition), background var(--transition);
}
.st-group > summary::-webkit-details-marker{ display:none; }
.st-group > summary::before{
  content:'›'; font-size:16px; line-height:1; color: var(--text-faint);
  transition: transform var(--spring);
}
.st-group[open] > summary::before{ transform: rotate(90deg); }
.st-group > summary:hover{ color: var(--text); background: var(--glass); }
.st-group[open] > summary{ border-bottom:1px solid var(--border); }
.st-group > .st-field{ margin:12px 14px; }
.st-field label{ display:flex; align-items:center; gap:8px; margin-bottom:5px; }
/* The shipped wording names the field, so it is set as a quiet caption rather
   than a shouty uppercase label repeating the value in the input below. */
.st-label{
  flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:11.5px; font-weight:500; letter-spacing:0; text-transform:none;
  color: var(--text-faint);
}
.st-badge{
  flex:none; font-size:10.5px; font-weight:700; letter-spacing:.04em;
  padding:2px 8px; border-radius: var(--radius-pill);
  background: rgba(224,34,31,.12); color: var(--accent-1);
}
.st-reset{
  flex:none; width:24px; height:24px; padding:0; border-radius:50%; cursor:pointer;
  border:1px solid var(--border-strong); background: var(--surface-strong);
  color: var(--text-muted); font-size:13px; line-height:1;
  transition: color var(--transition), transform var(--spring);
}
.st-reset:hover{ color: var(--accent-1); transform: rotate(-45deg); }

/* Favourite star in the candidate list — a real button with a comfortable
   click target, so the clickable row can't steal the click. */
.fav-star{
  width:34px; height:34px; border-radius:50%; border:none; cursor:pointer;
  background:transparent; font-size:17px; line-height:1; padding:0;
  display:flex; align-items:center; justify-content:center;
  filter: grayscale(1); opacity:.45;
  transition: filter var(--transition), opacity var(--transition),
              transform var(--spring), background var(--transition);
}
.fav-star:hover{ background: var(--surface-strong); opacity:.9; transform: scale(1.15); }
.fav-star:active{ transform: scale(.9); }
.fav-star.on{ filter:none; opacity:1; }
.fav-star:disabled{ opacity:.3; cursor:default; }

/* ---------- Mission statement on the landing page ---------- */
.mission-card{
  max-width:860px; margin:0 auto; padding:38px 42px; position:relative;
  animation: cardin .6s cubic-bezier(.16,1,.3,1) both;
}
.mission-card p{ font-size:15.5px; line-height:1.8; margin:0 0 16px; }
.mission-card p:last-child{ margin-bottom:0; }
.mission-lead{
  color: var(--text) !important; font-weight:600;
  padding-left:16px; border-left:3px solid var(--accent-1);
}
.mission-quote{
  position:absolute; top:6px; left:22px; font-size:78px; line-height:1;
  color: var(--accent-1); opacity:.14; font-family: Georgia, serif; pointer-events:none;
}
@media (max-width: 520px){ .mission-card{ padding:26px 20px; } .mission-quote{ display:none; } }

/* ==========================================================================
   Motion layer — the pieces the card animation didn't cover: table rows,
   sidebar links, tabs, badges and the landing sections.
   ========================================================================== */

/* Table rows arrive one after another instead of all at once. */
tbody tr{ animation: rowin .38s cubic-bezier(.16,1,.3,1) both; }
tbody tr:nth-child(1){ animation-delay:.02s; }  tbody tr:nth-child(2){ animation-delay:.05s; }
tbody tr:nth-child(3){ animation-delay:.08s; }  tbody tr:nth-child(4){ animation-delay:.11s; }
tbody tr:nth-child(5){ animation-delay:.14s; }  tbody tr:nth-child(6){ animation-delay:.17s; }
tbody tr:nth-child(7){ animation-delay:.20s; }  tbody tr:nth-child(8){ animation-delay:.23s; }
tbody tr:nth-child(9){ animation-delay:.26s; }  tbody tr:nth-child(n+10){ animation-delay:.29s; }
/* Rows past the first screenful do not animate, because nobody can see them
   do it: the cascade is finished in 0.29 s and row 31 is below the fold the
   whole time. On the staff register — 1313 rows — the rule as written started
   1313 animations at once, each one its own compositing layer, before the page
   would scroll. The look is identical; what is dropped is work done off
   screen. */
tbody tr:nth-child(n+31){ animation: none; }
@keyframes rowin{ from{ opacity:0; transform: translateY(8px);} to{ opacity:1; transform: translateY(0);} }

.row-link{ transition: background var(--transition), transform var(--transition); }
.row-link:hover{ background: var(--surface-strong); }

/* Sidebar links slide in on load and nudge right on hover. */
.side-nav a{
  transition: background var(--transition), color var(--transition),
              transform var(--spring), padding-left var(--transition);
  animation: navin .4s cubic-bezier(.16,1,.3,1) both;
}
.side-nav a:nth-of-type(1){ animation-delay:.04s; } .side-nav a:nth-of-type(2){ animation-delay:.08s; }
.side-nav a:nth-of-type(3){ animation-delay:.12s; } .side-nav a:nth-of-type(4){ animation-delay:.16s; }
.side-nav a:nth-of-type(5){ animation-delay:.20s; } .side-nav a:nth-of-type(6){ animation-delay:.24s; }
.side-nav a:nth-of-type(7){ animation-delay:.28s; } .side-nav a:nth-of-type(8){ animation-delay:.32s; }
@keyframes navin{ from{ opacity:0; transform: translateX(-12px);} to{ opacity:1; transform: translateX(0);} }
.side-nav a:hover{ transform: translateX(3px); }
.side-nav a .icon{ transition: transform var(--spring); display:inline-block; }
.side-nav a:hover .icon{ transform: scale(1.2) rotate(-6deg); }

/* Tabs and their panels. */
.tab-nav button{ transition: color var(--transition), border-color var(--transition), transform var(--spring); }
.tab-nav button:hover{ transform: translateY(-1px); }
.tab-panel.active{ animation: cardin .35s cubic-bezier(.16,1,.3,1) both; }

/* Badges and chips pop slightly on hover. */
.badge{ transition: transform var(--spring), box-shadow var(--transition); }
.badge:hover{ transform: scale(1.06); }

/* Landing sections fade up as they enter the viewport (see main.js). */
.section{ opacity:0; transform: translateY(24px);
  transition: opacity .6s cubic-bezier(.16,1,.3,1), transform .6s cubic-bezier(.16,1,.3,1); }
.section.in-view, .no-js .section{ opacity:1; transform: none; }

/* Flash messages slide in from the right. */
.flash{ animation: flashin .4s cubic-bezier(.34,1.56,.64,1) both; }
@keyframes flashin{ from{ opacity:0; transform: translateX(28px);} to{ opacity:1; transform: translateX(0);} }

/* Inputs settle in with the form. */
.field{ animation: cardin .4s cubic-bezier(.16,1,.3,1) both; }

/* ---------- Dashboard ----------
   The two feeds arrive item by item, the way they were written, instead of
   landing as one block of text. */
.activity-item{ animation: rowin .4s cubic-bezier(.16,1,.3,1) both; }
.activity-item:nth-child(1){ animation-delay:.06s; } .activity-item:nth-child(2){ animation-delay:.11s; }
.activity-item:nth-child(3){ animation-delay:.16s; } .activity-item:nth-child(4){ animation-delay:.21s; }
.activity-item:nth-child(5){ animation-delay:.26s; } .activity-item:nth-child(6){ animation-delay:.31s; }
.activity-item:nth-child(7){ animation-delay:.36s; } .activity-item:nth-child(n+8){ animation-delay:.41s; }
/* Only the newest entry keeps a pulse — a whole column of blinking dots is
   noise, one is a heartbeat. */
.activity-item:first-child .activity-dot{ animation: dotPulse 2.6s ease-out infinite; }
@keyframes dotPulse{
  0%,100%{ box-shadow: 0 0 0 0 rgba(224,34,31,.45); }
  60%    { box-shadow: 0 0 0 6px rgba(224,34,31,0); }
}
.activity-item{ transition: background var(--transition); border-radius: var(--radius-sm); }
.activity-item:hover{ background: var(--input-bg); }

/* A light sweeps across each stat card as it arrives, once. */
.stat-card::after{
  content:''; position:absolute; inset:0; pointer-events:none; border-radius:inherit;
  background: linear-gradient(105deg, transparent 42%, rgba(255,255,255,.45) 50%, transparent 58%);
  transform: translateX(-120%);
  animation: statSheen 1.1s cubic-bezier(.16,1,.3,1) both;
}
/* In step with the counters in main.js, which start 80ms apart. */
.stat-card:nth-child(1)::after{ animation-delay:.26s; } .stat-card:nth-child(2)::after{ animation-delay:.34s; }
.stat-card:nth-child(3)::after{ animation-delay:.42s; } .stat-card:nth-child(4)::after{ animation-delay:.50s; }
.stat-card:nth-child(5)::after{ animation-delay:.58s; } .stat-card:nth-child(6)::after{ animation-delay:.66s; }
.stat-card:nth-child(n+7)::after{ animation-delay:.74s; }
@keyframes statSheen{ to{ transform: translateX(120%); } }
[data-theme="dark"] .stat-card::after{
  background: linear-gradient(105deg, transparent 42%, rgba(255,255,255,.14) 50%, transparent 58%);
}
/* The count-up needs a fixed width or the card twitches as digits are added. */
.stat-card .stat-value{ font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce){
  tbody tr, .side-nav a, .field, .flash, .tab-panel.active,
  .activity-item, .activity-item:first-child .activity-dot{ animation: none !important; }
  .stat-card::after{ display:none; }
  .section{ opacity:1; transform:none; transition:none; }
  .help-fab{ animation: none !important; }
}

/* ==========================================================================
   Landing motion layer
   The page is a recruiting pitch, so it is meant to feel alive: things arrive
   rather than appear. Everything here is opt-in through classes main.js adds,
   which means a browser with JS off still gets the fully readable page — and
   the whole layer is switched off under prefers-reduced-motion at the bottom.
   ========================================================================== */

/* ---------- Scroll progress ---------- */
.scroll-progress{
  position:fixed; top:0; left:0; height:3px; width:100%; z-index:300;
  transform: scaleX(0); transform-origin:left;
  background: linear-gradient(90deg, var(--accent-1), var(--accent-1-light), var(--accent-warn));
  pointer-events:none;
}

/* ---------- Navbar reacts to scrolling ---------- */
.navbar{ transition: padding var(--transition-slow), box-shadow var(--transition-slow),
                     background var(--transition-slow), transform var(--transition-slow); }
.navbar.scrolled{ box-shadow: var(--shadow-lift); background: var(--surface-strong); }
.navbar .brand-logo{ transition: transform var(--transition-slow); }
.navbar.scrolled .brand-logo{ transform: scale(.92); }

/* ---------- Per-item reveal ----------
   The section fades up as a block; its children then arrive one after another
   on a delay main.js writes into --d. Staggering the children is what turns a
   single fade into something that reads as choreography. */
.reveal-item{
  opacity:0; transform: translateY(22px);
  transition: opacity .55s cubic-bezier(.16,1,.3,1) var(--d, 0s),
              transform .55s cubic-bezier(.16,1,.3,1) var(--d, 0s);
}
.reveal-item.in-view, .no-js .reveal-item{ opacity:1; transform:none; }
/* Cards slide in from alternating sides, so a long list never reads as one
   uniform column of identical fades. */
.reveal-item.from-left{ transform: translateX(-26px); }
.reveal-item.from-right{ transform: translateX(26px); }
.reveal-item.from-left.in-view, .reveal-item.from-right.in-view{ transform:none; }
.reveal-item.zoom-in{ transform: scale(.9); }
.reveal-item.zoom-in.in-view{ transform:none; }
/* For anything that carries an idle animation of its own: the entrance may
   only touch opacity, or the keyframes would fight the reveal transform. */
.reveal-item.fade-only, .reveal-item.fade-only.in-view{ transform:none; }

/* ---------- Hero: word-by-word title ---------- */
.hero h1 .word{
  display:inline-block; opacity:0; transform: translateY(28px) rotate(4deg);
  animation: wordIn .62s cubic-bezier(.16,1,.3,1) forwards; animation-delay: var(--d, 0s);
}
@keyframes wordIn{ to{ opacity:1; transform:none; } }

/* The rest of the hero follows the title in. */
.hero .eyebrow{ animation: heroPiece .6s cubic-bezier(.16,1,.3,1) both; }
.hero p.lead{ animation: heroPiece .6s cubic-bezier(.16,1,.3,1) .34s both; }
.hero-actions{ animation: heroPiece .6s cubic-bezier(.16,1,.3,1) .46s both; }
@keyframes heroPiece{ from{ opacity:0; transform: translateY(16px);} to{ opacity:1; transform:none;} }

/* A slow shine crossing the badge, so the "we are hiring" pill keeps catching
   the eye without ever moving out of place. */
.eyebrow{ position:relative; overflow:hidden; }
.eyebrow::after{
  content:''; position:absolute; inset:0; pointer-events:none;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.75) 50%, transparent 62%);
  transform: translateX(-120%); animation: shine 4.6s ease-in-out 1.6s infinite;
}
@keyframes shine{ 0%{ transform: translateX(-120%);} 26%,100%{ transform: translateX(120%);} }

/* ---------- Job cards ---------- */
.job-card{ position:relative; overflow:hidden; }
/* A highlight sweeps across on hover — the card reacts to the cursor instead
   of only changing colour. */
.job-card::after{
  content:''; position:absolute; inset:0; pointer-events:none;
  background: linear-gradient(105deg, transparent 40%, rgba(255,255,255,.5) 50%, transparent 60%);
  transform: translateX(-110%); transition: transform .75s cubic-bezier(.16,1,.3,1);
}
.job-card:hover::after{ transform: translateX(110%); }
.job-card{ transition: transform var(--spring), box-shadow var(--transition), border-color var(--transition); }
.job-card:hover{ transform: translateY(-3px) scale(1.012); box-shadow: var(--shadow-lift); }
.job-card h4{ transition: color var(--transition); }
.job-card:hover h4{ color: var(--accent-1); }
.job-card .badge{ transition: transform var(--spring); }
.job-card:hover .badge{ transform: scale(1.1) rotate(-3deg); }

/* ---------- Benefits: the icons keep breathing ---------- */
.benefit-cell .icon{ animation: iconFloat 4.4s ease-in-out infinite; animation-delay: var(--d, 0s); }
@keyframes iconFloat{ 0%,100%{ transform: translateY(0);} 50%{ transform: translateY(-5px);} }
.benefit-cell:hover .icon{ animation-play-state: paused; }

/* ---------- Stat cards ---------- */
.stat-value{ font-variant-numeric: tabular-nums; }
.benefit-card{ transition: transform var(--spring), box-shadow var(--transition); }
.benefit-card:hover{ transform: translateY(-4px); box-shadow: var(--shadow-lift); }

/* ---------- Partner logos drift ---------- */
.partner-logo{ animation: logoBob 5.5s ease-in-out infinite; animation-delay: var(--d, 0s); }
@keyframes logoBob{ 0%,100%{ transform: translateY(0);} 50%{ transform: translateY(-6px);} }

/* ---------- Buttons lean toward the cursor ---------- */
.btn{ will-change: transform; }

/* ---------- Section headings ---------- */
.section-title .kicker{
  display:inline-block;
  background: linear-gradient(90deg, var(--accent-1), var(--accent-warn), var(--accent-1));
  background-size: 220% 100%;
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent;
  animation: kickerFlow 5s linear infinite;
}
@keyframes kickerFlow{ from{ background-position: 0% 0;} to{ background-position: 220% 0;} }

/* Everything above is decoration. Someone who asked their OS for less motion
   gets the same page, still and complete. */
@media (prefers-reduced-motion: reduce){
  .scroll-progress{ display:none; }
  .reveal-item, .reveal-item.from-left, .reveal-item.from-right, .reveal-item.zoom-in{
    opacity:1 !important; transform:none !important; transition:none !important;
  }
  .hero h1 .word{ opacity:1 !important; transform:none !important; animation:none !important; }
  .hero .eyebrow, .hero p.lead, .hero-actions,
  .eyebrow::after, .benefit-cell .icon, .partner-logo, .section-title .kicker{
    animation:none !important;
  }
  .section-title .kicker{ -webkit-text-fill-color: var(--accent-1); color: var(--accent-1); }
  .job-card::after{ display:none; }
}

/* ==========================================================================
   "Seyco Help" chat bubble (templates/_seyco_help.html)
   The landing page's own copy of the assistant HR uses in the Candidate
   Database tool. Same shape as the one in that tool, rebuilt on the shared
   tokens above so it inherits the site's glass, radii and both themes.
   ========================================================================== */
.help-fab{
  position:fixed; bottom:24px; right:24px; z-index:200;
  width:58px; height:58px; border-radius:50%; border:none; cursor:pointer;
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1));
  color:#fff; display:flex; align-items:center; justify-content:center;
  box-shadow: var(--shadow-red), 0 4px 12px rgba(0,0,0,.15);
  transition: transform var(--spring), box-shadow var(--transition);
  animation: helpFabPulse 2.6s ease-in-out infinite;
}
.help-fab:hover{ transform: scale(1.08); }
.help-fab:active{ transform: scale(.96); }
/* A ring that expands and fades — the bubble has to be noticed once without
   ever moving, since it sits on top of the page's own scroll animations. */
@keyframes helpFabPulse{
  0%,100%{ box-shadow: var(--shadow-red), 0 0 0 0 rgba(224,34,31,.35); }
  50%    { box-shadow: var(--shadow-red), 0 0 0 10px rgba(224,34,31,0); }
}
.help-fab-icon-close{ display:none; }
.help-fab.open .help-fab-icon-chat{ display:none; }
.help-fab.open .help-fab-icon-close{ display:block; }

.help-window{
  position:fixed; bottom:94px; right:24px; z-index:200;
  width:340px; max-width:calc(100vw - 32px);
  height:460px; max-height:calc(100vh - 130px);
  background: var(--surface-strong); border:1px solid var(--border-strong);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lift);
  backdrop-filter: blur(30px) saturate(190%); -webkit-backdrop-filter: blur(30px) saturate(190%);
  display:flex; flex-direction:column; overflow:hidden;
  animation: helpWindowIn .25s cubic-bezier(.16,1,.3,1) both;
}
/* `hidden` alone loses to the `display:flex` above — the window would never
   close. Restated here so the attribute stays the single source of truth. */
.help-window[hidden]{ display:none; }
@keyframes helpWindowIn{
  from{ opacity:0; transform: translateY(16px) scale(.96); }
  to  { opacity:1; transform: none; }
}

.help-window-header{
  display:flex; align-items:center; gap:10px; padding:14px 16px; flex:none;
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1)); color:#fff;
}
.help-window-avatar{
  width:32px; height:32px; border-radius:50%; background: rgba(255,255,255,.2);
  display:flex; align-items:center; justify-content:center; flex:none;
}
.help-window-title{ flex:1; min-width:0; }
.help-window-name{ font-weight:800; font-size:13.5px; letter-spacing:-.01em; }
.help-window-status{ font-size:10.5px; opacity:.85; display:flex; align-items:center; gap:5px; }
.help-window-status::before{
  content:''; width:6px; height:6px; border-radius:50%; background: var(--accent-4);
}
.help-window-close{
  background: rgba(255,255,255,.15); border:none; border-radius:8px;
  width:26px; height:26px; color:#fff; cursor:pointer; flex:none;
  display:flex; align-items:center; justify-content:center;
  transition: background var(--transition);
}
.help-window-close:hover{ background: rgba(255,255,255,.28); }

.help-window-messages{
  flex:1; overflow-y:auto; padding:14px; display:flex; flex-direction:column; gap:10px;
}
.help-msg{
  max-width:82%; font-size:12.5px; line-height:1.5; padding:9px 12px;
  border-radius:14px; white-space:pre-wrap; animation: cardin .25s ease both;
}
.help-msg.bot{
  align-self:flex-start; background: var(--input-bg); color: var(--text);
  border-bottom-left-radius:4px;
}
.help-msg.user{
  align-self:flex-end; color:#fff; border-bottom-right-radius:4px;
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1));
}
.help-msg.typing{ display:flex; gap:4px; align-items:center; padding:11px 14px; }
.help-msg.typing span{
  width:6px; height:6px; border-radius:50%; background: var(--text-faint);
  animation: helpTypingDot 1.1s infinite ease-in-out both;
}
.help-msg.typing span:nth-child(2){ animation-delay:.15s; }
.help-msg.typing span:nth-child(3){ animation-delay:.3s; }
@keyframes helpTypingDot{
  0%,80%,100%{ transform: scale(.6); opacity:.4; }
  40%        { transform: scale(1);  opacity:1;  }
}

.help-window-input-row{
  display:flex; gap:8px; padding:12px; border-top:1px solid var(--line); flex:none;
}
.help-window-input{
  flex:1; background: var(--input-bg); border:1px solid transparent; border-radius: var(--radius-sm);
  padding:9px 12px; color: var(--text); font-size:12.5px; font-family:inherit; outline:none;
}
.help-window-input:focus{
  background: var(--surface-solid); box-shadow:0 0 0 3px rgba(224,34,31,.16);
}
.help-window-send{
  flex:none; width:38px; height:38px; border-radius:10px; border:none; cursor:pointer;
  background: linear-gradient(135deg, var(--accent-1-light), var(--accent-1)); color:#fff;
  display:flex; align-items:center; justify-content:center;
  transition: transform var(--spring), box-shadow var(--transition);
}
.help-window-send:hover{ transform: scale(1.1) rotate(-6deg); box-shadow: var(--shadow-red); }
.help-window-send:active{ transform: scale(.92); }
.help-window-send:disabled{ opacity:.5; cursor:default; transform:none; box-shadow:none; }

@media (max-width:480px){
  .help-window{ right:16px; bottom:88px; width:calc(100vw - 32px); }
  .help-fab{ right:16px; bottom:16px; }
}

/* ---------------------------------------------------------------------------
   Questionnaire tables (profile + PDF)
   The repeatable sections of the paper form — education, languages, jobs,
   references, family — read as tables everywhere HR looks at them.
--------------------------------------------------------------------------- */
.q-table{
  width:100%; border-collapse: collapse; font-size:13.5px; margin-bottom:6px;
  display:block; overflow-x:auto; white-space:nowrap;
}
.q-table thead th{
  text-align:left; padding:9px 12px; font-size:11.5px; font-weight:700;
  letter-spacing:.04em; text-transform:uppercase; color: var(--text-faint);
  border-bottom:1px solid var(--border);
}
.q-table tbody td{
  padding:11px 12px; color: var(--text); border-bottom:1px solid var(--border);
  vertical-align:top;
}
.q-table tbody tr:last-child td{ border-bottom:none; }
.q-table tbody tr:hover{ background: rgba(127,127,127,.06); }
.q-empty{ color: var(--text-faint); margin:0 0 20px; }

/* Whole-database download, sitting above the candidate list it describes. */
.list-actions{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:14px; }
.list-actions-hint{ font-size:12.5px; color: var(--text-faint); }
@media (max-width: 640px){ .list-actions-hint{ display:none; } }

/* ---------------------------------------------------------------------------
   Editing a saved questionnaire, and the candidate's own history
   The edit page reuses .field / .field-row; only the repeatable tables and the
   sticky save bar need shapes of their own.
--------------------------------------------------------------------------- */
.edit-head{ display:flex; align-items:center; gap:18px; flex-wrap:wrap; margin-bottom:22px; }
.edit-hint{
  font-size:12.5px; color: var(--text-muted); background: var(--input-bg);
  border:1px solid var(--border); border-radius: var(--radius-sm);
  padding:9px 13px; max-width:340px;
}
.edit-table{ margin:18px 0 4px; }
.edit-table-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; }
.edit-table-head h4{ margin:0; }
.edit-rows{ display:flex; flex-direction:column; gap:10px; }
.edit-rows:empty::before{
  content: attr(data-empty); display:block; font-size:12.5px;
  color: var(--text-faint); padding:10px 2px;
}
.edit-row{
  display:flex; align-items:flex-end; gap:10px; padding:12px;
  border:1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--input-bg);
}
.edit-row .rf{ display:flex; flex-direction:column; gap:5px; flex:1; min-width:120px; }
.edit-row .rf span{ font-size:11.5px; font-weight:700; color: var(--text-faint); }
.edit-row .rf input{ margin:0; }
.edit-row .repeat-row-remove{
  border:1px solid var(--border); background:transparent; color: var(--text-faint);
  border-radius: var(--radius-sm); width:34px; height:38px; cursor:pointer;
  flex-shrink:0; transition: var(--transition);
}
.edit-row .repeat-row-remove:hover{ color:#e0221f; border-color: rgba(224,34,31,.4); }
@media (max-width: 720px){ .edit-row{ flex-wrap:wrap; } }

.edit-actions{
  position:sticky; bottom:0; display:flex; gap:10px; align-items:center;
  padding:14px 18px; border-radius: var(--radius-sm); margin-bottom:10px;
}

/* One event: what happened and when on the first line, the value under it,
   HR's own note under that. Carded like .doc-item, which is how every other
   list of rows in the panel is drawn. */
.timeline-day{
  font-family: var(--font-label); font-size:11.5px; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  background: var(--surface-strong); border:1px solid var(--border);
  border-radius: var(--radius-pill); padding:3px 12px;
  display:inline-block; margin:2px 0 12px;
}
.timeline-day + .timeline-item{ margin-top:0; }

/* Defined once at the top of the tab and referenced per row; never drawn
   where it stands. */
.hist-sprite{ display:none; }

/* Four tones, so the column can be scanned without reading it. The chip stays
   a plain white disc in both themes — the tone is carried by the stroke and a
   hairline ring, which keeps fourteen icons from turning the trail into
   bunting. */
.hist-icon{
  position:absolute; left:-46px; top:0;
  width:32px; height:32px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background: var(--surface-solid);
  border:1px solid var(--hist-edge, var(--border-strong));
  color: var(--hist-tone, var(--text-muted));
}
.hist-icon svg{ width:17px; height:17px; display:block; }

/* The tone sits on the row so the chip and the card's left edge read as one
   thing. Each carries its own translucent pair rather than being mixed from
   the base colour: nothing else in this file mixes colours, and the tuned
   values survive a theme swap better than a percentage does. */
.tone-key { --hist-tone:#C1121C; --hist-edge:rgba(193,18,28,.34);  --hist-ring:rgba(193,18,28,.14); }
.tone-note{ --hist-tone:#2B5CA5; --hist-edge:rgba(43,92,165,.32);  --hist-ring:rgba(43,92,165,.13); }
.tone-mute{ --hist-tone:#6B6E78; --hist-edge:rgba(107,110,120,.30);--hist-ring:rgba(107,110,120,.12); }
.tone-stop{ --hist-tone:#B0721A; --hist-edge:rgba(176,114,26,.32); --hist-ring:rgba(176,114,26,.13); }
[data-theme="dark"] .tone-key { --hist-tone:#FF6B63; --hist-edge:rgba(255,107,99,.36); --hist-ring:rgba(255,107,99,.16); }
[data-theme="dark"] .tone-note{ --hist-tone:#7FADEB; --hist-edge:rgba(127,173,235,.34);--hist-ring:rgba(127,173,235,.15); }
[data-theme="dark"] .tone-mute{ --hist-tone:#9A9AA5; --hist-edge:rgba(154,154,165,.30);--hist-ring:rgba(154,154,165,.13); }
[data-theme="dark"] .tone-stop{ --hist-tone:#E0A34A; --hist-edge:rgba(224,163,74,.34); --hist-ring:rgba(224,163,74,.15); }

/* The newest event, ringed — the one the eye should land on when the tab
   opens. */
.timeline-item.is-latest .hist-icon{ box-shadow: 0 0 0 3px var(--hist-ring); }

.hist-card{
  background: var(--input-bg); border:1px solid var(--border);
  border-left:2px solid var(--hist-edge, var(--border-strong));
  border-radius: var(--radius-sm); padding:10px 14px;
  transition: var(--transition);
}
.hist-card:hover{ border-color: rgba(224,34,31,.3); }
.hist-head{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:10px; flex-wrap:wrap;
}
.hist-title{ font-weight:600; font-size:14px; }
.hist-when{
  font-family: var(--font-label); font-size:11.5px; color: var(--text-faint);
  font-variant-numeric: tabular-nums; white-space:nowrap;
}
.hist-diff{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:6px 0 0; font-size:13px; }
.hist-old, .hist-new{
  padding:2px 8px; border-radius:6px; max-width:100%; overflow-wrap:anywhere;
}
.hist-old{ background: rgba(127,127,127,.14); color: var(--text-muted); text-decoration: line-through; }
.hist-new{ background: rgba(62,110,82,.16); color: var(--text); }
.hist-arrow{ color: var(--text-faint); }
.hist-note{
  margin-top:8px; padding-left:10px; border-left:2px solid var(--hist-rail);
  font-size:13px; color: var(--text-muted); white-space:pre-wrap;
}

@media (max-width: 560px){
  .timeline{ padding-left:38px; }
  .timeline::before{ left:12px; }
  .hist-icon{ left:-38px; width:26px; height:26px; }
  .hist-icon svg{ width:14px; height:14px; }
}

/* ---------- Staff database (the wall of faces) ---------- */
/* Branches down the side, one card per person. /employees is the register HR
   works in; this is the one they look at, so it is faces first and fields
   second. Two columns on a desktop, stacked from tablet down.               */
.staff-layout{
  display:grid; grid-template-columns: 236px minmax(0, 1fr);
  gap:20px; align-items:start;
}
@media (max-width: 900px){ .staff-layout{ grid-template-columns: 1fr; } }

.staff-demo-note{
  display:flex; align-items:center; gap:10px;
  padding:11px 16px; margin-bottom:16px;
  border-radius: var(--radius-pill);
  border:1px dashed var(--border-strong);
  background: var(--surface-strong);
  color: var(--text-muted); font-size:13px; line-height:1.5;
}

.staff-side{ padding:14px; position:sticky; top:14px; }
.staff-search{ margin-bottom:12px; }
.staff-search .search-input-wrap{ min-width:0; }
.staff-search input{ width:100%; }

.staff-branches{
  display:flex; flex-direction:column; gap:2px;
  max-height: calc(100vh - 230px); overflow-y:auto;
}
@media (max-width: 900px){ .staff-branches{ max-height:none; } }

.staff-branch{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:9px 14px; border-radius: var(--radius-pill);
  color: var(--text-muted); font-size:14px; font-weight:600;
  text-decoration:none; transition: background var(--transition), color var(--transition);
}
.staff-branch:hover{ background: var(--surface-strong); color: var(--text); }
.staff-branch.active{ background: rgba(224,34,31,.10); color: var(--accent-1); }
.staff-branch-name{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.staff-count{ font-size:12px; font-weight:700; color: var(--text-faint); flex:none; }
.staff-branch.active .staff-count{ color: var(--accent-1); }

.staff-grid{
  display:grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap:14px;
}
.staff-card{
  position:relative; display:flex; align-items:center; gap:14px;
  padding:14px 16px;
  background: var(--surface); border:1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-soft);
  backdrop-filter: blur(42px) saturate(200%);
  -webkit-backdrop-filter: blur(42px) saturate(200%);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.staff-card:hover{
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift); border-color: var(--border-strong);
}

/* The wall is 787 cards, and the browser was laying out and painting every
   one of them to show the twenty on screen — and queueing 657 portraits with
   them. This hands the off-screen ones back: they keep their place in the
   scrollbar (that is what the intrinsic size is for, and `auto` makes the
   browser remember the real height once a card has been drawn once) and cost
   nothing until they are scrolled to. Ctrl-F still finds a name that has not
   been reached yet — that is `auto` rather than `hidden`. */
.staff-card{ content-visibility: auto; contain-intrinsic-size: auto 86px; }
/* The catch: this also clips whatever a card paints outside itself, and the ⋮
   menu is half a card tall and hangs below the bottom edge. So the one card
   with an open menu steps out of it. Every browser that understands
   content-visibility understands :has(), so the pair travel together. */
.staff-card:has(.staff-menu:not([hidden])){ content-visibility: visible; }

.staff-photo{
  flex:none; width:56px; height:56px; border-radius:14px; overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  background: linear-gradient(140deg, var(--accent-1), var(--accent-1-light));
  color:#fff; font-weight:700; font-size:20px;
}
.staff-photo img{ width:100%; height:100%; object-fit:cover; }

.staff-meta{ min-width:0; flex:1; }
.staff-name{ font-weight:700; font-size:14.5px; line-height:1.35; }
.staff-position{ font-size:12.5px; color: var(--text-faint); line-height:1.4; margin-top:2px; }

.staff-actions{ position:relative; flex:none; align-self:flex-start; }
.staff-kebab{
  width:28px; height:28px; border:none; background:none; cursor:pointer;
  border-radius:50%; color: var(--text-faint); font-size:17px; line-height:1;
  transition: background var(--transition), color var(--transition);
}
.staff-kebab:hover{ background: var(--surface-strong); color: var(--text); }

.staff-menu{
  position:absolute; right:0; top:32px; z-index:20; min-width:190px;
  display:flex; flex-direction:column; padding:6px;
  background: var(--surface-solid); border:1px solid var(--border-strong);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lift);
}
.staff-menu[hidden]{ display:none; }
.staff-menu button{
  text-align:left; padding:8px 12px; border:none; background:none; cursor:pointer;
  border-radius:8px; font-size:13.5px; font-weight:600; color: var(--text);
}
.staff-menu button:hover:not(:disabled){ background: var(--surface-strong); }
.staff-menu button:disabled{ opacity:.45; cursor:not-allowed; }
.staff-menu button.danger{ color: var(--accent-3); }

/* ---------- Staff sheet (one person, opened beside the wall) ---------- */
.staff-card{ cursor:pointer; }
.staff-card:focus-visible{ outline:2px solid var(--accent-1); outline-offset:3px; }

.staff-sheet-backdrop{
  position:fixed; inset:0; z-index:120;
  background: rgba(20,16,22,.34);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
  animation: staffFade .18s ease both;
}
.staff-sheet-backdrop[hidden]{ display:none; }
@keyframes staffFade{ from{ opacity:0; } to{ opacity:1; } }
body.staff-sheet-open{ overflow:hidden; }

.staff-sheet{
  position:fixed; top:0; right:0; bottom:0; z-index:130;
  width: min(480px, 100vw);
  display:flex; flex-direction:column;
  background: var(--surface-solid);
  border-left:1px solid var(--border-strong);
  box-shadow: var(--shadow-lift);
  animation: staffSlide .26s cubic-bezier(.16,1,.3,1) both;
  transition: width var(--transition-slow);
}
.staff-sheet[hidden]{ display:none; }
.staff-sheet:focus{ outline:none; }
.staff-sheet.expanded{ width: min(980px, 100vw); }
@keyframes staffSlide{ from{ transform: translateX(28px); opacity:0; } to{ transform:none; opacity:1; } }
@media (max-width: 560px){ .staff-sheet, .staff-sheet.expanded{ width:100vw; } }

.staff-sheet-head{
  display:flex; align-items:center; gap:12px;
  padding:16px 18px; border-bottom:1px solid var(--border-strong);
  background: var(--surface-solid); position:sticky; top:0; z-index:2;
}
.staff-sheet-head h2{
  flex:1; min-width:0; margin:0; font-size:19px; font-weight:700; line-height:1.25;
  /* A long ФИО gets a second line rather than an ellipsis — it is the one
     thing on the sheet that must never be cut off. */
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.staff-sheet-tools{ display:flex; align-items:center; gap:4px; flex:none; }
.staff-sheet-sep{ width:1px; height:24px; background: var(--border-strong); margin:0 6px; }

.staff-icon-btn{
  width:32px; height:32px; border:none; background:none; cursor:pointer;
  border-radius:9px; color: var(--text-muted); font-size:18px; line-height:1;
  transition: background var(--transition), color var(--transition);
}
.staff-icon-btn:hover:not(:disabled){ background: var(--surface-strong); color: var(--text); }
.staff-icon-btn:disabled{ opacity:.3; cursor:not-allowed; }

.staff-sheet-body{ flex:1; overflow-y:auto; padding:0 0 28px; }

.staff-sheet-photo{
  display:flex; align-items:center; justify-content:center;
  min-height:210px; padding:18px;
  border-bottom:1px solid var(--border-strong);
  background: var(--surface-strong);
  position:relative;
}
/* «Заменить фото» лежит на самом портрете и до наведения почти не видна:
   заменяют лицо редко, а смотрят на него каждый раз, и кнопка не должна
   спорить с тем, ради чего карточку открыли. На касании наведения нет,
   поэтому там она видна сразу. */
.staff-photo-change{
  position:absolute; left:50%; bottom:14px; transform:translateX(-50%);
  border:0; cursor:pointer; font: inherit; font-size:12.5px; font-weight:600;
  color:#fff; background: rgba(20,20,24,.72); backdrop-filter: blur(8px);
  padding:8px 16px; border-radius: var(--radius-pill);
  opacity:0; transition: opacity var(--transition), background var(--transition);
}
.staff-sheet-photo:hover .staff-photo-change,
.staff-photo-change:focus-visible{ opacity:1; }
.staff-photo-change:hover{ background: var(--accent-1); }
@media (hover: none){ .staff-photo-change{ opacity:1; } }
.staff-sheet-photo img{ max-height:280px; max-width:100%; border-radius: var(--radius-md); object-fit:cover; }
.staff-sheet-nophoto{ display:flex; flex-direction:column; align-items:center; gap:10px; }
.staff-sheet-nophoto span{
  width:96px; height:96px; border-radius:26px;
  display:flex; align-items:center; justify-content:center;
  background: linear-gradient(140deg, var(--accent-1), var(--accent-1-light));
  color:#fff; font-size:36px; font-weight:700;
}
.staff-sheet-nophoto small{ font-size:12px; color: var(--text-faint); }

.staff-sheet-fields{ margin:0; padding:20px 22px 0; }
/* Two columns once the sheet is pulled wide — the same fields, less scrolling. */
.staff-sheet.expanded .staff-sheet-fields{
  display:grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap:0 32px;
}
.staff-field{ padding:12px 0; border-bottom:1px solid var(--border); }
.staff-field:last-child{ border-bottom:none; }
.staff-field dt{
  font-size:11.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color: var(--text-faint); margin-bottom:5px;
}
.staff-field dd{ margin:0; font-size:15px; line-height:1.45; color: var(--text); }
.staff-field dd.empty{ color: var(--text-faint); }
.staff-field dd.mono{ font-family: var(--font-label); font-size:14px; letter-spacing:.04em; font-variant-numeric: tabular-nums; }
.staff-field dd a{ color: var(--accent-1); text-decoration:none; }
.staff-field dd a:hover{ text-decoration:underline; }
.staff-field dd.chips{ display:flex; flex-wrap:wrap; gap:6px; }
.staff-field .chip{
  padding:4px 11px; border-radius: var(--radius-pill);
  /* A flat grey, not a glass token: the sheet already sits on a solid panel,
     and a translucent chip on white simply disappeared. */
  background: rgba(122,122,138,.13); border:1px solid transparent;
  font-size:12.5px; font-weight:600; color: var(--text-muted);
}

.staff-sheet-hint{
  margin:18px 22px 0; font-size:12px; color: var(--text-faint);
}
.staff-sheet.expanded .staff-sheet-hint{ grid-column: 1 / -1; }

/* ---------- Active / passive, and the two groups above the branches ---------- */
/* Полупрозрачная заливка поверх розового стекла карточки читалась как пятно
   без границ: было не понять, где кончается переключатель и начинается фон.
   Волосяная рамка возвращает ему край, а выбранной таблетке — контраст. */
.staff-views{
  display:flex; gap:4px; padding:4px; margin-bottom:12px;
  background: var(--surface-strong); border:1px solid var(--border);
  border-radius: var(--radius-pill);
}
.staff-view{
  flex:1; display:flex; align-items:center; justify-content:center; gap:6px;
  padding:7px 10px; border-radius: var(--radius-pill);
  font-size:13px; font-weight:700; color: var(--text-muted); text-decoration:none;
  transition: background var(--transition), color var(--transition), box-shadow var(--transition);
}
.staff-view span{ font-size:11.5px; font-weight:700; color: var(--text-faint); }
.staff-view:hover{ color: var(--text); }
.staff-view.active{
  background: var(--surface-solid); color: var(--accent-1); box-shadow: var(--shadow-soft);
}
.staff-view.active span{ color: var(--accent-1); }
/* The order the wall is read in, as the same pair of pills as the two walls
   themselves. No counts on these: the number of people does not change with
   the sorting, and a number that never moves is furniture. */
/* Три подписи по-русски в один ряд шириной в боковую колонку не встают:
   «По алфавиту» ломалось на две строки, «Дольше всех» на узком экране
   уезжало за край и мышью до него было не добраться. Поэтому порядок чтения
   стоит списком, строка под строкой, и у контейнера обычный радиус: таблетка
   в 100px вокруг трёх этажей превращалась в пятно. */
.staff-sorts{
  margin-top:-6px; flex-direction:column; gap:2px;
  padding:5px; border-radius: var(--radius-md);
}
.staff-sorts .staff-view{ flex:none; font-size:12.5px; padding:7px 12px; }

/* A group is a filter and a drawer at once: the row filters, the arrow opens
   the offices inside it. */
.staff-group{ display:block; }
.staff-group > summary{
  list-style:none; cursor:pointer; user-select:none;
}
.staff-group > summary::-webkit-details-marker{ display:none; }
.staff-group > summary::after{
  content:'⌄'; flex:none; font-size:13px; line-height:1; color: var(--text-faint);
  transition: transform var(--transition);
}
.staff-group[open] > summary::after{ transform: rotate(180deg); }
.staff-group-head{ font-weight:700; color: var(--text); }
.staff-group-body{
  display:flex; flex-direction:column; gap:2px;
  margin:2px 0 6px 12px; padding-left:10px;
  border-left:1px solid var(--border);
}
.staff-branch.sub{ padding:7px 12px; font-size:13.5px; font-weight:600; }

/* ---------- Who is here, and who has left ---------- */
.staff-pill{
  display:inline-block; flex:none; align-self:center; padding:4px 10px;
  border-radius: var(--radius-pill); font-size:11.5px; font-weight:700;
  background: rgba(122,122,138,.13); color: var(--text-muted);
  white-space:nowrap;
}
.staff-pill.is-working{ background: rgba(46,160,90,.14); color:#2e7d4f; }
.staff-pill.is-maternity{ background: rgba(224,132,31,.15); color:#a9631a; }
.staff-pill.is-passive{ background: rgba(122,122,138,.16); color: var(--text-faint); }
.staff-pill.is-branch{ background: rgba(224,34,31,.09); color: var(--accent-1); }
/* A passive card stays legible but stops competing with the people who are
   actually at work. */
.staff-meta .staff-pill{ margin-top:7px; }
.staff-card.is-passive{ opacity:.72; }
.staff-card.is-passive .staff-photo{ filter: grayscale(1); }
.staff-card.is-passive:hover{ opacity:1; }

/* ---------- The sheet, read as a page ---------- */
.staff-sheet-ident{ padding:16px 22px 0; }
.staff-sheet-role{ font-size:14.5px; font-weight:600; color: var(--text-muted); }
.staff-sheet-tags{ display:flex; flex-wrap:wrap; gap:6px; margin-top:9px; }
.staff-sheet-tags .staff-pill{ align-self:flex-start; }

.staff-sheet-sections{ padding:6px 0 0; }
.staff-sheet.expanded .staff-sheet-sections{
  display:grid; grid-template-columns: repeat(2, minmax(0,1fr));
  gap:0 32px; align-items:start;
}
.staff-sheet-section{ padding:14px 22px 0; }
.staff-sheet-section h3{
  margin:0 0 2px; font-size:11.5px; font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color: var(--accent-1);
}
.staff-sheet.expanded .staff-sheet-fields{ display:block; }
.staff-field dd.staff-notes{ white-space:pre-line; font-size:14px; color: var(--text-muted); }

/* The one destructive-ish button on the sheet, kept at the far end of it. */
.staff-sheet-foot{
  display:flex; justify-content:flex-start; flex:none;
  padding:12px 22px; border-top:1px solid var(--border-strong);
  background: var(--surface-solid);
}
.staff-sheet-foot .btn.danger{ color: var(--accent-3); }

/* ---------- Adding somebody, in that same sheet ---------- */
.staff-form{ flex:1; min-height:0; display:flex; flex-direction:column; }
/* The person's sheet runs its rows edge to edge; a form needs the margin. */
.staff-form .staff-sheet-body{ padding:20px 22px 24px; }
/* Two dates fit side by side in a 480px sheet only at a narrower track than
   the page-wide default. */
.staff-form .field-row{ grid-template-columns: repeat(auto-fit, minmax(150px,1fr)); }
.staff-form-hint{ margin-top:6px; font-size:12px; color: var(--text-faint); line-height:1.45; }
.staff-form-foot{
  display:flex; justify-content:flex-end; gap:10px; flex:none;
  padding:14px 22px; border-top:1px solid var(--border-strong);
  background: var(--surface-solid);
}

/* ---------- Feedback on the questionnaire ---------- */
/* The thank-you card and the question about it, stacked as one column. The
   pair is the whole page, so it centres like a single card would. */
.fb-stack{ width:100%; max-width:460px; display:flex; flex-direction:column; gap:16px; }

.fb-card{ padding:24px 26px; text-align:center; }
.fb-card h3{ margin:0 0 6px; font-size:17px; }
.fb-card .fb-lead{ margin:0 0 14px; font-size:13.5px; color: var(--text-muted); line-height:1.5; }
.fb-card textarea{ resize:vertical; min-height:74px; text-align:start; }
.fb-card .btn{ width:100%; margin-top:14px; }
.fb-note{ margin:10px 0 0; font-size:12px; color: var(--text-faint); }
.fb-error{ margin:12px 0 0; font-size:13px; font-weight:600; color: var(--accent-3); }

/* Reversed on purpose: `input:checked ~ label` can only reach labels that come
   *after* it, so the row is laid out from five down to one and flipped back
   with row-reverse. That is what lets the fill work with no JavaScript. */
.fb-stars{ display:inline-flex; flex-direction:row-reverse; justify-content:center; gap:4px; }
.fb-stars input{
  position:absolute; width:1px; height:1px; opacity:0;
  /* Off-screen rather than display:none — a hidden radio is still reachable
     by keyboard, and the focus ring below is drawn on its label. */
}
.fb-stars label{
  cursor:pointer; font-size:34px; line-height:1;
  color: var(--border-strong); padding:2px;
  transition: color var(--transition), transform var(--spring);
}
.fb-stars label:hover{ transform: scale(1.15); }
.fb-stars input:checked ~ label,
.fb-stars label:hover,
.fb-stars label:hover ~ label{ color:#F5A623; }
.fb-stars input:focus-visible + label{ outline:2px solid var(--accent-1); outline-offset:3px; border-radius:6px; }
.fb-word{ margin:6px 0 14px; font-size:13px; font-weight:600; color: var(--text-muted); min-height:18px; }

.fb-done{ animation: cardin .5s var(--transition-slow) both; }
.fb-done-mark{ font-size:34px; margin-bottom:8px; }
.fb-done p{ margin:0; font-size:13.5px; color: var(--text-muted); }

/* ---------- ...and how it reads in the panel ---------- */
.fb-stars-read{ color:#F5A623; font-size:16px; letter-spacing:1px; }
.fb-bar-row{ display:flex; align-items:center; gap:12px; margin-bottom:9px; }
.fb-bar-row:last-child{ margin-bottom:0; }
.fb-bar-label{ width:38px; font-size:13px; font-weight:600; color: var(--text-muted); white-space:nowrap; }
.fb-bar{ flex:1; height:9px; border-radius:999px; background: var(--input-bg); border:1px solid var(--border); overflow:hidden; }
.fb-bar-fill{ display:block; height:100%; border-radius:999px; background: linear-gradient(90deg, #F5A623, #FFC65C); }
.fb-bar-count{ width:34px; text-align:right; font-size:13px; font-weight:700; }

/* Two year lists where the period of employment used to be one typed box. */
.year-range{ display:flex; gap:8px; }
.year-range select{ min-width:0; flex:1; }

/* ===================================================================
   Proctoring — the candidate's side of a watched test, and the record
   HR reads afterwards. The page cannot stop anybody leaving it, so all
   of this is about saying so plainly rather than pretending otherwise.
   =================================================================== */

/* The gate before the first question, and the warning on the way back:
   same shape, different colour. */
.proctor-gate, .proctor-warn{
  position:fixed; inset:0; z-index:320; display:flex; align-items:center; justify-content:center;
  padding:24px; backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  background: rgba(247,238,245,.80);
  animation: gateIn .3s ease both;
}
[data-theme="dark"] .proctor-gate, [data-theme="dark"] .proctor-warn{ background: rgba(24,18,25,.86); }
.proctor-warn[hidden]{ display:none; }
.proctor-gate-card, .proctor-warn-card{
  text-align:center; max-width:440px; width:100%; padding:36px 30px;
  background: var(--surface-strong); border:1px solid var(--border-strong);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lift);
  backdrop-filter: blur(42px) saturate(200%); -webkit-backdrop-filter: blur(42px) saturate(200%);
  animation: cardin .45s cubic-bezier(.16,1,.3,1) both;
}
.proctor-gate-icon, .proctor-warn-icon{ display:block; font-size:42px; line-height:1; margin-bottom:12px; }
.proctor-gate-card h2, .proctor-warn-card h2{ font-size:20px; line-height:1.35; margin:0 0 10px; }
.proctor-warn-card h2{ color: var(--accent-warn); }
.proctor-gate-card p, .proctor-warn-card p{
  font-size:14px; line-height:1.6; color: var(--text-muted); margin:0 0 18px;
}
.proctor-rules{
  list-style:none; padding:0; margin:0 0 22px; text-align:left;
  display:flex; flex-direction:column; gap:10px;
}
.proctor-rules li{
  position:relative; padding-left:26px; font-size:13.5px; line-height:1.55; color: var(--text-muted);
}
.proctor-rules li::before{
  content:"•"; position:absolute; left:8px; top:-1px; color: var(--accent-1); font-weight:800;
}
/* While a gate or warning is up, nothing underneath scrolls or is answerable. */
html.proctor-locked, html.proctor-locked body{ overflow:hidden; }

/* Standing reminder above the questions that the window is being watched. */
.proctor-strip{
  display:flex; align-items:center; gap:9px; margin:0 0 14px;
  padding:9px 14px; border-radius: var(--radius-md);
  background: var(--surface); border:1px solid var(--border);
  font-size:12.5px; color: var(--text-muted);
}
.proctor-strip-dot{
  width:8px; height:8px; border-radius:50%; background: var(--accent-4); flex:none;
  animation: proctorPulse 2.4s ease-in-out infinite;
}
@keyframes proctorPulse{ 0%,100%{ opacity:1; } 50%{ opacity:.25; } }
.proctor-strip-count{ margin-left:auto; font-weight:700; color: var(--accent-warn); }
.proctor-strip-hit{ border-color: rgba(255,159,10,.5); }
.proctor-strip-hit .proctor-strip-dot{ background: var(--accent-warn); }

/* Copy and paste are the two things the page really can block; the attempt
   gets a one-line answer rather than a modal. */
.proctor-toast{
  position:fixed; left:50%; bottom:28px; transform: translate(-50%, 16px); z-index:340;
  padding:11px 18px; border-radius: 999px; font-size:13px; font-weight:600;
  background: var(--surface-strong); border:1px solid var(--border-strong);
  box-shadow: var(--shadow-lift); color: var(--text);
  opacity:0; pointer-events:none; transition: opacity .25s, transform .25s;
}
.proctor-toast.show{ opacity:1; transform: translate(-50%, 0); }

/* Questions are not selectable while proctoring is on -- it makes copying
   them out one step harder and marks the page as a test, not a document. */
.proctor-on .test-q-text, .proctor-on .test-option-text{
  -webkit-user-select:none; user-select:none;
}

/* ---------- The record, on the candidate's profile ---------- */
.proctor-badge{
  align-self:flex-start; flex:none; padding:5px 11px; border-radius:999px;
  font-size:11.5px; font-weight:700; white-space:nowrap;
  border:1px solid var(--border-strong); background: var(--surface);
}
.proctor-badge-clean, .proctor-badge-minor{ color: var(--accent-4); border-color: rgba(48,209,88,.45); }
.proctor-badge-warn{ color: var(--accent-warn); border-color: rgba(255,159,10,.5); }
.proctor-badge-high{ color: var(--accent-1); border-color: rgba(224,34,31,.5); }

.proctor-log{
  margin-top:10px; padding:14px 16px; border-radius: var(--radius-md);
  background: var(--surface); border:1px solid var(--border);
}
.proctor-log-head{
  font-family: var(--font-label); font-size:11px; text-transform:uppercase; letter-spacing:.12em;
  color: var(--text-faint); margin-bottom:10px;
}
.proctor-log-stats{ display:flex; flex-wrap:wrap; gap:8px 18px; font-size:13px; color: var(--text-muted); }
.proctor-log-stats b{ font-variant-numeric: tabular-nums; color: var(--text); }
.proctor-log-list{ list-style:none; padding:0; margin:12px 0 0; display:flex; flex-direction:column; gap:6px; }
.proctor-log-list li{
  display:flex; align-items:center; gap:10px; font-size:12.5px; color: var(--text-muted);
  padding-top:6px; border-top:1px solid var(--border);
}
.proctor-log-at{
  font-family: var(--font-label); font-size:11.5px; color: var(--text-faint);
  min-width:52px; font-variant-numeric: tabular-nums;
}
.proctor-log-dur{ margin-left:auto; font-weight:700; color: var(--accent-warn); font-variant-numeric: tabular-nums; }
.proctor-log-empty{ margin:10px 0 0; font-size:12.5px; color: var(--accent-4); }

/* The one line under the switch in the test editor. */
.proctor-hint{ margin:2px 0 0 26px; font-size:12.5px; line-height:1.5; color: var(--text-faint); max-width:60ch; }
.proctor-badge-unknown{ color: var(--text-faint); }
.proctor-log-missing{ margin:0; font-size:12.5px; line-height:1.55; color: var(--text-faint); }

/* The branch a branch admin is confined to, shown beside their role. */
.branch-field[hidden]{ display:none; }
.role-hint{ font-size:12.5px; line-height:1.55; color: var(--text-faint); margin:6px 0 12px; }

/* ------------------------------------------------------------------ */
/* Greetings — anniversaries and birthdays                             */
/* Built on the staff wall's rail and card so the two pages read as one */
/* register looked at from two sides.                                   */
/* ------------------------------------------------------------------ */
.greet-rail{ max-height:none; }
.greet-rail-sep{ height:1px; margin:10px 6px; background: var(--border); }

.greet-group{
  display:flex; align-items:center; gap:10px;
  margin:22px 0 12px; font-size:13px; font-weight:800;
  letter-spacing:.06em; text-transform:uppercase; color: var(--text-faint);
}
.greet-group:first-child{ margin-top:0; }
.greet-group span{
  font-size:11.5px; padding:2px 9px; border-radius: var(--radius-pill);
  background: var(--surface-strong); color: var(--text-muted); letter-spacing:0;
}
.greet-group.is-now{ color: var(--accent-1); }
.greet-group.is-now span{ background: rgba(224,34,31,.10); color: var(--accent-1); }
.greet-group.is-late{ color: var(--accent-warn); }
.greet-group.is-late span{ background: rgba(255,159,10,.14); color: var(--accent-warn); }

.greet-grid{
  display:grid; grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  gap:14px;
}
@media (max-width: 560px){ .greet-grid{ grid-template-columns: 1fr; } }

.greet-card{
  display:flex; flex-direction:column; gap:12px; padding:16px;
  background: var(--surface); border:1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-soft);
  backdrop-filter: blur(42px) saturate(200%);
  -webkit-backdrop-filter: blur(42px) saturate(200%);
  transition: transform var(--transition), box-shadow var(--transition),
              border-color var(--transition), opacity var(--transition);
}
.greet-card:hover{
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift); border-color: var(--border-strong);
}
/* A round year is the one a company marks with more than a message. */
.greet-card.is-milestone{ border-color: rgba(224,34,31,.35); }
/* Sent, but still on the page until the date passes — visibly done, and one
   press away from being undone. */
.greet-card.is-sent{ opacity:.62; }
.greet-card.is-sent:hover{ opacity:1; }

.greet-head{ display:flex; align-items:flex-start; gap:12px; }
.greet-ident{ min-width:0; flex:1; }
.greet-tags{ display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.greet-occasion.is-work{ background: rgba(224,34,31,.10); color: var(--accent-1); }
.greet-occasion.is-birthday{ background: rgba(88,86,214,.12); color:#5856d6; }

.greet-when{
  flex:none; text-align:right; display:flex; flex-direction:column; gap:2px;
  font-variant-numeric: tabular-nums;
}
.greet-date{ font-size:13px; font-weight:700; color: var(--text); }
.greet-days{ font-size:11.5px; color: var(--text-faint); }
.greet-when.is-now .greet-date, .greet-when.is-now .greet-days{ color: var(--accent-1); }
.greet-when.is-late .greet-date, .greet-when.is-late .greet-days{ color: var(--accent-warn); }

.greet-msg{
  border:1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-strong);
}
.greet-msg summary{
  cursor:pointer; padding:9px 13px; font-size:12.5px; font-weight:600;
  color: var(--text-muted); list-style:none;
}
.greet-msg summary::-webkit-details-marker{ display:none; }
.greet-msg summary::before{ content:'💬 '; }
.greet-msg[open] summary{ border-bottom:1px solid var(--border); }
.greet-msg-body{
  margin:0; padding:12px 13px; font-size:13px; line-height:1.6;
  color: var(--text-muted); white-space:pre-wrap;
}

/* Четыре языка поздравления. Ряд узких пилюль, а не select: выбор виден
   целиком, и до нужного языка — одно нажатие. */
.greet-langs{
  display:flex; flex-wrap:wrap; gap:6px; padding:10px 13px 0;
}
.greet-lang{
  flex:none; cursor:pointer; font:inherit; font-size:11.5px; font-weight:600;
  padding:4px 10px; border-radius: var(--radius-pill);
  border:1px solid var(--border); background: var(--surface);
  color: var(--text-muted); transition: background .15s, color .15s, border-color .15s;
}
.greet-lang:hover{ color: var(--text); border-color: var(--text-faint); }
.greet-lang.active{
  background: rgba(224,34,31,.10); border-color: rgba(224,34,31,.35);
  color: var(--accent-1);
}

.greet-actions{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.greet-actions .btn{ flex:none; }
.greet-nophone{
  font-size:12.5px; color: var(--accent-warn);
  padding:6px 12px; border-radius: var(--radius-pill);
  background: rgba(255,159,10,.12);
}
.greet-card.is-sent .greet-mark{ color: var(--accent-4); border-color: rgba(48,209,88,.4); }

.greet-undated{
  margin:22px 2px 0; font-size:12.5px; line-height:1.6; color: var(--text-faint);
}
.greet-tpl-foot{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  margin-top:6px;
}
.greet-tpl-foot .staff-form-hint{ margin:0; }

/* ==========================================================================
   Reference request — the page a referee opens from the link HR sent.
   Lives outside the panel, so it carries its own width and rhythm rather
   than inheriting the admin shell's.
   ========================================================================== */
.ref-page{ max-width: 860px; margin: 32px auto 64px; padding: 0 18px; }
.ref-kicker{
  font-family: var(--font-label); font-size:12px; letter-spacing:.14em;
  text-transform:uppercase; color: var(--accent-1);
}
.req{ color: var(--accent-1); }

.ref-anketa summary{
  cursor:pointer; font-weight:600; font-size:15px; padding:2px 0;
  list-style:none;
}
.ref-anketa summary::-webkit-details-marker{ display:none; }
.ref-anketa summary::before{ content:"▸ "; color: var(--text-muted); }
.ref-anketa[open] summary::before{ content:"▾ "; }

.ref-error{
  background: rgba(224,34,31,.10); border:1px solid rgba(224,34,31,.30);
  color: var(--accent-1); border-radius: var(--radius-md);
  padding:12px 14px; margin-bottom:16px; font-size:14px;
}
.ref-scale{ margin-top:6px; font-size:12.5px; color: var(--text-muted); }

/* Radio row that reads as chips rather than a stack of bullets. */
.ref-choice{ display:flex; gap:10px; flex-wrap:wrap; }
.ref-choice label{
  display:flex; align-items:center; gap:8px; cursor:pointer;
  border:1px solid var(--line); border-radius: var(--radius-pill);
  padding:9px 16px; font-size:14px; background: var(--input-bg);
  transition: border-color var(--transition), background var(--transition);
}
.ref-choice label:has(input:checked){
  border-color: var(--accent-1); background: rgba(224,34,31,.08);
}

.ref-consent{
  margin:14px 0 0; font-size:12px; line-height:1.55; color: var(--text-faint);
}

.ref-thanks{ margin-top:12vh; }
.ref-thanks-icon{
  width:56px; height:56px; margin:0 auto; border-radius:50%;
  background: var(--accent-1); color:#fff;
  display:flex; align-items:center; justify-content:center;
  font-size:28px; font-weight:700;
}
.ref-thanks-mark{
  margin-top:18px; font-size:20px; letter-spacing:.08em; color: var(--accent-1);
}

/* --- the hero: a face, a name, and what they are applying for --- */
.ref-hero-top{ display:flex; gap:20px; align-items:center; flex-wrap:wrap; }
.ref-photo{
  width:96px; height:96px; flex:0 0 96px; border-radius:24px; overflow:hidden;
  background: var(--surface-strong); border:1px solid var(--border-strong);
  display:flex; align-items:center; justify-content:center;
  font-size:34px; font-weight:800; color: var(--text-muted);
  box-shadow: var(--shadow-soft);
}
.ref-photo img{ width:100%; height:100%; object-fit:cover; display:block; }
.ref-hero-who h1{ margin:6px 0 2px; font-size:27px; line-height:1.15; }
.ref-hero-post{ font-size:16px; color: var(--text); font-weight:600; }
.ref-hero-firm{ margin-top:2px; font-size:13.5px; color: var(--text-muted); }
.ref-hero-intro{
  margin:18px 0 0; padding-top:16px; border-top:1px solid var(--line);
  color: var(--text-muted); font-size:14.5px; line-height:1.65;
}

/* The shared star widget paints unfilled stars in --border-strong, which is a
   near-white in the light theme: on this page's light card they vanished
   altogether. Repainted against the hairline colour and enlarged — this is
   the one control the whole page is asking for. */
.ref-page .score-stars{ gap:6px; margin-top:4px; }
.ref-page .score-stars .star{ font-size:30px; }
.ref-page .score-stars label:hover .star{ color: var(--accent-1-light); transform: scale(1.12); }
.ref-page .score-stars .star.filled{ color: var(--accent-1); }

/* "Не уверен" was breaking onto a second line and pushing the row out of
   rhythm — the chips size to their text now. */
.ref-choice label{ white-space:nowrap; }
.ref-choice input{ accent-color: var(--accent-1); }

.ref-dictate-row{
  display:flex; align-items:center; gap:12px; margin-top:8px; flex-wrap:wrap;
  font-size:12.5px; color: var(--text-muted);
}
.ref-dictate-row .is-listening{
  border-color: var(--accent-1); color: var(--accent-1);
}

/* Ряд диктовки, который js/dictate.js подставляет под поле сам. Прижат к
   полю и набран мельче него: это способ заполнить поле, а не отдельное
   действие рядом с «Сохранить». Пока идёт запись, кнопка светится красным —
   единственный признак того, что микрофон открыт. */
.dictate-row{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:6px;
}
.dictate-btn{ flex:none; }
.dictate-btn.is-listening{
  border-color: var(--accent-1); color: var(--accent-1);
  background: rgba(224,34,31,.06);
}
/* Пульс — не украшение: он отличает «слушаю» от просто нажатой кнопки. */
.dictate-btn.is-listening{ animation: dictate-pulse 1.4s ease-in-out infinite; }
@keyframes dictate-pulse{
  0%, 100%{ box-shadow: 0 0 0 0 rgba(224,34,31,.30); }
  50%     { box-shadow: 0 0 0 5px rgba(224,34,31,0); }
}
@media (prefers-reduced-motion: reduce){
  .dictate-btn.is-listening{ animation:none; }
}
.dictate-note{ font-size:12.5px; line-height:1.5; color: var(--text-muted); }

/* The list of requests on the candidate's card. */
.refreq-row{
  display:flex; justify-content:space-between; align-items:center; gap:12px;
  flex-wrap:wrap; padding:10px 0; border-top:1px solid var(--line);
  font-size:13.5px;
}
.refreq-row:first-of-type{ border-top:none; }
.refreq-link{
  font-family: var(--font-label); font-size:12.5px; color: var(--text-muted);
  word-break: break-all;
}
.refreq-actions{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
/* Recipient + both role buttons on one line: the card's contact is a default,
   not a decision, so it has to be editable before the link is minted. */
.refreq-send{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.refreq-send input{
  border:1px solid var(--line); border-radius: var(--radius-pill);
  padding:8px 14px; font-size:13px; background: var(--input-bg);
  color: var(--text); min-width:140px; max-width:190px;
}
.refreq-send input:focus{ outline:none; border-color: var(--accent-1); }

/* Who is carrying a candidate, on the profile header. A strip rather than
   another row in the details table: it is the first thing worth knowing when
   the page opens, and on a phone it has to wrap without pushing the status
   badge off the screen. */
.responsible-strip{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  margin-top:16px; padding:10px 14px;
  border:1px solid var(--border); border-radius:14px;
}
.responsible-label{ font-size:13px; color:var(--text-muted); font-weight:600; }
.responsible-note{ font-size:12.5px; color:var(--text-faint); }


/* --- the reminder to switch the second factor on --- */
.twofa-nudge{
  display:flex; align-items:flex-start; gap:14px; flex-wrap:wrap;
  border:1px solid rgba(224,34,31,.28); background: rgba(224,34,31,.06);
  border-radius: var(--radius-lg); padding:16px 18px; margin-bottom:18px;
}
.twofa-nudge[hidden]{ display:none; }
.twofa-nudge-icon{ font-size:22px; line-height:1.2; }
.twofa-nudge-body{ flex:1; min-width:240px; }
.twofa-nudge-body b{ font-size:15px; }
.twofa-nudge-body p{ margin:4px 0 0; font-size:13.5px; line-height:1.6; color: var(--text-muted); }
.twofa-nudge-actions{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; }

/* ---------- Column picker on the candidate list ---------- */
/* Fourteen columns do not fit a laptop; the list carries all of them and each
   person hides what they do not need. The menu is a plain panel rather than a
   <select multiple> so the labels read at full length in all four languages. */
.col-picker{ position:relative; display:flex; justify-content:flex-end; margin-bottom:10px; }
.col-picker-menu{
  position:absolute; top:calc(100% + 6px); right:0; z-index:40;
  min-width:210px; padding:8px; border-radius:14px;
  background:var(--surface-solid); border:1px solid var(--line);
  box-shadow:0 18px 40px rgba(0,0,0,.16);
  display:grid; gap:2px; max-height:60vh; overflow-y:auto;
}
.col-picker-menu[hidden]{ display:none; }
.col-picker-menu label{
  display:flex; align-items:center; gap:9px; cursor:pointer;
  padding:7px 10px; border-radius:9px; font-size:13.5px; white-space:nowrap;
}
.col-picker-menu label:hover{ background:var(--input-bg); }
.col-picker-menu input{ width:15px; height:15px; margin:0; accent-color:var(--accent-1); }

/* A school name or a list of languages is long enough to push the score and
   the status off the screen. Clipped in the cell, in full on hover. */
.cell-clip{ max-width:190px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }


/* --- три оценки кандидата и итог --- */
.score-board{
  display:grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap:1px; background: var(--line); border:1px solid var(--line);
  border-radius: var(--radius-md); overflow:hidden; margin:18px 0 4px;
}
.score-cell{ background: var(--bg-elevated); padding:16px 18px; }
.score-cell-label{
  font-family: var(--font-label); font-size:11.5px; letter-spacing:.12em;
  text-transform:uppercase; color: var(--text-muted); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;
}
.score-cell-value{
  margin-top:6px; font-size:30px; font-weight:800; letter-spacing:-.03em;
  line-height:1.1; color: var(--text); font-variant-numeric: tabular-nums;
}
.score-cell-value span{ font-size:14px; font-weight:600; color: var(--text-faint); }
.score-cell-value.is-empty{ color: var(--text-faint); font-weight:600; }
.score-cell-note{ margin-top:4px; font-size:12px; color: var(--text-faint); }
.score-cell-total{ background: rgba(224,34,31,.06); }
.score-cell-total .score-cell-label{ color: var(--accent-1); }


/* --- окно выбора получателя рекомендации --- */
.refask{
  border:none; padding:0; background:transparent;
  max-width:min(560px, calc(100vw - 32px));
}
.refask::backdrop{ background: rgba(16,14,20,.45); backdrop-filter: blur(2px); }
.refask form{
  background: var(--surface-solid); border:1px solid var(--line);
  border-radius: var(--radius-lg); padding:26px 26px 22px;
  box-shadow: var(--shadow-lift);
  display:flex; flex-direction:column; gap:14px;
}
.refask h3{ margin:0; font-size:19px; letter-spacing:-.01em; }
.refask-hint{ margin:0; font-size:13px; color: var(--text-muted); }
.refask-actions{
  display:flex; justify-content:flex-end; gap:10px; margin-top:4px;
  padding-top:14px; border-top:1px solid var(--line);
}

/* Sending our own hiring manager a link to score a candidate. Folded away by
   default: most candidates never need it, and an open form under every score
   box makes the tab look like paperwork. */
.mgrreq{ margin-top:14px; border-top:1px solid var(--border); padding-top:12px; }
.mgrreq > summary{ cursor:pointer; font-size:13.5px; font-weight:600; }
.mgrreq-row{
  display:flex; justify-content:space-between; align-items:center; gap:10px;
  flex-wrap:wrap; padding:8px 0; border-top:1px solid var(--border);
}
.mgrreq-pos{ font-size:12.5px; color:var(--text-faint); margin-left:6px; }
.mgrreq-state{ font-size:12.5px; color:var(--text-muted); margin-top:2px; }

/* The assessment list: one row per person who scored the candidate. It
   replaced two fixed star boxes, so it has to carry more than they did —
   a name, a role, what they wrote — without turning the tab into a wall. */
.assess{ margin-bottom:18px; }
.assess-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; }
.assess-head h4{ margin:0; }
.assess-row{
  display:flex; align-items:flex-start; gap:12px;
  padding:10px 0; border-top:1px solid var(--border);
}
.assess-who{ flex:1; min-width:0; }
.assess-role{
  font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:.04em;
  color:var(--text-faint); margin-left:8px;
}
.assess-pos{ font-size:12.5px; color:var(--text-faint); margin-left:8px; }
.assess-text{ font-size:13.5px; color:var(--text-muted); margin-top:4px; }
.assess-mark{ font-size:20px; font-weight:800; white-space:nowrap; }
.assess-mark span{ font-size:12px; font-weight:600; color:var(--text-faint); }
.assess-pending{ opacity:.75; }
.assess-form{ margin-top:14px; padding-top:12px; border-top:1px solid var(--border); }
.assess-form-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr));
  gap:8px; margin-bottom:8px;
}
/* Кнопка диктовки вставляется сразу после поля, а поле здесь — ячейка
   сетки: без этого 🎙 занял бы следующую колонку и вытолкнул «Поставить
   оценку» на строку ниже. Своя строка во всю ширину — и ряд с ползунком
   остаётся тем, чем был. */
.assess-form-grid .dictate-row{ grid-column:1 / -1; margin-top:0; }
/* Ползунку тоже своя строка. Он не поле в 150px: рядом с дорожкой стоит
   цифра, вместе они просят больше двухсот, а колонка сетки задана снизу
   жёстко (minmax(150px, 1fr)) и под содержимое не растёт. Ячейка молча
   вылезала вправо, и «5/10» садился поверх соседнего поля — ровно на слова
   «Напишите комментарий», которые под ним было уже не прочитать. */
.assess-form-grid .rate{ grid-column:1 / -1; }
/* Комментарий к оценке обязателен — ему вся ширина, а не колонка, в которую
   помещается одно слово. */
.assess-form-grid input[data-mic]{ grid-column:1 / -1; }

/* "My assessment": the one row you fill in as yourself. Set apart from the
   list because it is an action, not a record — everything below it has
   already happened.

   Поэтому карточка и выглядит иначе, чем строки под ней: своя подложка с
   лёгким фирменным оттенком сверху, поля во всю ширину и одна кнопка внизу
   справа. Раньше здесь была почти невидимая рамка (`--surface-2` в проекте
   не объявлена, и фон падал на 2% чёрного), ползунок и однострочный
   комментарий стояли в одной сетке по 150px — половина карточки пустовала,
   а поле для обязательного комментария просило одно слово. */
.assess-mine{
  display:flex; flex-direction:column; gap:14px;
  background:
    linear-gradient(180deg, rgba(224,34,31,.055), rgba(224,34,31,0) 78px),
    var(--surface-strong);
  border:1px solid var(--border-strong); border-radius: var(--radius-md);
  padding:16px 18px 18px; margin-bottom:14px;
  box-shadow: var(--shadow-soft);
}
.mine-head{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.mine-head b{ font-size:15px; }
/* Имя и роль одной строкой: роль мельче и бледнее — она уточняет имя, а не
   спорит с ним. */
.mine-who{ display:flex; align-items:baseline; gap:8px; font-size:13px; font-weight:600; color: var(--text-muted); }
.mine-who i{ font-style:normal; font-size:11.5px; font-weight:700; letter-spacing:.04em;
  text-transform:uppercase; color: var(--text-faint); }

.mine-rate{ gap:16px; }
/* Цифра оценки — тем же кеглем, что и чужие оценки в списке ниже: одна
   карточка, один способ показать балл. */
/* Селектор с .rate — иначе .rate-out ниже перебивает и ширину, и
   выравнивание: цифру прижимало вправо, к самой дорожке. */
.rate .mine-mark{
  display:flex; align-items:baseline; gap:1px; min-width:66px;
  text-align:left; font-size:26px; font-weight:800; line-height:1;
  color: var(--accent-1); font-variant-numeric: tabular-nums;
}
.mine-mark i{ font-style:normal; font-size:12px; font-weight:700; color: var(--text-faint); }
/* Оценки ещё нет: прочерк не должен выглядеть как поставленный балл. */
.mine-mark.is-empty{ color: var(--text-faint); }
.mine-mark.is-empty i{ opacity:.5; }

.mine-slider{ flex:1; min-width:0; }
.mine-slider input[type="range"]{ width:100%; display:block; }
/* Три подписи с засечками — начало, середина, конец. Не десять делений:
   шкала здесь нужна, чтобы было видно, где середина, а не чтобы считать по
   ней клетки. Засечка растёт из самой подписи, поэтому она с ней и совпадает,
   какой бы ширины ни была карточка. */
.mine-scale{
  margin-top:2px; display:flex; justify-content:space-between;
  font-size:11px; font-weight:600; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.mine-scale span{ position:relative; padding-top:9px; }
.mine-scale span::before{
  content:''; position:absolute; top:0; width:2px; height:5px;
  border-radius:1px; background: var(--border-strong);
}
.mine-scale span:first-child::before{ left:0; }
.mine-scale span:nth-child(2)::before{ left:50%; transform:translateX(-50%); }
.mine-scale span:last-child::before{ right:0; }

/* Поле во всю ширину карточки и в четыре строки. Комментарий здесь
   обязателен, и пишут в него не одно слово, а что человек показал на
   разговоре: в две строки такой текст приходилось листать колёсиком, ещё
   не дописав. Поля под ним — 🎙 и кнопка — стоят одним рядом, а не двумя
   этажами с пустотой между ними. */
.mine-comment{
  display:grid; grid-template-columns:1fr auto; gap:10px 12px; align-items:center;
}
.mine-comment textarea{
  grid-column:1 / -1; width:100%; min-height:116px;
  padding:12px 14px; line-height:1.55; resize:vertical;
}
/* Ряд диктовки принадлежит полю и остаётся под ним — см. .dictate-row. */
.mine-comment .dictate-row{ grid-column:1; justify-self:start; margin-top:0; }

.mine-foot{ grid-column:2; justify-self:end; display:flex; justify-content:flex-end; }
@media (max-width: 560px){
  .assess-mine{ padding:14px; }
  /* На телефоне ряд не разрезать: 🎙 и кнопка встают друг под друга, и
     кнопка занимает всю ширину — мимо неё большим пальцем не промахнуться. */
  .mine-comment{ grid-template-columns:1fr; }
  .mine-comment .dictate-row, .mine-foot{ grid-column:1; justify-self:stretch; }
  .mine-foot .btn{ width:100%; }
  .rate .mine-mark{ font-size:22px; min-width:56px; }
}

.assess-mine-head{ display:flex; align-items:baseline; gap:10px; margin-bottom:8px; }
.assess-edit{ margin-top:6px; }
.assess-edit > summary{ cursor:pointer; font-size:12.5px; color:var(--text-faint); }

/* The 1–10 slider. A dropdown made you read ten lines to choose a position on
   a scale; this shows the whole scale at once and prints the number beside it,
   because a slider without its value is a guess. */
.rate{ display:flex; align-items:center; gap:10px; min-width:0; }
.rate input[type="range"]{
  flex:1; min-width:120px; accent-color:var(--accent-1);
  height:22px; cursor:pointer;
}
.rate-out{
  min-width:74px; text-align:right; font-weight:700; font-size:14px;
  color:var(--text); white-space:nowrap;
}

/* The add-assessor button, under the list and above the form it opens. Full
   width on a phone, where a lone small button under a list of names is easy
   to walk past. */
.assess-add{ margin-top:12px; }
@media (max-width: 640px){ .assess-add{ width:100%; } }

/* Paging under the candidate list. The total sits on the left because it is
   read far more often than the arrows are pressed: it says whether the filter
   above did anything. */
.pager{
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; flex-wrap:wrap; padding:14px 4px 4px;
}
.pager-count{ font-size:13px; color:var(--text-muted); }
.pager-nav{ display:flex; align-items:center; gap:8px; }
.pager-at{ font-size:13px; color:var(--text-muted); white-space:nowrap; }

/* ==========================================================================
   Адаптация — карточки новых сотрудников и одна карточка целиком.

   Рейка этапов на списке нарисована точками без подписей: подпись рядом с
   каждой из шести точек не помещается в карточку шириной в треть экрана, а
   название текущего этапа и так написано словами под рейкой. На самой
   карточке сотрудника места хватает, и там используется общий .stage-rail —
   тот же, что на экзаменах.
   ========================================================================== */
.adapt-hint{ margin:0; font-size:12.5px; line-height:1.55; color: var(--text-faint); }

.adapt-start{ margin-bottom:18px; }
.adapt-start-form{
  display:grid; grid-template-columns: repeat(auto-fit, minmax(210px,1fr)); gap:14px;
  align-items:end;
}
.adapt-start-form .field{ margin:0; min-width:0; }
.adapt-start-go{ display:flex; flex-direction:column; gap:6px; }

.adapt-grid{
  display:grid; grid-template-columns: repeat(auto-fill, minmax(370px, 1fr)); gap:14px;
}
@media (max-width: 560px){ .adapt-grid{ grid-template-columns: 1fr; } }

.adapt-card{
  display:flex; flex-direction:column; gap:12px; padding:16px;
  background: var(--surface); border:1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-soft);
  backdrop-filter: blur(42px) saturate(200%);
  -webkit-backdrop-filter: blur(42px) saturate(200%);
  transition: transform var(--transition), box-shadow var(--transition),
              border-color var(--transition), opacity var(--transition);
}
.adapt-card:hover{
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift); border-color: var(--border-strong);
}
/* Всё сделано и разговоры записаны — осталось одно решение, и карточка это
   показывает, не дожидаясь, пока её откроют. */
.adapt-card.is-ready{ border-color: rgba(48,209,88,.42); }
/* Завершённые не уходят со страницы, но и не спорят за внимание с теми, кто
   ещё в процессе. */
.adapt-card.is-done{ opacity:.68; }
.adapt-card.is-done:hover{ opacity:1; }

.adapt-card-head{ display:flex; align-items:flex-start; gap:12px; }
.adapt-ident{ min-width:0; flex:1; }
.adapt-ident .staff-name{ text-decoration:none; color: var(--text); }
.adapt-ident .staff-name:hover{ color: var(--accent-1); }

.adapt-when{
  flex:none; text-align:right; display:flex; flex-direction:column;
  align-items:flex-end; gap:4px; font-variant-numeric: tabular-nums;
}
.adapt-when-main{ font-size:13px; font-weight:700; color: var(--text); white-space:nowrap; }
.adapt-when-sub{ font-size:11.5px; color: var(--text-faint); white-space:nowrap; }
.adapt-when.is-late .adapt-when-main,
.adapt-when.is-late .adapt-when-sub{ color: var(--accent-warn); }

/* Шесть точек — весь процесс. Между ними линия, чтобы читалось как путь, а
   не как набор значков. */
.adapt-rail{ display:flex; align-items:center; gap:0; }
.adapt-step{
  flex:1; height:6px; border-radius:999px; background: var(--chart-track);
  transition: background var(--transition);
}
.adapt-step + .adapt-step{ margin-left:4px; }
.adapt-step.is-done{ background: var(--accent-4); }
.adapt-step.is-now{ background: var(--accent-1); box-shadow: 0 0 0 3px rgba(224,34,31,.14); }

.adapt-card-foot{ display:flex; flex-direction:column; gap:10px; }
.adapt-now{
  display:flex; align-items:center; flex-wrap:wrap; gap:8px;
  font-size:13px; color: var(--text-muted);
}
.adapt-now b{ font-size:14px; color: var(--text); }

.adapt-bar{
  height:6px; border-radius:999px; background: var(--chart-track); overflow:hidden;
}
.adapt-bar i{
  display:block; height:100%; border-radius:999px;
  background: linear-gradient(90deg, var(--accent-1-light), var(--accent-1));
  transition: width var(--transition-slow);
}
.adapt-bar-lg{ height:8px; margin:16px 0 10px; }

.adapt-people{
  display:flex; flex-wrap:wrap; gap:4px 14px;
  font-size:12px; color: var(--text-faint);
}

.staff-pill.is-ready{ background: rgba(48,209,88,.14); color:#1f8b45; }
.staff-pill.is-late{ background: rgba(255,159,10,.16); color:#a9631a; }
.staff-pill.is-score{ background: rgba(88,86,214,.12); color:#5856d6; }
.staff-pill.is-passed{ background: rgba(48,209,88,.14); color:#1f8b45; }
.staff-pill.is-extended{ background: rgba(255,159,10,.16); color:#a9631a; }
.staff-pill.is-failed{ background: rgba(224,34,31,.10); color: var(--accent-1); }
.staff-pill.is-src-employee{ background: rgba(224,34,31,.09); color: var(--accent-1); }
.staff-pill.is-src-mentor{ background: rgba(88,86,214,.12); color:#5856d6; }
.staff-pill.is-src-manager{ background: rgba(255,159,10,.16); color:#a9631a; }
.staff-pill.is-src-hr{ background: rgba(60,60,67,.10); color: var(--text-muted); }

/* ---------- Одна карточка адаптации ---------- */
.adapt-top{ margin-bottom:18px; }
.adapt-top-head{ display:flex; align-items:flex-start; gap:16px; margin-bottom:20px; }
.adapt-who{ font-size:20px; font-weight:800; margin:0 0 2px; }
.staff-photo-lg{ width:72px; height:72px; font-size:24px; }
.adapt-facts{
  display:flex; flex-wrap:wrap; gap:4px 18px; margin-top:10px;
  font-size:12.5px; color: var(--text-faint);
}
.adapt-facts b{ color: var(--text-muted); font-weight:700; }

/* План слева, управление справа: пункты открывают и закрывают каждый день,
   параметры трогают раз. */
.adapt-cols{
  display:grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap:18px; align-items:start;
}
@media (max-width: 1040px){ .adapt-cols{ grid-template-columns: 1fr; } }
.adapt-col{ display:flex; flex-direction:column; gap:18px; min-width:0; }
.adapt-col .card{ margin:0; }

.adapt-group-head{
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  margin-bottom:14px;
}
.adapt-group-head h3{ margin:0; }
.adapt-group-count{
  font-family: var(--font-label); font-size:12.5px; font-weight:700;
  font-variant-numeric: tabular-nums; color: var(--text-faint);
}

.adapt-items{ list-style:none; margin:0 0 14px; padding:0; display:flex;
  flex-direction:column; gap:2px; }
.adapt-item{
  display:flex; align-items:flex-start; gap:10px;
  padding:10px 4px; border-bottom:1px solid var(--line);
}
.adapt-item:last-child{ border-bottom:none; }
.adapt-item-body{ flex:1; min-width:0; }
.adapt-item-title{ font-size:14px; font-weight:600; line-height:1.4; }
.adapt-item-detail{ margin:4px 0 0; font-size:12.5px; line-height:1.5; color: var(--text-muted); }
.adapt-item-meta{
  display:flex; flex-wrap:wrap; align-items:center; gap:6px 12px; margin-top:5px;
  font-size:11.5px; color: var(--text-faint);
}
.adapt-item.is-done .adapt-item-title{ color: var(--text-muted); text-decoration: line-through; }
.adapt-item.is-late .adapt-item-title{ color: var(--accent-warn); }

.adapt-tick{ display:flex; align-items:center; gap:6px; margin:0; flex:none; }
.adapt-check{
  width:26px; height:26px; flex:none; border-radius:50%;
  border:1.5px solid var(--border-strong); background: var(--input-bg);
  color: transparent; font-size:13px; font-weight:800; line-height:1;
  cursor:pointer; transition: var(--transition);
}
.adapt-check:hover{ border-color: var(--accent-4); color: rgba(48,209,88,.5); }
.adapt-item.is-done .adapt-check{
  background: var(--accent-4); border-color: var(--accent-4); color:#fff;
}
.adapt-score-in{
  width:58px; padding:5px 8px; font-size:12.5px; text-align:center;
}
.adapt-item-del{ margin:0; flex:none; opacity:0; transition: opacity var(--transition); }
.adapt-item:hover .adapt-item-del,
.adapt-item:focus-within .adapt-item-del{ opacity:1; }
@media (hover: none){ .adapt-item-del{ opacity:1; } }

.adapt-add{
  display:flex; flex-wrap:wrap; gap:8px; align-items:center;
  padding-top:12px; border-top:1px solid var(--line);
}
.adapt-add input[type="text"]{ flex:1; min-width:180px; }
.adapt-add input[type="date"]{ width:150px; flex:none; }

.adapt-fb{ list-style:none; margin:0 0 16px; padding:0; display:flex;
  flex-direction:column; gap:12px; }
.adapt-fb-item{
  padding:12px 14px; border-radius: var(--radius-sm);
  background: var(--surface-strong); border:1px solid var(--border);
}
.adapt-fb-head{ display:flex; align-items:center; flex-wrap:wrap; gap:8px; }
.adapt-fb-who{ font-size:12.5px; font-weight:700; color: var(--text-muted); }
.adapt-fb-date{ font-size:12px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.adapt-fb-del{ margin:0 0 0 auto; }
.adapt-fb-text{ margin:8px 0 0; font-size:13.5px; line-height:1.6; white-space:pre-wrap; }
.adapt-fb-form{ padding-top:14px; border-top:1px solid var(--line); }

.adapt-done{ display:flex; flex-direction:column; gap:12px; align-items:flex-start; }
.adapt-done-head{ display:flex; align-items:center; gap:10px; }
/* Удаление карточки — не часть работы с ней, поэтому оно отделено чертой и
   стоит под всем остальным. */
.adapt-danger{ margin-top:18px; padding-top:14px; border-top:1px solid var(--line); }

/* ---------- Dashboard tiles: colour that already means something ----------
   Eight tiles that differed only by an emoji at 40% opacity, and every one of
   them is a filter into the candidate list. The colour that filter sorts by is
   already on screen — the badges in the table underneath use it — so the tile
   borrows the same one: a tinted chip behind the icon and a hairline along the
   top edge. The glass itself stays neutral. Eight coloured cards would shout
   over the numbers, and the numbers are what the page is read for. */
.stat-card{ --tone: #6B6E78; --tone-soft: rgba(107,110,120,.12); }
.stat-card[data-tone="brand"] { --tone:#E0221F; --tone-soft:rgba(224,34,31,.12); }
.stat-card[data-tone="blue"]  { --tone:#2B5CA5; --tone-soft:rgba(43,92,165,.12); }
.stat-card[data-tone="indigo"]{ --tone:#4B4FC4; --tone-soft:rgba(75,79,196,.12); }
.stat-card[data-tone="violet"]{ --tone:#7A3FC9; --tone-soft:rgba(122,63,201,.13); }
.stat-card[data-tone="amber"] { --tone:#D98C1F; --tone-soft:rgba(217,140,31,.15); }
.stat-card[data-tone="green"] { --tone:#1E8E5A; --tone-soft:rgba(30,142,90,.13); }
.stat-card[data-tone="red"]   { --tone:#C1121C; --tone-soft:rgba(193,18,28,.12); }
/* Dark: the same hues lifted, the way the theme lifts its own red. The badge
   palette is fixed across themes because a badge is an outline in its own
   colour; a filled chip is not, and these hues go to mud behind glass. */
[data-theme="dark"] .stat-card              { --tone:#9BA0AA; --tone-soft:rgba(155,160,170,.18); }
[data-theme="dark"] .stat-card[data-tone="brand"] { --tone:#FF3B30; --tone-soft:rgba(255,59,48,.20); }
[data-theme="dark"] .stat-card[data-tone="blue"]  { --tone:#6AA6F5; --tone-soft:rgba(106,166,245,.20); }
[data-theme="dark"] .stat-card[data-tone="indigo"]{ --tone:#8C90F2; --tone-soft:rgba(140,144,242,.20); }
[data-theme="dark"] .stat-card[data-tone="violet"]{ --tone:#B57BF0; --tone-soft:rgba(181,123,240,.20); }
[data-theme="dark"] .stat-card[data-tone="amber"] { --tone:#F0B75A; --tone-soft:rgba(240,183,90,.20); }
[data-theme="dark"] .stat-card[data-tone="green"] { --tone:#3FD39A; --tone-soft:rgba(63,211,154,.20); }
[data-theme="dark"] .stat-card[data-tone="red"]   { --tone:#FF5A54; --tone-soft:rgba(255,90,84,.20); }

/* The icon becomes a chip rather than a faded sticker in the corner. At full
   opacity inside its own tint it reads as part of the tile instead of as
   something left on top of it. */
.stat-card .stat-icon{
  right:14px; top:14px; width:36px; height:36px; padding:0;
  display:flex; align-items:center; justify-content:center;
  border-radius:12px; background: var(--tone-soft);
  font-size:17px; line-height:1; opacity:1;
  transition: transform var(--spring), background var(--transition);
}
/* Room for the chip, or a two-word label runs underneath it. */
.stat-card .stat-label{ padding-right:46px; }

/* The accent bar every other glass card grows on hover: here it is always
   there, quietly, so the grid reads as a row of statuses at a glance. It
   fades out to the right rather than ruling a hard line across the card. */
.glass.stat-card[data-tone]::before{
  opacity:.55; transform: scaleX(1);
  background: linear-gradient(90deg, var(--tone), transparent 88%);
}
a.stat-card[data-tone]:hover::before{ opacity:1; }
a.stat-card[data-tone]:hover{ border-color: var(--tone); }
a.stat-card[data-tone]:hover .stat-value{ color: var(--tone); }
a.stat-card[data-tone]:hover .stat-icon{ transform: scale(1.12) rotate(-6deg); }

/* ==========================================================================
   Знакомство — три дня по ссылке

   Две стороны одного механизма: строки в панели, где HR выписывает ссылку и
   читает отметки, и страница кандидата, где этих дней всего три и ничего,
   кроме них, нет. Вторая намеренно просторнее первой: её открывают с
   телефона, по одному разу в день, чтобы прочитать один абзац.
   ========================================================================== */

/* --- Панель: список выписанных ссылок ---------------------------------- */
/* Секция идёт третьим ребёнком в сетке «фильтры + список», то есть на второй
   её строке — и без этого вставала в первую колонку, ширину бокового фильтра,
   оставляя справа пустое поле во весь экран. Знакомство относится ко всей
   странице, а не к колонке, поэтому занимает обе. */
.welcome-block{ margin-top: 34px; grid-column: 1 / -1; }
.welcome-block .section-head{ margin-bottom: 14px; }
.welcome-block .section-head h3{ margin: 0 0 4px; }

.welcome-issue{
  display:flex; gap:14px; align-items:flex-end; flex-wrap:wrap;
  padding:18px 20px; margin-bottom:16px;
}
.welcome-issue .field{ flex:1; min-width:240px; margin:0; }

.welcome-list{ display:flex; flex-direction:column; gap:10px; }
/* Строка переносится сама, а не по ширине окна. Точка перелома ниже
   смотрит на окно, а карточка стоит в колонке рядом с боковым меню и всегда
   заметно уже его: в промежутке правило не срабатывало, левый блок сжимался
   почти в ноль, имя вставало в три строки, «с 17.09 по 21.09.2026» сыпалось
   по слову в строку, а счётчик с бейджем налезали сверху. С переносом
   правая половина уходит вниз тогда, когда ей действительно не хватило
   места, при любой ширине колонки. */
.welcome-row{
  display:flex; align-items:center; justify-content:space-between;
  gap:10px 14px; flex-wrap:wrap; padding:16px 20px;
  text-decoration:none; color:inherit;
  transition: transform var(--spring), box-shadow var(--transition);
}
.welcome-row:hover{ transform: translateY(-1px); box-shadow: var(--shadow-lift); }
.welcome-row-main{ display:flex; flex-direction:column; gap:3px; min-width:0; flex:1 1 220px; }
.welcome-row-main b{ font-size:15px; }
/* Срок — одна короткая строка и переносу не подлежит: разорванная по словам
   дата не читается, а места она просит немного. */
.welcome-row-when{
  font-size:12.5px; color: var(--text-faint);
  font-variant-numeric: tabular-nums; white-space:nowrap;
}
.welcome-row-side{ display:flex; align-items:center; gap:12px; flex-shrink:0; }
.welcome-progress{
  font-size:12.5px; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
/* Отозванная и просроченная гасятся, а не прячутся: HR приходит сюда в том
   числе затем, чтобы увидеть, что ссылка не сработала. */
.welcome-row.is-revoked, .welcome-row.is-expired{ opacity:.6; }
.welcome-row.is-done{ border-color: rgba(48,209,88,.45); }

/* --- Панель: карточка одной ссылки ------------------------------------- */
.welcome-link-card{ padding:22px 24px; margin-bottom:16px; }
.welcome-link-row{ display:flex; gap:10px; margin:12px 0 18px; }
.welcome-link-row input{
  flex:1; min-width:0;
  /* Ссылка — строка, которую копируют целиком и не читают глазами, поэтому
     ей хватает того же шрифта, что и остальному: разбирать в ней символы по
     одному никому не нужно. */
  font-size:13px; color: var(--text-muted);
}
.welcome-facts{
  display:grid; grid-template-columns: repeat(auto-fit, minmax(160px,1fr));
  gap:14px; margin:0;
}
.welcome-facts dt{
  font-size:11px; text-transform:uppercase; letter-spacing:.08em;
  font-weight:700; color: var(--text-faint);
}
.welcome-facts dd{
  margin:3px 0 0; font-size:14px; font-weight:600;
  font-variant-numeric: tabular-nums;
}

.welcome-day-edit{ padding:16px 22px; margin-bottom:10px; }
.welcome-day-edit.is-done{ border-left:3px solid var(--accent-4); }
/* Свёрнутый день — одна строка, и она кликабельна целиком. Родную стрелку
   убираем: вместо неё своя, чтобы она стояла там же во всех браузерах. */
.welcome-day-edit > summary{ cursor:pointer; list-style:none; }
.welcome-day-edit > summary::-webkit-details-marker{ display:none; }
.welcome-day-edit > summary::after{
  content:'▾'; margin-left:10px; color:var(--text-faint); font-size:12px;
  transition: transform .15s ease; display:inline-block;
}
.welcome-day-edit[open] > summary::after{ transform:rotate(180deg); }
.welcome-day-edit[open] > summary{ margin-bottom:14px; }
.welcome-day-sum{ display:flex; flex-wrap:wrap; gap:9px; align-items:center; min-width:0; }
.welcome-day-when{ font-size:12px; color:var(--text-faint); font-variant-numeric:tabular-nums; }
.welcome-day-who{ font-size:12.5px; color:var(--text-muted); }
.welcome-day-head{
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; flex-wrap:wrap; margin-bottom:0;
}
.welcome-day-head h4{ margin:0; font-variant-numeric: tabular-nums; }
.welcome-day-mark{ font-size:12px; color: var(--text-faint); }
.welcome-day-form{
  display:grid; grid-template-columns: repeat(auto-fit, minmax(220px,1fr));
  gap:12px; align-items:end;
}
.welcome-day-form .field{ margin:0; }
/* Пояснение — во всю ширину. По классу, а не по `:nth-child`: первым
   ребёнком формы идёт скрытое поле CSRF, и счёт по номеру держался бы на
   том, что его никто не переставит. */
.welcome-day-form .field.is-wide{ grid-column: 1 / -1; }

.welcome-danger{
  display:flex; gap:10px; flex-wrap:wrap;
  margin-top:20px; padding-top:16px; border-top:1px solid var(--border);
}

/* --- Страница кандидата ------------------------------------------------ */
.wel-page{ padding: 30px 18px 60px; }
.wel-head{ text-align:center; margin-bottom:26px; }
.wel-head h1{ font-size: clamp(1.6rem, 4vw, 2.1rem); }
.wel-lead{ color: var(--text-muted); max-width: 520px; margin: 0 auto; }

.wel-banner{ padding:16px 20px; text-align:center; margin-bottom:18px; }
.wel-banner.is-done{ border-color: rgba(48,209,88,.45); }

.wel-days{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:14px; }
.wel-day{ padding:20px 22px; }
.wel-day-head{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:10px; margin-bottom:8px;
}
.wel-day-n{
  font-size:11.5px; font-weight:700; text-transform:uppercase;
  letter-spacing:.1em; color: var(--accent-1);
}
.wel-day-date{
  font-size:12.5px; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.wel-day-title{ font-size:18px; margin:0 0 6px; }
/* Перенос строки в тексте дня — это перенос строки: программа дня состоит из
   пунктов, и слитый в абзац список пунктов перестаёт быть списком. */
.wel-day-detail{ color: var(--text-muted); margin:0 0 14px; line-height:1.55; white-space:pre-line; }
.wel-map{ margin-bottom:12px; }
.wel-mark{ width:100%; }
/* Отзыв ко дню: свёрнут в одну строку, пока его не открыли, — страницу
   открывают каждое утро ради дней, а не ради пяти полей для текста подряд.
   Развёрнут сам, если человек уже что-то написал. */
/* Слова кандидата в карточке HR — цитата, а не ещё одно поле: их читают,
   и отличать их от того, что HR писала сама, нужно с одного взгляда. */
.welcome-day-note{
  margin:0 0 14px; padding:10px 14px;
  border-left:3px solid var(--accent-1);
  border-radius:4px 12px 12px 4px;
  background:linear-gradient(120deg, rgba(211,36,43,.05), rgba(255,183,140,.08));
}
.welcome-day-note p{ margin:0; font-size:13.5px; line-height:1.55; white-space:pre-line; }
.welcome-day-note cite{ display:block; margin-top:6px; font-size:11.5px; font-style:normal; color:var(--text-faint); }

/* Вступление: одна колонка текста и одна кнопка. Ширина ограничена не
   карточкой, а строкой — читать абзац в 120 символов поперёк экрана тяжело. */
.wel-intro{ padding:30px 32px 28px; }
.wel-intro h1{ font-size:clamp(1.5rem, 3.4vw, 2rem); margin:0 0 16px; }
.wel-intro p{ font-size:15px; line-height:1.7; margin:0 0 14px; max-width:62ch; }
.wel-intro-note{
  padding:12px 16px; border-left:3px solid var(--accent-1);
  border-radius:4px 12px 12px 4px; background:var(--surface);
  font-size:14px !important;
}
.wel-intro-go{ margin-top:20px; min-width:180px; }

/* Значок WhatsApp сразу за номером: маленький, не спорит с самим номером,
   но попадает пальцем — минимальная цель на телефоне около 32px. */
.wa-chip{
  display:inline-flex; align-items:center; justify-content:center;
  width:26px; height:26px; margin-left:4px; vertical-align:-6px;
  border-radius:50%; text-decoration:none; font-size:14px; line-height:1;
  background:rgba(37,211,102,.14);
  transition: background var(--transition), transform var(--transition);
}
.wa-chip:hover{ background:rgba(37,211,102,.26); transform:translateY(-1px); }

.wel-note{ margin-top:12px; }
.wel-note > summary{
  list-style:none; cursor:pointer; display:inline-flex; align-items:center; gap:6px;
  font-size:13px; font-weight:700; color:var(--text-muted);
}
.wel-note > summary::-webkit-details-marker{ display:none; }
.wel-note > summary::before{ content:'💬'; }
.wel-note textarea{ width:100%; margin-top:8px; min-height:84px; resize:vertical; }
.wel-note-foot{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:6px; }
.wel-note-when{ font-size:12px; color:var(--text-faint); }

/* Закрытый день не притворяется карточкой с содержимым: приглушённый фон и
   одна строка с датой — видно, что он есть, и видно, что он не сейчас. */
.wel-day.is-locked{ opacity:.55; }
.wel-day-locked{ margin:0; color: var(--text-faint); font-size:13.5px; }
.wel-day.is-today{ border-color: var(--accent-1); box-shadow: var(--shadow-red); }
.wel-day.is-done{ border-color: rgba(48,209,88,.45); }
.wel-day-done{ margin:0; color: var(--accent-4); font-weight:700; font-size:13.5px; }
.wel-day-rest{ margin:0; color: var(--text-muted); font-size:13.5px; }
/* Корзина в строке приглашения. Серой среди серых она читается как ещё одна
   служебная кнопка; краснеет только под курсором — увидеть её надо тогда,
   когда до неё дотянулись, а не всё время. */
.invite-trash{ font-size:15px; line-height:1; padding-left:10px; padding-right:10px; }
.invite-trash:hover{ background: var(--accent-3); border-color: var(--accent-3); color:#fff; }

/* --- Выгрузка реестра ----------------------------------------------------
   Панель — тот же выдвижной лист, что у карточки сотрудника, только короче:
   пара строк текста и решётка галочек. */
.staff-xls-form{ padding:18px 22px 0; }
.staff-xls-scope{ font-size:12.5px; color: var(--text-muted); margin:0 0 16px; }
.staff-xls-cols{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(168px,1fr));
  gap:6px 14px; margin-bottom:18px;
}
.staff-xls-col{
  display:flex; align-items:center; gap:8px; cursor:pointer;
  font-size:13px; padding:5px 8px; border-radius: var(--radius-sm);
  transition: background var(--transition);
}
.staff-xls-col:hover{ background: var(--surface-strong); }
.staff-xls-col input{ width:15px; height:15px; flex:none; accent-color: var(--accent-1); }
/* Закрытые колонки помечены и глазом: их отдают не всем, и человек должен
   видеть, что кладёт в файл персональные данные. */
.staff-xls-col.is-private span{ color: var(--accent-1); }

/* Две решётки галочек подряд — филиалы и колонки — без подписей читаются как
   одна длинная. Подпись разделяет их и говорит, что именно отмечают. */
.staff-xls-head{
  font-size:11px; letter-spacing:.09em; text-transform:uppercase;
  color: var(--text-muted); font-weight:600; margin:0 0 9px;
  display:flex; align-items:center; gap:8px;
}
.staff-xls-head::before{
  content:""; width:12px; height:2px; background: var(--accent-1);
  border-radius:2px; flex:none;
}
/* Строка под филиалами меняется на «Листов в файле: N», поэтому она прижата к
   решётке: это подпись к ней, а не отдельный абзац. */
.staff-xls-hint{ font-size:12px; color: var(--text-muted); margin:-12px 0 18px; }

/* --- Выбор темы ----------------------------------------------------------
   Образец темы — не квадратик цвета, а маленькая страница: тот же фон, тот же
   акцент, та же строка текста. Цвет в отрыве от того, где он лежит, ничего не
   говорит — выбирают не краску, а вид панели. */
.theme-picker{
  display:grid; grid-template-columns:repeat(2,1fr); gap:12px; margin-bottom:16px;
}
.theme-card{ display:block; cursor:pointer; }
/* Радиокнопка нужна форме и клавиатуре, но не глазу: сам образец и есть
   переключатель. Спрятана размером, а не display:none — иначе Tab её минует. */
.theme-card input{ position:absolute; width:1px; height:1px; opacity:0; }
.theme-swatch{
  display:block; height:76px; padding:12px; overflow:hidden;
  border-radius: var(--radius-sm); border:2px solid var(--line);
  background: linear-gradient(160deg, var(--bg-a), var(--bg-b) 55%, var(--bg-c));
  transition: transform var(--spring), border-color var(--transition),
              box-shadow var(--transition);
}
.theme-card:hover .theme-swatch{ transform: translateY(-2px); }
.theme-card input:focus-visible + .theme-swatch{ outline:2px solid var(--accent-1); outline-offset:2px; }
.theme-card input:checked + .theme-swatch{
  border-color: var(--accent-1); box-shadow: var(--shadow-red);
}
.tsw-accent{
  display:block; width:36px; height:9px; border-radius: var(--radius-pill);
  background: var(--accent-1); margin-bottom:11px;
}
.tsw-line{
  display:block; height:7px; border-radius: var(--radius-pill);
  background: var(--text); opacity:.5; margin-bottom:7px;
}
.tsw-line-short{ width:56%; opacity:.24; }
.theme-name{
  display:block; margin-top:9px; text-align:center;
  font-size:13px; font-weight:600; color: var(--text-muted);
  transition: color var(--transition);
}
.theme-card input:checked ~ .theme-name{ color: var(--text); }

/* --- Фотография аккаунта -------------------------------------------------
   В шапке — кружок, он же ссылка в свой профиль. Буква вместо снимка занимает
   ровно столько же места, поэтому шапка не дёргается, когда фотографию
   ставят или снимают. */
.topbar-me{
  width:34px; height:34px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center; overflow:hidden;
  border:1.5px solid var(--border-strong); background: var(--surface-strong);
  text-decoration:none; transition: border-color .15s ease, transform .15s ease;
}
.topbar-me:hover{ border-color: var(--accent-1); transform: translateY(-1px); }
.topbar-me img{ width:100%; height:100%; object-fit:cover; display:block; }
.topbar-me-letter{ font-weight:800; font-size:14px; color: var(--accent-1); }

.my-photo-row{ display:flex; gap:20px; align-items:flex-start; flex-wrap:wrap; }
.my-photo{
  width:104px; height:104px; border-radius:50%; object-fit:cover; flex:none;
  border:2px solid var(--border-strong); background: var(--surface-strong);
}
.my-photo-empty{
  display:flex; align-items:center; justify-content:center;
  font-size:38px; font-weight:800; color: var(--accent-1);
}
.my-photo-actions{ flex:1; min-width:180px; }

/* --- Путь до финиша ------------------------------------------------------
   Пять кружков и флаг. Линия слева от кружка закрашивается вместе с ним, а не
   считается процентами по ширине: так полоса остаётся верной при любом числе
   шагов и не разъезжается, когда у дня длинная подпись. */
.lvl{
  border:1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); padding:16px 18px 10px; margin-bottom:18px;
}
.lvl-head{ display:flex; flex-wrap:wrap; gap:8px; align-items:baseline; justify-content:space-between; margin-bottom:16px; }
.lvl-title{ font-size:13px; font-weight:700; letter-spacing:.02em; }
.lvl-count{ font-size:12.5px; color: var(--text-muted); }
.lvl-pct{ color: var(--accent-1); font-size:15px; margin-left:4px; }
.lvl-nodes{ display:flex; margin:0; padding:0; list-style:none; }
.lvl-node{
  position:relative; flex:1; min-width:0;
  display:flex; flex-direction:column; align-items:center; gap:7px;
}
/* Линия к предыдущему кружку. У первого её нет — слева от него ничего. */
.lvl-node::before{
  content:''; position:absolute; top:16px; right:50%; left:-50%; height:4px;
  background: var(--border-strong); border-radius:2px;
}
.lvl-node:first-child::before{ display:none; }
.lvl-node.is-done::before{ background: var(--accent-4); }
.lvl-dot{
  position:relative; z-index:1; flex:none;
  width:34px; height:34px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-size:13px; font-weight:800;
  background: var(--surface-strong); color: var(--text-faint);
  border:2px solid var(--border-strong);
}
.lvl-node.is-done .lvl-dot{ background: var(--accent-4); border-color: var(--accent-4); color:#fff; }
/* Следующий шаг — тот, на который человек идёт сегодня. Он единственный
   выделен: подсвеченные разом три «предстоящих» не говорят ничего. */
.lvl-node.is-next .lvl-dot{
  border-color: var(--accent-1); color: var(--accent-1);
  box-shadow:0 0 0 4px rgba(211,36,43,.14);
}
.lvl-label{
  font-size:11.5px; line-height:1.3; text-align:center; color: var(--text-muted);
  max-width:92px; overflow-wrap:anywhere;
}
.lvl-node.is-done .lvl-label{ color: var(--text); }
.lvl-node.is-next .lvl-label{ color: var(--accent-1); font-weight:700; }
.lvl-finish .lvl-dot{ font-size:16px; background: var(--surface-strong); }
.lvl-finish.is-done .lvl-dot{ background:#F7C948; border-color:#F7C948; }
.lvl.is-finished{ border-color: var(--accent-4); }

@media (max-width: 560px){
  .lvl-dot{ width:28px; height:28px; font-size:12px; }
  .lvl-node::before{ top:13px; }
  .lvl-label{ font-size:10.5px; max-width:60px; }
}

/* Смена ещё идёт: кнопки нет, но час назван — иначе пустое место под текстом
   читается как страница, которая не догрузилась. */
.wel-day-wait{ margin:0; color: var(--accent-2); font-weight:600; font-size:13.5px; }

/* Место, кто встречает, адрес, телефон. Две колонки: подпись слева узкой
   колонкой, значение справа — так четыре строки читаются взглядом сверху
   вниз, а не как сплошной абзац. */
.wel-facts{
  display:grid; grid-template-columns:auto 1fr; gap:6px 14px;
  margin:0 0 14px; font-size:14px;
}
.wel-facts dt{ color: var(--text-faint); font-size:12.5px; padding-top:1px; }
.wel-facts dd{ margin:0; font-weight:600; }
.wel-facts dd a{ color: var(--accent-1); text-decoration:none; }
.wel-facts dd a:hover{ text-decoration:underline; }

@media (max-width: 560px){
  .welcome-row{ flex-direction:column; align-items:flex-start; gap:8px; }
  .welcome-day-form{ grid-template-columns: 1fr; }
}

/* ---------- Памятка на странице первых дней ----------
   Длинный текст под короткими карточками дней: своя типографика, чтобы
   пятьдесят строк читались с телефона, и свёртка — потому что на третий день
   человек приходит сюда за кнопкой, а не за инструкцией. */
.wel-guide{ margin-top:22px; padding:0; }
.wel-guide > summary{
  display:flex; gap:14px; align-items:center; cursor:pointer; list-style:none;
  padding:20px 22px; border-radius:inherit;
}
.wel-guide > summary::-webkit-details-marker{ display:none; }
.wel-guide-ico{ font-size:22px; line-height:1; flex:none; }
.wel-guide-head-text{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.wel-guide-head-text strong{ font-family:var(--font-display); font-size:16px; }
.wel-guide-head-text em{ font-style:normal; font-size:13px; color:var(--text-muted); }
/* Стрелка, которая поворачивается: свёрнутый блок должен выглядеть свёрнутым,
   а не обрезанным. */
.wel-guide > summary::after{
  content:''; flex:none; margin-left:auto; width:9px; height:9px;
  border-right:2px solid var(--text-faint); border-bottom:2px solid var(--text-faint);
  transform: rotate(45deg); transition: transform var(--transition);
}
.wel-guide[open] > summary::after{ transform: rotate(225deg); }
.wel-guide-sec{ padding:0 22px; border-top:1px solid var(--border); }
.wel-guide-sec h2{
  font-size:12px; text-transform:uppercase; letter-spacing:.09em;
  font-family:var(--font-label); color:var(--accent-1); margin:18px 0 10px;
}
.wel-guide-sec h3{ font-size:15px; margin:14px 0 6px; }
.wel-guide-sec ul{ margin:0 0 10px; padding-left:20px; }
.wel-guide-sec li{ margin:5px 0; line-height:1.55; color:var(--text-muted); }
.wel-guide-sec li a{ color:var(--accent-1); font-weight:600; white-space:nowrap; }
.wel-guide-wish{
  margin:0; padding:16px 22px 20px; border-top:1px solid var(--border);
  font-style:italic; color:var(--text-muted); line-height:1.55;
}

/* Карта проезда в памятке новичка. Своей рамкой и подписью, чтобы читалась
   как часть инструкции, а не как картинка, забытая посреди текста. */
/* Карта чуть уже колонки и по центру: во всю ширину она перебивала текст
   памятки, ради которого страницу и открывают, — а прочитать по ней улицу
   хватает и в этом размере. */
.wel-guide-map{ margin:14px auto 4px; max-width:440px; }
.wel-guide-map img{
  display:block; width:100%; height:auto; border-radius: var(--radius-md);
  border:1px solid var(--border-strong); box-shadow: var(--shadow-soft);
}
.wel-guide-map a{ display:block; }
.wel-guide-map figcaption{
  margin-top:8px; font-size:12.5px; color:var(--text-muted); text-align:center;
}
.wel-guide-map figcaption a{ display:inline; color:var(--accent-1); font-weight:600; white-space:nowrap; }
