/* ==========================================================================
   FinanceSeyco — Design System

   iOS-style liquid glass: translucent panels floating over a slow field of
   light, continuous corner radii, specular highlights, spring easing. The
   accent is the red of the Seyco Group mark, on black and white — the panel is
   the company's own lockup rather than a palette invented next to it.

   Tokens first — change them here and every screen follows.
   ========================================================================== */

:root{
  /* --- Accent: deep navy, with a brighter partner for the gradients.
     Deliberately not the Seyco red of the logo and of the HR platform: two
     panels of the same company, told apart at a glance. --------------------- */
  --accent-1: #1A3D8F;        /* primary brand blue        */
  --accent-1-dark: #12285F;   /* pressed / hover-deep      */
  --accent-1-light: #3E74E8;  /* gradient partner          */
  --accent-tint: rgba(26,61,143,.11);
  /* A filled surface and a coloured word are two different jobs. `--accent-1`
     is the word: it sits on the page background. The pair below is the fill,
     and it is picked so white text on the lighter end still clears 4.5:1 —
     the old gradient started at #3E74E8, where it did not. */
  --accent-fill-a: #3569DC;
  --accent-fill-b: #1A3D8F;

  /* Translucent tints of the status colours and of the accent.

     Each is written twice on purpose. The first line is the literal value; the
     second recomputes it from the token above, so changing --danger changes
     every surface tinted with it. A browser without color-mix() cannot parse
     the second declaration, drops it, and keeps the first — same result, no
     fallback machinery. This is the fix for what kept happening by hand: the
     accent moved and a dozen hard-coded rgba() values stayed behind. */
  --tint-success: rgba(31,157,85,.16);
  --tint-success: color-mix(in srgb, var(--success) 16%, transparent);
  --tint-warn: rgba(245,165,36,.18);
  --tint-warn: color-mix(in srgb, var(--warn) 18%, transparent);
  --tint-danger: rgba(229,72,77,.16);
  --tint-danger: color-mix(in srgb, var(--danger) 16%, transparent);
  --tint-neutral: rgba(142,142,147,.20);
  --tint-neutral: color-mix(in srgb, var(--text-muted) 22%, transparent);
  --accent-glow: rgba(26,61,143,.52);
  --accent-glow: color-mix(in srgb, var(--accent-1) 52%, transparent);
  --ink: #111111;             /* the black of the wordmark */
  --danger: #E5484D;
  --success: #1F9D55;
  --warn: #F5A524;

  /* iOS squircles are flatter at the corner than a plain circle; the sizes
     below are the ones that read as "system", not as "rounded box". */
  --radius-xl: 32px;
  --radius-lg: 24px;
  --radius-md: 17px;
  --radius-sm: 12px;
  --radius-pill: 980px;

  /* Two faces, one job each. Inter reads at 13px in a dense table without
     turning to mush; Manrope is wider and rounder, so a heading and a number
     carry weight the body text does not. Both cover Cyrillic *and* the Kazakh
     extension, which is the requirement a three-language panel actually has.
     The system stack stays behind them for the first paint. */
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'SF Pro Text',
               'Segoe UI', Roboto, sans-serif;
  --font-display: 'Manrope', 'Inter', -apple-system, BlinkMacSystemFont,
                  'SF Pro Display', 'Segoe UI', sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  --shadow-soft: 0 1px 2px rgba(17,17,17,.05), 0 10px 30px -14px rgba(17,17,17,.16);
  --shadow-lift: 0 6px 14px rgba(17,17,17,.08), 0 26px 56px -20px rgba(17,17,17,.26);
  --shadow-accent: 0 10px 26px -6px rgba(26,61,143,.40);

  /* Two easings do all the work: `ease-ios` for anything that travels (the
     system's own decelerate curve), `spring` for anything that should feel
     like it has weight — buttons, cards, toasts. */
  --ease-ios: cubic-bezier(.32,.72,0,1);
  --spring: cubic-bezier(.34,1.42,.64,1);
  --transition: 260ms var(--ease-ios);
}

/* ---------- Light: paper white ----------
   The page is plain white; the only colour is the accent and the soft bloom
   behind the glass. The greys are the system label colours, so text on white
   sits at the contrast the OS itself uses.

   The glass surfaces are translucent, so the browser's own painting of native
   controls shows through them; `color-scheme` is what stops a device in dark
   mode from filling our light inputs with charcoal. */
:root, [data-theme="light"]{
  color-scheme: light;
  --bg: #FFFFFF;
  --bg-elevated: #FFFFFF;
  --surface: rgba(255,255,255,.58);
  --surface-strong: rgba(246,246,248,.86);
  --surface-solid: #FFFFFF;
  --border: rgba(0,0,0,.07);
  --line: rgba(0,0,0,.09);
  --text: #09090B;
  --text-muted: #5A5A61;
  --text-faint: #767680;
  --input-bg: rgba(255,255,255,.72);
  /* The thin bright line along the top edge of a glass panel — the single
     detail that makes it read as a lit surface rather than a grey box. */
  --sheen: rgba(255,255,255,.9);
  --sheen-soft: rgba(255,255,255,.45);
  --blob: .34;
}

/* ---------- Dark: true black ----------
   #000, not charcoal: on an OLED screen the background is then genuinely off,
   and the glass panels read as lit sheets floating on nothing. */
[data-theme="dark"]{
  color-scheme: dark;
  --bg: #000000;
  --bg-elevated: #0B0B0D;
  --surface: rgba(28,28,30,.62);
  --surface-strong: rgba(44,44,46,.78);
  --surface-solid: #0B0B0D;
  --border: rgba(255,255,255,.12);
  --line: rgba(255,255,255,.13);
  --text: #FFFFFF;
  --text-muted: #A2A2AA;
  --text-faint: #80808A;
  --input-bg: rgba(28,28,30,.72);
  --sheen: rgba(255,255,255,.14);
  --sheen-soft: rgba(255,255,255,.05);
  --blob: .42;
  /* The same blue, lifted so it holds its saturation against true black. */
  --accent-1: #4C7FF0;
  --accent-1-light: #6E9BFF;
  --accent-tint: rgba(76,127,240,.18);
  /* The accent itself is lifted for black; the fill is not, because white text
     on #6E9BFF came out at 2.7:1 — a button nobody could read comfortably. */
  --accent-fill-a: #3F6FE0;
  --accent-fill-b: #21418C;
  --shadow-soft: 0 1px 2px rgba(0,0,0,.35), 0 10px 30px -14px rgba(0,0,0,.7);
  --shadow-lift: 0 6px 14px rgba(0,0,0,.4), 0 26px 56px -20px rgba(0,0,0,.8);
  --shadow-accent: 0 10px 26px -6px rgba(76,127,240,.40);
}

*{ box-sizing: border-box; }

body{
  margin:0;
  min-height:100vh;
  font-family: var(--font-body);
  font-size:15px;
  line-height:1.55;
  letter-spacing:-.01em;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---------- Background field ---------------------------------------------
   Light behind the glass. Deliberately still: a blurred shape this large,
   moving under translucent panels, forces the browser to re-sample and re-blur
   the backdrop of every one of them on every frame — which is what the whole
   interface was stuttering on. Painted once, it costs nothing and looks the
   same. */
.field-bg{ position:fixed; inset:0; z-index:-1; overflow:hidden; }
.field-bg span{
  position:absolute; border-radius:50%; filter:blur(110px); opacity: var(--blob, .4);
}
.field-bg span:nth-child(1){
  width:56vw; height:56vw; left:-12vw; top:-16vw;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent-1-light) 40%, transparent), transparent 70%);
}
.field-bg span:nth-child(2){
  width:48vw; height:48vw; right:-14vw; bottom:-18vw; animation-delay:-15s;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent-1) 32%, transparent), transparent 70%);
}
.field-bg span:nth-child(3){
  width:34vw; height:34vw; left:42vw; top:48vh; animation-delay:-8s;
  /* A third light, not a third helping of the accent: two blues alone read as
     one flat wash. Deliberately not derived from a token. */
  background: radial-gradient(circle, rgba(120,86,232,.22), transparent 70%);
}

/* ---------- Typography ---------- */
h1,h2,h3{
  margin:0 0 10px; color:var(--text); font-family:var(--font-display);
  letter-spacing:-.03em; line-height:1.15;
  /* Optical sizing and a slightly tighter track: at display sizes the default
     spacing reads loose, and the tightening is what makes a heading look set
     rather than typed. */
  font-feature-settings:'ss01' 1, 'cv11' 1;
}
h1{ font-size:31px; font-weight:800; }
h2{ font-size:22px; font-weight:750; letter-spacing:-.025em; }
h3{ font-size:16.5px; font-weight:700; letter-spacing:-.02em; }
p{ margin:0 0 14px; color:var(--text-muted); }
a{ color:var(--accent-1); text-decoration:none; }
code{ font-family:var(--font-mono); font-size:.86em; background:var(--surface-strong);
      padding:2px 7px; border-radius:7px; }
/* Money only reads as money when the digits sit in a grid. */
.num, .money{ font-variant-numeric: tabular-nums; }

/* ---------- Liquid glass -------------------------------------------------
   Three layers stacked: the blurred backdrop, a top-to-bottom sheen that
   fakes a lit edge, and a soft outer shadow to lift it off the field. */
.glass{
  position:relative;
  background: var(--surface);
  border:1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft), inset 0 1px 0 var(--sheen);
  backdrop-filter: blur(30px) saturate(180%);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
}
.glass::after{
  /* Specular sweep across the top third. `inherit` on the radius keeps it
     glued to the corner no matter which radius the panel uses.
     z-index:-1 lays it under the content and over the panel's own fill: the
     backdrop-filter above makes the panel a stacking context, so -1 stays
     inside it. Painted on top, the sweep washed out whatever sat in the top
     third — in the light theme the logo tile and the heading came out pale. */
  content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  z-index:-1;
  background: linear-gradient(170deg, var(--sheen-soft) 0%, transparent 42%);
}

/* ---------- Buttons ---------- */
.btn{
  position:relative;
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font:inherit; font-weight:600; letter-spacing:-.01em;
  padding:13px 24px; border:1px solid transparent;
  border-radius: var(--radius-pill); cursor:pointer;
  background: var(--surface-strong); color: var(--text);
  transition: transform 220ms var(--spring), box-shadow var(--transition),
              background var(--transition), opacity var(--transition);
  -webkit-tap-highlight-color: transparent;
}
.btn:hover{ transform: translateY(-1.5px); }
/* iOS presses shrink; they do not ripple. */
.btn:active{ transform: scale(.965); transition-duration:90ms; }
.btn:focus-visible{ outline:none; box-shadow: 0 0 0 4px var(--accent-tint); }
.btn-primary{
  background: linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  color:#fff; box-shadow: var(--shadow-accent), inset 0 1px 0 rgba(255,255,255,.28);
}
.btn-primary:hover{ box-shadow: 0 14px 34px -8px var(--accent-glow), inset 0 1px 0 rgba(255,255,255,.3); }
.btn-ghost{ background:transparent; border-color:var(--line); color:var(--text-muted); }
.btn-ghost:hover{ background: var(--surface-strong); color:var(--text); }
.btn-sm{ padding:8px 16px; font-size:13px; }
.btn-block{ width:100%; }
.btn[disabled]{ opacity:.5; pointer-events:none; }
/* The spinner the sign-in button shows while the form is in flight. */
.btn.is-busy{ color:transparent; pointer-events:none; }
.btn.is-busy::before{
  content:''; position:absolute; width:18px; height:18px; border-radius:50%;
  border:2px solid rgba(255,255,255,.35); border-top-color:#fff;
  animation: spin 700ms linear infinite;
}
@keyframes spin{ to{ transform: rotate(360deg); } }

/* ---------- Fields ---------- */
.field{ margin-bottom:16px; }
.field label{
  display:block; margin-bottom:7px; font-size:12px; font-weight:600;
  letter-spacing:.02em; color:var(--text-muted);
}
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], select, textarea{
  width:100%; font:inherit; color:var(--text); padding:14px 18px;
  background: var(--input-bg); border:1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: inset 0 1px 0 var(--sheen-soft);
  transition: border-color var(--transition), box-shadow var(--transition),
              background var(--transition);
}
textarea{ min-height:110px; resize:vertical; }
input::placeholder, textarea::placeholder{ color:var(--text-faint); }
input:focus, select:focus, textarea:focus{
  outline:none; border-color: var(--accent-1);
  background: var(--surface-solid);
  box-shadow: 0 0 0 4px var(--accent-tint);
}
.password-field{ position:relative; }
.password-field input{ padding-right:52px; }
.password-eye{
  position:absolute; right:10px; top:50%; transform:translateY(-50%);
  border:0; background:transparent; cursor:pointer; font-size:16px;
  padding:6px 8px; border-radius:50%; opacity:.6; transition:opacity var(--transition);
}
.password-eye:hover{ opacity:1; }
.checkbox-row{
  display:flex; align-items:center; gap:9px; margin-bottom:20px;
  font-size:14px; color:var(--text-muted); cursor:pointer;
}
.checkbox-row input{ accent-color: var(--accent-1); width:17px; height:17px; }

/* ---------- Role picker -------------------------------------------------
   The development sign-in screen: one card per role, stacked. Radio inputs
   live inside the labels, so the whole card is the hit area and
   `:checked + .role-card` is what paints the chosen one. */
.role-picker{ display:grid; gap:8px; }
.role-option{ display:block; cursor:pointer; -webkit-tap-highlight-color: transparent; }
.role-option input{ position:absolute; opacity:0; pointer-events:none; }
.role-card{
  display:grid; grid-template-columns:auto 1fr; align-items:center;
  column-gap:13px; row-gap:1px; padding:12px 15px;
  background: var(--input-bg); border:1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: inset 0 1px 0 var(--sheen-soft);
  transition: transform 260ms var(--spring), background var(--transition),
              border-color var(--transition), box-shadow var(--transition);
}
.role-option:hover .role-card{ transform: translateY(-1.5px); }
.role-option:active .role-card{ transform: scale(.98); }
.role-ico{
  grid-row:1 / span 2; width:36px; height:36px; display:grid; place-items:center;
  border-radius:11px; font-size:16px; font-weight:700;
  background: var(--accent-tint); color: var(--accent-1);
  transition: background var(--transition), color var(--transition);
}
.role-name{ font-size:14.5px; font-weight:650; color:var(--text); letter-spacing:-.01em; }
.role-hint{ font-size:12.5px; color:var(--text-faint); line-height:1.35; }

.role-option input:checked + .role-card{
  border-color:transparent;
  background: linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  box-shadow: var(--shadow-accent), inset 0 1px 0 rgba(255,255,255,.26);
}
.role-option input:checked + .role-card .role-name{ color:#fff; }
.role-option input:checked + .role-card .role-hint{ color:rgba(255,255,255,.78); }
.role-option input:checked + .role-card .role-ico{
  background: rgba(255,255,255,.22); color:#fff;
}
/* The radio itself is invisible, so the focus ring has to be drawn on the card. */
.role-option input:focus-visible + .role-card{ box-shadow: 0 0 0 4px var(--accent-tint); }

/* ---------- Flash messages ---------- */
.flash-stack{
  position:fixed; top:16px; left:50%; transform:translateX(-50%);
  z-index:80; display:grid; gap:10px; width:min(440px, calc(100vw - 32px));
}
.flash{
  padding:13px 22px; border-radius: var(--radius-pill); color:#fff; font-weight:600;
  font-size:14px; text-align:center;
  box-shadow: var(--shadow-lift), inset 0 1px 0 rgba(255,255,255,.22);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  animation: flash-in 520ms var(--spring) both;
}
.flash-success{ background: linear-gradient(145deg, color-mix(in srgb, var(--success) 78%, #fff), var(--success)); }
.flash-error{ background: linear-gradient(145deg, color-mix(in srgb, var(--danger) 80%, #fff), var(--danger)); }
.flash-info{ background: linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b)); }
@keyframes flash-in{
  from{ opacity:0; transform: translateY(-22px) scale(.92); }
  to{ opacity:1; transform: translateY(0) scale(1); }
}

/* ---------- Auth / error card ---------- */
.auth-wrap{ min-height:100vh; display:grid; place-items:center; padding:24px; }
.auth-card{
  width:100%; max-width:430px; padding:40px 34px;
  border-radius: var(--radius-xl);
  animation: card-in 420ms var(--ease-ios) both;
}
@keyframes card-in{
  from{ opacity:0; transform: translateY(14px); }
  to{ opacity:1; transform:none; }
}
.auth-card h2{ text-align:center; font-size:25px; }
.auth-card .sub{ text-align:center; margin-bottom:26px; font-size:14.5px; }
.auth-card.center{ text-align:center; }
.error-code{
  font-size:74px; font-weight:800; letter-spacing:-.05em; line-height:1;
  background: linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  -webkit-background-clip:text; background-clip:text; color:transparent;
  margin-bottom:12px;
}

/* A banner the login page shows only while the password is switched off, so
   the state is never a surprise. */
.notice{
  display:flex; gap:10px; align-items:flex-start;
  padding:12px 16px; margin-bottom:22px;
  border-radius: var(--radius-md); border:1px solid var(--line);
  background: var(--accent-tint);
  font-size:13px; line-height:1.45; color:var(--text-muted); text-align:left;
}
.notice strong{ color:var(--text); display:block; font-size:13.5px; }
.notice-ico{ font-size:15px; line-height:1.35; }

/* ---------- Brand lockup ---------- */
/* The SF tile on its own; the wordmark only on the printed sheet — see the
   note in templates/brand.html. Alone in the sidebar corner it is a size up. */
.brand{ display:flex; align-items:center; gap:12px; color:var(--text); }
.brand-text{ display:grid; line-height:1.2; }

/* The mark: an S for SEYCO with a light stroke under it — the flourish of a
   signature, since signing is what the panel is for. The tab icons
   (static/images/favicon-*) are rendered from this same drawing. Colours are
   fixed, not theme tokens: the dark theme lightens --accent-1, and the tile
   must stay the same blue as the icon in the tab above it. Everything is in
   proportions of the tile, so one rule serves 42 px in the sidebar and 64 px
   on the sign-in card. */
.brand-mark{
  position:relative; flex:none; display:grid; place-items:center;
  width:42px; height:42px; border-radius:24%;
  background: linear-gradient(145deg, #3D72E6 0%, #1E47A8 55%, #142F78 100%);
  color:#fff; font-family:var(--font-display);
  font-size:25px; font-weight:800; line-height:1;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), inset 0 -2px 6px rgba(0,0,0,.18),
              0 6px 16px rgba(20,47,120,.30);
  user-select:none;
}
.brand-mark > span{ transform: translateY(-10%); }
.brand-mark::after{
  content:""; position:absolute; left:50%; bottom:19%;
  width:40%; height:7%; border-radius:99px;
  transform: translateX(-50%) rotate(-4deg);
  background: linear-gradient(90deg, #9EC2FF, #D6E6FF);
}
/* How the wordmark is actually set lives in one place, further down. */

/* ---------- Panel shell ---------- */
.shell{ display:flex; min-height:100vh; gap:18px; padding:18px; }
.sidebar{
  width:256px; flex:none; padding:22px 16px;
  display:flex; flex-direction:column; gap:26px; position:sticky; top:18px;
  height: calc(100vh - 36px);
  border-radius: var(--radius-xl);
}
.nav{ display:grid; gap:3px; }
.nav-item{
  position:relative;
  display:flex; align-items:center; gap:11px; padding:11px 15px;
  border-radius: var(--radius-md); color:var(--text-muted);
  font-weight:600; font-size:14.5px;
  transition: color var(--transition), background var(--transition),
              transform 220ms var(--spring);
}
.nav-item:hover{ background: var(--surface-strong); color:var(--text); }
.nav-item:active{ transform: scale(.97); }
.nav-item.is-active{
  color:#fff;
  background: linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  box-shadow: var(--shadow-accent), inset 0 1px 0 rgba(255,255,255,.26);
}
.sidebar-foot{ margin-top:auto; display:grid; gap:12px; }
.who{
  display:flex; align-items:center; gap:10px;
  padding:9px 11px; border-radius: var(--radius-md); background: var(--surface-strong);
}
.who-avatar{
  width:34px; height:34px; flex:none; border-radius:50%; display:grid; place-items:center;
  font-size:13px; font-weight:700; color:#fff;
  background: linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
}
.who-text{ display:grid; min-width:0; }
.who-text strong{ font-size:13.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.who-text small{ font-size:11.5px; color:var(--text-faint); }
.theme-toggle{
  justify-self:start; border:1px solid var(--line); background:transparent;
  width:36px; height:36px; border-radius:50%; cursor:pointer; font-size:15px;
  display:grid; place-items:center;
  transition: background var(--transition), transform 300ms var(--spring);
}
.theme-toggle:hover{ background: var(--surface-strong); transform: rotate(-18deg); }
.theme-toggle:active{ transform: scale(.9); }

.content{ flex:1; min-width:0; padding:6px 6px 48px; }

/* The panel keeps theme and language in its sidebar; the sign-in and error
   screens have no sidebar, so theirs float in the corner. Somebody who only
   reads Turkish has to be able to switch before signing in, not after. */
.floating-controls{
  position:fixed; top:18px; right:18px; z-index:70;
  display:flex; align-items:center; gap:8px;
}
.theme-float{
  width:42px; height:42px; flex:none; border-radius:50%; cursor:pointer; font-size:16px;
  display:grid; place-items:center;
  background: var(--surface-strong); border:1px solid var(--border);
  box-shadow: var(--shadow-soft), inset 0 1px 0 var(--sheen);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  transition: transform 300ms var(--spring), box-shadow var(--transition);
}
.theme-float:hover{ transform: rotate(-18deg) scale(1.06); box-shadow: var(--shadow-lift); }
.theme-float:active{ transform: scale(.92); }

/* ---------- Language switch ----------------------------------------------
   Four codes in one track. A POST per button rather than a link: a language is
   a change to the session, and a GET that changes state can be triggered by
   anything that embeds the URL. */
.foot-row{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.lang-switch{
  display:flex; gap:2px; padding:3px; margin:0;
  background: var(--input-bg); border:1px solid var(--border);
  border-radius: var(--radius-pill);
  box-shadow: inset 0 1px 2px rgba(0,0,0,.05);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
}
.lang-btn{
  font:inherit; font-size:12px; font-weight:600; letter-spacing:-.01em;
  padding:6px 10px; border:0; border-radius: var(--radius-pill);
  background:transparent; color:var(--text-muted); cursor:pointer;
  transition: transform 220ms var(--spring), background var(--transition),
              color var(--transition), box-shadow var(--transition);
  -webkit-tap-highlight-color: transparent;
}
.lang-btn:hover{ color:var(--text); background: var(--surface-strong); }
.lang-btn:active{ transform: scale(.94); }
.lang-btn:focus-visible{ outline:none; box-shadow: 0 0 0 3px var(--accent-tint); }
.lang-btn.is-active{
  color:#fff;
  background: linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  box-shadow: var(--shadow-accent), inset 0 1px 0 rgba(255,255,255,.26);
}

/* iOS large title: full size at the top of the page, shrinking into a compact
   glass bar once the page scrolls. `.is-stuck` is set from main.js. */
.page-head{
  position:sticky; top:8px; z-index:20;
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; margin-bottom:22px; padding:10px 14px; flex-wrap:wrap;
  border-radius: var(--radius-lg);
  border:1px solid transparent;
  transition: background 200ms var(--ease-ios), border-color 200ms var(--ease-ios);
}
/* `transform`, not `font-size`: scaling is done by the compositor, resizing
   text re-lays out the whole header — and the heading sits above the page, so
   that reflow reached everything under it. */
.page-head h1{
  margin:0; transform-origin:left center;
  transition: transform 200ms var(--ease-ios);
}
.page-head.is-stuck{
  background: var(--surface-strong); border-color: var(--border);
}
.page-head.is-stuck h1{ transform: scale(.74); }

/* ---------- Stat tiles ---------- */
.stat-grid{
  display:grid; gap:14px; margin-bottom:20px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.stat{
  padding:20px 22px; border-radius: var(--radius-lg);
  transition: transform 200ms var(--ease-ios);
}
.stat:hover{ transform: translateY(-3px); }
.stat-label{
  display:flex; align-items:center; gap:8px;
  font-size:12.5px; font-weight:600; color:var(--text-muted); margin-bottom:10px;
}
.stat-value{
  font-size:27px; font-weight:750; letter-spacing:-.035em; line-height:1.1;
  font-variant-numeric: tabular-nums; color:var(--text);
}
.stat-hint{ font-size:12.5px; color:var(--text-faint); margin:6px 0 0; }

/* ---------- Empty state ---------- */
.empty{ padding:52px 40px; text-align:center; max-width:660px; border-radius: var(--radius-xl); }
.empty-mark{
  width:68px; height:68px; margin:0 auto 18px; border-radius:21px;
  display:grid; place-items:center; font-size:31px; font-weight:800; color:#fff;
  background: linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  box-shadow: var(--shadow-accent), inset 0 1px 0 rgba(255,255,255,.3);
}
.empty-hint{ font-size:13.5px; color:var(--text-faint); margin-bottom:0; }

/* ---------- Tables (for the first finance screen) ---------- */
.table-wrap{ overflow-x:auto; border-radius: var(--radius-lg); }
table{ width:100%; border-collapse:collapse; background: var(--surface-solid); }
th, td{ padding:14px 18px; text-align:left; border-bottom:1px solid var(--line); }
th{
  font-size:11.5px; font-weight:650; letter-spacing:.06em; text-transform:uppercase;
  color:var(--text-muted); background: var(--surface-strong);
}
td.num, th.num{ text-align:right; font-variant-numeric: tabular-nums; }
tbody tr:last-child td{ border-bottom:0; }
tbody tr{ transition: background 160ms var(--ease-ios); }
tbody tr:hover{ background: var(--surface-strong); }

/* ---------- Motion policy -------------------------------------------------
   Pages arrive already in place: no staged entrances, nothing that loops, and
   nothing animated behind a translucent surface. Movement is kept for what a
   person causes — a press, a modal, a toast — where it confirms an action
   rather than delaying the content. */

/* Circular reveal when the theme flips, driven from main.js. Without these the
   browser cross-fades instead, which on a full-page colour change looks like a
   flash rather than a wipe. */
::view-transition-old(root),
::view-transition-new(root){ animation:none; mix-blend-mode:normal; }
::view-transition-old(root){ z-index:0; }
::view-transition-new(root){ z-index:1; }

/* ---------- Mobile ---------- */
@media (max-width: 860px){
  h1{ font-size:25px; }
  .shell{ flex-direction:column; padding:12px 12px 96px; }
  .sidebar{
    width:auto; height:auto; position:static; flex-direction:row;
    align-items:center; gap:14px; padding:12px 14px;
  }
  /* The nav becomes an iOS tab bar pinned to the bottom edge. */
  .nav{
    position:fixed; left:12px; right:12px; bottom:12px; z-index:60;
    grid-auto-flow:column; gap:6px; padding:8px;
    background: var(--surface-strong); border:1px solid var(--border);
    border-radius: var(--radius-xl); box-shadow: var(--shadow-lift);
    backdrop-filter: blur(30px) saturate(180%);
    -webkit-backdrop-filter: blur(30px) saturate(180%);
  }
  /* Text, not icons: the label is the same word in all four languages the
     panel speaks, and it cannot fall back to a box. The bar scrolls when the
     words do not fit rather than squeezing them. */
  .nav{ overflow-x:auto; scrollbar-width:none; }
  .nav::-webkit-scrollbar{ display:none; }
  .nav-item{ font-size:12px; padding:9px 12px; white-space:nowrap; }
  .sidebar-foot{ margin:0 0 0 auto; grid-auto-flow:column; align-items:center; gap:10px; }
  .lang-btn{ padding:6px 8px; font-size:11.5px; }
  .floating-controls{ top:12px; right:12px; }
  .who{ background:transparent; padding:0; }
  .who-text{ display:none; }
  .page-head{ top:0; }
}

/* ---------- Reduced motion -----------------------------------------------
   Everything above is decoration; nothing here carries meaning that is lost
   when it stops. Animations collapse to their end state rather than turning
   into an instant jump mid-flight. */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important;
  }
  .field-bg span{ animation:none; }
}

/* ==========================================================================
   Wordmark
   ========================================================================== */

/* With nothing beside it, the name has to hold the corner on its own: caps,
   opened up. Tight tracking is for long words read as shapes; a five-letter
   wordmark wants air between the letters instead.

   The qualifier under it is the one place the accent appears in the lockup —
   the same trick as the printed version, where the name is black and the line
   under it is the company colour. */
.brand-text strong{
  font-size:17px; font-weight:800; letter-spacing:.11em;
  /* Caps have no descenders, so the optical gap under them reads wider than it
     measures; the negative margin takes that back. */
  margin-bottom:-1px;
}
.brand-text small{
  font-size:9.5px; font-weight:700; color: var(--accent-1);
  letter-spacing:.3em; text-transform:uppercase;
}

/* On the sign-in card there is nothing above it and nothing beside it, so it
   is set as a title rather than as a label: the tile goes on top, larger, and
   the name is centred under it. */
.brand-lg{ flex-direction:column; justify-content:center; gap:18px; margin-bottom:28px; }
.brand-lg .brand-mark{
  width:64px; height:64px; font-size:38px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.25),
              0 10px 26px rgba(26,61,143,.32);
}
.brand-lg .brand-text{ text-align:center; }
.brand-lg .brand-text strong{ font-size:31px; letter-spacing:.14em; margin-bottom:1px; }
.brand-lg .brand-text small{ font-size:11px; letter-spacing:.42em; }

/* Centred text with wide tracking hangs to the left: the space after the last
   letter is real, the one before the first is not. */
.brand-lg .brand-text strong,
.brand-lg .brand-text small{ text-indent:.14em; }

/* --- Анимация логотипа на входе -------------------------------------------
   Только на большом лого страницы входа (в сайдбаре оно статично — дёргать
   его при каждом переходе было бы навязчиво). SEYCO поднимается, FINANCE
   проявляется, разводя буквы к финальному трекингу — сдержанно, «дорого»,
   в тему финансов. Тонкая линия прочерчивается под словом. Первой, раньше
   слов, появляется плитка SF: она чуть подрастает до своего размера. */
.brand-lg .brand-mark{
  animation: mark-lg-in 560ms var(--ease-ios) 40ms both;
}
.brand-lg .brand-text strong{
  animation: seyco-lg-in 620ms var(--ease-ios) 140ms both;
}
.brand-lg .brand-text small{
  position: relative;
  animation: fin-lg-in 760ms var(--ease-ios) 380ms both;
}
.brand-lg .brand-text small::after{
  content:""; position:absolute; left:50%; bottom:-8px; height:2px; width:0;
  border-radius:2px; transform:translateX(-50%);
  background: linear-gradient(90deg, var(--accent-1-light), var(--accent-1));
  animation: fin-rule 620ms var(--ease-ios) 720ms both;
}
@keyframes mark-lg-in{
  from{ opacity:0; transform: scale(.82); }
  to{   opacity:1; transform: none; }
}
@keyframes seyco-lg-in{
  from{ opacity:0; transform: translateY(12px); }
  to{   opacity:1; transform: none; }
}
@keyframes fin-lg-in{
  from{ opacity:0; letter-spacing:.12em; }
  to{   opacity:1; letter-spacing:.42em; }
}
@keyframes fin-rule{
  from{ width:0; opacity:0; }
  to{   width:60%; opacity:1; }
}
/* Кто отключил анимации в системе — получает готовый кадр без движения. */
@media (prefers-reduced-motion: reduce){
  .brand-lg .brand-mark,
  .brand-lg .brand-text strong,
  .brand-lg .brand-text small,
  .brand-lg .brand-text small::after{ animation: none; }
  .brand-lg .brand-text small::after{ width:60%; opacity:1; }
}

/* ==========================================================================
   Document workflow
   ========================================================================== */

.visually-hidden{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.lead{ max-width:70ch; margin-bottom:20px; }
.muted{ color:var(--text-faint); }
.mono{ font-family:var(--font-mono); font-size:.9em; }
.narrow{ max-width:520px; }
.mt{ margin-top:14px; }
.section-title{ margin:26px 0 12px; font-size:16px; }

.card{ padding:22px 24px; margin-bottom:16px; }
.card-lead{ margin-bottom:18px; }
.card-head{
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; margin-bottom:14px;
}
.card-head h3{ margin:0; }
.card-foot{
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; margin-top:16px; padding-top:14px; border-top:1px solid var(--line);
}
.two-col{ display:grid; gap:16px; grid-template-columns:repeat(auto-fit, minmax(320px, 1fr)); }
.form-grid{ display:grid; gap:14px; grid-template-columns:repeat(auto-fit, minmax(190px, 1fr)); }
.form-grid .field{ margin-bottom:0; }
.field-wide{ grid-column:1 / -1; }
.field-submit{ display:flex; align-items:flex-end; }

/* Language switch and the role picker are defined once, up with the other
   controls. A second copy lived here and won by being later in the file: its
   `.role-card` was a flex row, which put the role's hint beside its name
   instead of under it. */

/* ---------- Badges, chips, verdicts ------------------------------------- */
.badge{
  display:inline-flex; align-items:center; gap:5px;
  padding:3px 10px; border-radius:var(--radius-pill);
  font-size:11.5px; font-weight:700; letter-spacing:.01em; white-space:nowrap;
  background:var(--surface-strong); color:var(--text-muted);
}
.badge-urgent{ background:var(--accent-1); color:#fff; }
.badge-high{ background:var(--tint-warn); color:var(--warn); }
.badge-muted{ background:var(--surface-strong); color:var(--text-faint); }
.badge-processing{ background:var(--tint-neutral); color:var(--text-muted); }
.badge-pending-admin12,
.badge-pending-admin1,
.badge-pending-admin2,
.badge-pending-admin3{ background:var(--accent-tint); color:var(--accent-1); }
.badge-approved{ background:var(--tint-success); color:var(--success); }
.badge-rejected{ background:var(--tint-danger); color:var(--danger); }
.badge-needs-review{ background:var(--tint-warn); color:var(--warn); }

.chip{
  display:inline-flex; align-items:center; gap:6px;
  padding:3px 11px; border-radius:var(--radius-pill);
  font-size:12px; font-weight:600; white-space:nowrap;
  color:var(--chip, var(--accent-1));
  background:color-mix(in srgb, var(--chip, var(--accent-1)) 14%, transparent);
}
.chip-empty{ color:var(--text-faint); background:var(--surface-strong); }

.verdict{
  display:inline-flex; align-items:center; gap:6px;
  padding:6px 13px; border-radius:var(--radius-pill);
  font-size:13px; font-weight:650;
}
.verdict-ok{ background:var(--tint-success); color:var(--success); }
.verdict-warn{ background:var(--tint-warn); color:var(--warn); }
.verdict-unknown{ background:var(--surface-strong); color:var(--text-muted); }
.verdicts{ display:flex; flex-wrap:wrap; gap:8px; margin:14px 0; }
.ok-tick{ color:var(--success); font-weight:700; }
.warn-tick{ color:var(--warn); font-weight:700; }

.pin-mark{
  display:inline-block; padding:1px 7px; border-radius:var(--radius-pill);
  font-size:10px; font-weight:800; letter-spacing:.08em;
  background:var(--accent-1); color:#fff;
}

/* ---------- Dashboard cards ---------------------------------------------- */
.card-grid{
  display:grid; gap:12px; margin-bottom:18px;
  grid-template-columns:repeat(auto-fit, minmax(158px, 1fr));
}
.count-card{
  display:grid; gap:2px; padding:18px 20px; color:var(--text);
  border-radius:var(--radius-lg);
  transition: transform 200ms var(--ease-ios);
}
.count-card:hover{ transform:translateY(-3px); }
.count-card:active{ transform:scale(.98); }
.count-value{ font-size:30px; font-weight:750; letter-spacing:-.035em; font-variant-numeric:tabular-nums; }
.count-label{ font-size:12.5px; color:var(--text-muted); font-weight:600; }
/* An urgent count that is not zero should be impossible to scroll past. */
.count-card.is-hot{
  background:linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  border-color:transparent; color:#fff; box-shadow:var(--shadow-accent);
}
.count-card.is-hot .count-card.is-hot .count-label{ color:rgba(255,255,255,.85); }

/* ---------- Document rows ------------------------------------------------ */
.doc-list{ display:grid; gap:10px; }
.doc-row{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:14px 18px; color:var(--text);
  background:var(--surface-strong); border:1px solid var(--border);
  border-radius:var(--radius-md); box-shadow:var(--shadow-soft);
  /* Transform only. Animating box-shadow repaints the row on every frame, and
     a list is where that is felt. */
  transition: transform 180ms var(--ease-ios), border-color var(--transition);
}
.doc-row:hover{ transform:translateY(-2px); border-color:var(--line); }
.doc-row:active{ transform:scale(.995); }
/* Urgent rows carry a red edge — the queue is sorted by it too, so the colour
   confirms the order rather than being the only signal. */
.doc-row.is-urgent{
  border-color:color-mix(in srgb, var(--accent-1) 45%, transparent);
  box-shadow:var(--shadow-soft), inset 3px 0 0 var(--accent-1);
}
.doc-main{ display:grid; gap:3px; min-width:0; }
.doc-top{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
/* The number is an identifier, not code. The mono face was drawing it with
   slab hyphens and slots too wide for four digits; the display face with
   tabular figures keeps the columns aligned down the list and still reads as
   one word. */
.doc-number{
  font-family:var(--font-display); font-size:12.5px; font-weight:700;
  letter-spacing:.04em; color:var(--text-faint);
  font-variant-numeric: tabular-nums lining-nums;
}
.doc-title{ font-weight:650; font-size:14.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.doc-meta{ font-size:12.5px; color:var(--text-faint); }
.doc-side{ display:grid; gap:6px; justify-items:end; flex:none; text-align:right; }
.doc-amount{ font-weight:700; font-variant-numeric:tabular-nums; white-space:nowrap; }

/* ---------- Upload ------------------------------------------------------- */
.upload-form{ max-width:760px; }
.dropzone{
  display:grid; place-items:center; gap:6px; padding:44px 24px; cursor:pointer;
  border:2px dashed var(--line); border-radius:var(--radius-lg);
  background:var(--input-bg); text-align:center;
  transition: border-color var(--transition), background var(--transition),
              transform 220ms var(--spring);
}
.dropzone:hover, .dropzone.is-over{
  border-color:var(--accent-1); background:var(--accent-tint);
}
.dropzone.is-over{ transform:scale(1.01); }
.dropzone.has-file{ border-style:solid; border-color:var(--success); }
.dropzone-ico{
  width:46px; height:46px; display:grid; place-items:center; border-radius:15px;
  font-size:21px; color:#fff;
  background:linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  box-shadow:var(--shadow-accent);
}
.dropzone-text{ font-weight:650; }
.dropzone-hint{ font-size:12.5px; color:var(--text-faint); }

/* The URGENT control: a switch that looks like the button the specification
   asks for, and turns red the moment it is on. */
.urgent-switch{ display:block; cursor:pointer; margin-top:4px; }
.urgent-switch input{ position:absolute; opacity:0; pointer-events:none; }
.urgent-face{
  display:flex; align-items:center; gap:14px; padding:14px 18px;
  border:1px solid var(--line); border-radius:var(--radius-md);
  background:var(--input-bg);
  transition: background var(--transition), border-color var(--transition),
              transform 200ms var(--spring);
}
.urgent-switch:active .urgent-face{ transform:scale(.99); }
.urgent-switch input:checked + .urgent-face{
  background:linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  border-color:transparent; color:#fff; box-shadow:var(--shadow-accent);
}
.urgent-switch input:checked + .urgent-face small{ color:rgba(255,255,255,.85); }
.urgent-switch input:focus-visible + .urgent-face{ box-shadow:0 0 0 4px var(--accent-tint); }
.urgent-bolt{ font-size:22px; }
.urgent-body{ display:grid; }
.urgent-body strong{ letter-spacing:.06em; font-size:14px; }
.urgent-body small{ font-size:12.5px; color:var(--text-faint); }
.form-foot{
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin-top:4px;
}
.foot-note{ margin:0; font-size:13px; max-width:46ch; }

/* ---------- Review layout ------------------------------------------------ */
.review{ display:grid; gap:16px; grid-template-columns:minmax(0, 1.05fr) minmax(0, .95fr); }
.review-doc{ padding:14px; position:sticky; top:74px; height:calc(100vh - 110px); display:flex; flex-direction:column; }
.review-doc-head{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:4px 6px 12px;
}
.review-doc-head strong{ display:block; font-size:14.5px; }
.review-doc-head small{ font-size:12px; color:var(--text-faint); }
.pdf-frame{
  flex:1; width:100%; border:0; border-radius:var(--radius-md);
  background:var(--surface-solid);
}
.review-side{ min-width:0; }

.fact-row{ display:flex; flex-wrap:wrap; gap:8px; margin-bottom:14px; }
.facts{ display:grid; grid-template-columns:auto 1fr; gap:6px 16px; margin:0; }
.facts dt{ font-size:12.5px; color:var(--text-faint); }
.facts dd{ margin:0; font-size:13.5px; }
.quote{
  margin:4px 0 0; padding:8px 12px; font-size:13px;
  border-left:3px solid var(--line); background:var(--surface-strong);
  border-radius:0 var(--radius-sm) var(--radius-sm) 0; color:var(--text-muted);
}

/* ---------- AI analysis block -------------------------------------------- */
.ai-card{ border-color:color-mix(in srgb, var(--accent-1) 22%, var(--border)); }
.ai-summary{ font-size:14.5px; color:var(--text); margin-bottom:12px; }
.ai-note{ font-size:13px; margin:6px 0; }
.ai-disclaimer{
  font-size:12px; color:var(--text-faint); margin:10px 0 0;
  padding:9px 12px; border-radius:var(--radius-sm); background:var(--surface-strong);
}
.risk{
  padding:4px 11px; border-radius:var(--radius-pill);
  font-size:11.5px; font-weight:700;
}
.risk-low{ background:var(--tint-success); color:var(--success); }
.risk-medium{ background:var(--tint-warn); color:var(--warn); }
.risk-high{ background:var(--tint-danger); color:var(--danger); }
.risk-list{ margin-top:14px; font-size:13px; }
.risk-list ul{ margin:6px 0 0; padding-left:18px; color:var(--text-muted); }
.risk-list li{ margin-bottom:4px; }

/* ---------- Recognised fields -------------------------------------------- */
.fields{ display:grid; gap:1px; background:var(--line); border-radius:var(--radius-md); overflow:hidden; }
.field-row{
  display:grid; grid-template-columns:150px 1fr auto; align-items:center; gap:10px;
  padding:10px 14px; background:var(--surface-solid);
}
.field-row.is-weak{ background:color-mix(in srgb, var(--warn) 7%, var(--surface-solid)); }
.field-key{ font-size:12.5px; color:var(--text-faint); }
.field-value{ font-size:14px; display:flex; align-items:center; gap:7px; min-width:0; }
.field-value > span:first-child{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tag{
  width:18px; height:18px; flex:none; display:grid; place-items:center;
  border-radius:50%; font-size:10px; font-weight:800;
}
.tag-ok{ background:var(--tint-success); color:var(--success); }
.tag-warn{ background:var(--tint-warn); color:var(--warn); }
/* The edit form replaces the value in place; it is hidden until asked for, so
   a screen of read-only facts does not look like a screen of inputs. */
.field-edit{ display:none; grid-column:1 / -1; gap:8px; }
.field-row.is-editing .field-edit{ display:flex; }
.field-row.is-editing .field-value{ opacity:.45; }
.field-input{ flex:1; padding:8px 12px; border-radius:var(--radius-sm); }
.field-toggle{ padding:4px 10px; }

/* ---------- Stage track --------------------------------------------------- */
.stage-track{ display:grid; gap:8px; margin-bottom:16px; }
.stage-pill{
  display:flex; align-items:flex-start; gap:12px; padding:11px 14px;
  border-radius:var(--radius-md); border:1px solid var(--line);
  background:var(--surface-strong);
}
.stage-num{
  width:26px; height:26px; flex:none; display:grid; place-items:center;
  border-radius:50%; font-size:12px; font-weight:800;
  background:var(--surface-solid); color:var(--text-faint);
}
.stage-body{ display:grid; gap:1px; min-width:0; }
.stage-body strong{ font-size:13.5px; }
.stage-body small{ font-size:12px; color:var(--text-muted); }
.stage-who{ color:var(--text-faint) !important; }
.stage-pill.is-confirmed{ border-color:color-mix(in srgb, var(--success) 40%, transparent); }
.stage-pill.is-confirmed .stage-num{ background:var(--success); color:#fff; }
.stage-pill.is-waiting{ border-color:color-mix(in srgb, var(--accent-1) 45%, transparent); }
.stage-pill.is-waiting .stage-num{ background:var(--accent-1); color:#fff; }
.stage-pill.is-rejected{ border-color:color-mix(in srgb, var(--danger) 40%, transparent); }
.stage-pill.is-rejected .stage-num{ background:var(--danger); color:#fff; }
.stage-pill.is-review .stage-num{ background:var(--warn); color:#fff; }
.stage-pill.is-blocked{ opacity:.6; }

/* ---------- Timeline ------------------------------------------------------ */
.timeline{ list-style:none; margin:0; padding:0 0 0 18px; position:relative; }
.timeline::before{
  content:''; position:absolute; left:4px; top:6px; bottom:6px;
  width:2px; background:var(--line); border-radius:2px;
}
.timeline-item{ position:relative; padding:0 0 14px 6px; }
.timeline-item:last-child{ padding-bottom:0; }
.timeline-dot{
  position:absolute; left:-18px; top:5px; width:10px; height:10px;
  border-radius:50%; background:var(--text-faint);
  box-shadow:0 0 0 3px var(--bg);
}
.timeline-item.is-confirmed .timeline-dot{ background:var(--success); }
.timeline-item.is-rejected .timeline-dot{ background:var(--danger); }
.timeline-item.is-sent_to_review .timeline-dot{ background:var(--warn); }
.timeline-item.is-uploaded .timeline-dot{ background:var(--accent-1); }
.timeline-body strong{ font-size:13.5px; margin-right:6px; }
.timeline-body small{ display:block; font-size:12px; color:var(--text-faint); }
.timeline-compact .timeline-item{ padding-bottom:10px; }

/* ---------- Decision ------------------------------------------------------ */
.decide{ border-color:color-mix(in srgb, var(--accent-1) 30%, var(--border)); }
.decide-actions{ display:flex; flex-wrap:wrap; gap:10px; }
.btn-lg{ padding:15px 28px; font-size:15px; letter-spacing:.02em; }
.btn-danger{ background:var(--tint-danger); color:var(--danger); border-color:transparent; }
.btn-danger:hover{ background:var(--danger); color:#fff; }
.btn-warn{ background:var(--tint-warn); color:var(--warn); border-color:transparent; }
.btn-warn:hover{ background:var(--warn); color:#fff; }
.btn-pin{ background:var(--surface-strong); border-color:var(--accent-1); color:var(--accent-1); }
.btn-pin:hover{ background:var(--accent-tint); }

/* ---------- Modal --------------------------------------------------------- */
.modal{
  width:min(440px, calc(100vw - 32px)); padding:26px 28px; border:1px solid var(--border);
  border-radius:var(--radius-xl); color:var(--text); background:var(--surface-strong);
  box-shadow:var(--shadow-lift);
  backdrop-filter: blur(30px) saturate(180%);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
}
.modal::backdrop{ background:rgba(0,0,0,.45); backdrop-filter:blur(4px); }
.modal[open]{ animation: modal-in 380ms var(--spring) both; }
@keyframes modal-in{
  from{ opacity:0; transform:translateY(18px) scale(.94); }
  to{ opacity:1; transform:none; }
}
.modal h3{ margin-bottom:6px; }
.modal-actions{ display:flex; gap:10px; justify-content:flex-end; margin-top:18px; }
/* The PIN reads as a code, not as a word: spaced digits in the mono face. */
.pin-input{ font-family:var(--font-mono); letter-spacing:.42em; font-size:17px; }

/* ---------- Filters ------------------------------------------------------- */
.filters{ padding:16px 18px; margin-bottom:16px; }
.filter-search{ display:flex; gap:10px; margin-bottom:12px; }
.filter-search input{ flex:1; }
.chip-row{ display:flex; flex-wrap:wrap; gap:7px; }
.chip-btn{
  font:inherit; font-size:12.5px; font-weight:600; cursor:pointer;
  padding:6px 14px; border-radius:var(--radius-pill);
  border:1px solid var(--line); background:transparent; color:var(--text-muted);
  transition: background var(--transition), color var(--transition),
              border-color var(--transition), transform 180ms var(--spring);
}
.chip-btn:hover{ background:var(--surface-strong); color:var(--text); }
.chip-btn:active{ transform:scale(.95); }
.chip-btn.is-active{
  background:linear-gradient(145deg, var(--accent-fill-a), var(--accent-fill-b));
  border-color:transparent; color:#fff;
}
.filter-more{ margin-top:14px; }
.filter-more summary{
  cursor:pointer; font-size:13px; font-weight:650; color:var(--text-muted);
  padding:6px 0;
}
.filter-grid{
  display:grid; gap:12px; margin-top:12px;
  grid-template-columns:repeat(auto-fit, minmax(170px, 1fr));
}
.filter-grid .field{ margin-bottom:0; }
.filter-foot{ display:flex; justify-content:flex-end; gap:10px; margin-top:14px; }

/* ---------- Category bars ------------------------------------------------- */
.cat-bars{ display:grid; gap:10px; }
.cat-bar{ display:grid; grid-template-columns:1fr 2fr auto; align-items:center; gap:12px; }
.cat-name{ font-size:13.5px; }
.cat-name small{ color:var(--text-faint); }
.cat-track{ height:8px; border-radius:4px; background:var(--surface-strong); overflow:hidden; }
.cat-fill{
  display:block; height:100%; width:var(--w, 0%); border-radius:4px;
  background:var(--chip, var(--accent-1));
  transition: width 700ms var(--ease-ios);
}
.cat-count{ font-variant-numeric:tabular-nums; font-size:13px; color:var(--text-muted); }
.cat-cards{ display:grid; gap:14px; grid-template-columns:repeat(auto-fit, minmax(320px, 1fr)); }
.cat-card{ margin:0; }
.cat-dot{
  display:inline-block; width:10px; height:10px; border-radius:50%;
  background:var(--chip); margin-right:8px;
}
.add-form summary{ cursor:pointer; font-weight:650; }
.add-form[open] summary{ margin-bottom:16px; }
.cell-input{ padding:7px 11px; border-radius:var(--radius-sm); font-size:13px; }
.row-denied{ background:color-mix(in srgb, var(--danger) 8%, transparent); }
.nav-count{
  margin-left:auto; padding:1px 8px; border-radius:var(--radius-pill);
  font-size:11px; font-weight:700; background:var(--accent-1); color:#fff;
}

/* ---------- Mobile -------------------------------------------------------- */
@media (max-width: 1100px){
  .review{ grid-template-columns:1fr; }
  .review-doc{ position:static; height:auto; }
  .pdf-frame{ height:62vh; }
}
@media (max-width: 860px){
  .field-row{ grid-template-columns:1fr; gap:4px; }
  .doc-row{ flex-direction:column; align-items:flex-start; gap:10px; }
  .doc-side{ justify-items:start; text-align:left; flex-direction:row; display:flex; gap:10px; }
  .lang-switch{ margin-left:0; }
}


/* ---------- Type: the display face on the things that carry weight -------- */
.stat-value, .count-value, .doc-amount, .error-code, .brand-text strong{
  font-family: var(--font-display);
  /* Lining figures of one width, so a column of money does not shuffle as the
     numbers change. */
  font-variant-numeric: tabular-nums lining-nums;
}
.stat-value, .count-value{ letter-spacing:-.04em; }
/* Inter's default comma sits low next to a digit; the contextual set fixes the
   spacing in "2 450 000,00" without touching anything else. */
body{ font-feature-settings:'cv05' 1, 'cv11' 1, 'ss03' 1; }

/* ==========================================================================
   Refinements

   Last in the file on purpose: everything here sharpens what is defined above,
   and the media query at the end deliberately overrides it. Anything that has
   to win has to come last — that is the only ordering rule this sheet has.
   ========================================================================== */

::selection{ background: var(--accent-1); color:#fff; }

/* A heading breaks where the lines come out even, rather than dropping one
   orphan word onto the last line. Browsers without it just wrap as before. */
h1, h2, h3{ text-wrap: balance; }
p, .sub, .lead, .role-hint, .stat-hint{ text-wrap: pretty; }

/* One ring for anything keyboard-reachable that has not drawn its own. */
:focus-visible{ outline:2px solid var(--accent-1); outline-offset:2px; }

/* Without this a long queue gets a slab of system grey down its side, which is
   the one part of the page the design does not reach. */
*{ scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
::-webkit-scrollbar{ width:11px; height:11px; }
::-webkit-scrollbar-track{ background:transparent; }
::-webkit-scrollbar-thumb{
  background: var(--line); border-radius:11px;
  border:3px solid transparent; background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover{ background: var(--text-faint); background-clip: content-box; }

/* The buttons that sit beside a page title. */
.page-actions{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }

/* A tile lifts toward the light: an accent edge arrives along the top rather
   than the whole card changing colour under the pointer. */
/* No `overflow:hidden` here: the strip is already inset from both corners, and
   clipping a card would quietly kill any `position:sticky` placed inside one. */
.stat, .card{ position:relative; }
.stat::before, .card::before{
  content:''; position:absolute; left:16px; right:16px; top:0; height:2px;
  border-radius:0 0 2px 2px;
  background: linear-gradient(90deg, transparent, var(--accent-1-light), transparent);
  opacity:0; transition: opacity 320ms var(--ease-ios);
}
.stat:hover::before, .card:hover::before{ opacity:.9; }

/* A wide table scrolls sideways on a narrow screen; give it momentum and keep
   the columns from being crushed into unreadable slivers. */
.table-wrap{
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  border:1px solid var(--border);
  box-shadow: var(--shadow-soft);
}
.table-wrap table{ min-width: 560px; }

/* ---------- Touch and small screens -------------------------------------- */
@media (max-width: 860px){
  /* Safari zooms the whole page in when it focuses an input under 16px, and
     never zooms back out. This is the fix, not a preference. */
  input[type=text], input[type=email], input[type=password], input[type=number],
  input[type=date], input[type=search], input[type=tel], select, textarea{
    font-size:16px;
  }

  /* The tab bar clears the home indicator instead of hiding under it, and
     scrolls sideways once there are more sections than fit — a Super Admin has
     eight, which would otherwise squeeze into slivers. */
  /* max-content, not minmax(66px, max-content): when the bar is short of
     room, grid shrinks such tracks to their 66px minimum and the labels spill
     onto each other. The 66px floor lives on .nav-item instead. */
  .nav{
    bottom: calc(12px + env(safe-area-inset-bottom));
    grid-auto-columns: max-content;
    justify-content:start;
    overflow-x:auto; overscroll-behavior-x: contain;
    scrollbar-width:none;
  }
  .nav::-webkit-scrollbar{ display:none; }
  .shell{ padding-bottom: calc(100px + env(safe-area-inset-bottom)); }
  .floating-controls{ top: calc(12px + env(safe-area-inset-top)); }

  /* Roughly the smallest target a thumb hits reliably. */
  .nav-item{ min-height:50px; min-width:66px; justify-content:center; }
  .btn{ min-height:46px; }
  .btn-sm{ min-height:38px; }
  .lang-btn{ min-height:36px; padding:8px 11px; font-size:12px; }
  .theme-float{ width:44px; height:44px; }
  .theme-toggle{ width:40px; height:40px; }
  .role-card{ padding:13px 14px; }

  .auth-wrap{ padding:16px; }
  .auth-card{ padding:30px 22px; border-radius: var(--radius-lg); }
  .content{ padding:4px 2px 40px; }
  .page-head{ padding:8px 10px; }
  th, td{ padding:12px 14px; }
}

@media (max-width: 560px){
  h1{ font-size:23px; }
  .page-head.is-stuck h1{ font-size:18px; }
  /* Two narrow tiles read better than one wide one on a phone. */
  .stat-grid{ grid-template-columns: repeat(2, minmax(0, 1fr)); gap:10px; }
  .stat{ padding:15px 16px; }
  .stat-value{ font-size:21px; }
  .stat-label{ font-size:11.5px; }
  .empty{ padding:38px 22px; }
}



/* ---------- Print ---------------------------------------------------------
   A finance panel gets printed: a queue taken into a meeting, a document
   attached to a file. On paper the glass, the navigation and the controls are
   noise, and a table that scrolls sideways on screen has to fit the sheet. */
@media print{
  @page{ margin: 14mm; }

  .field-bg, .sidebar, .nav, .floating-controls, .flash-stack,
  .page-actions, .lang-switch, .theme-toggle, .theme-float{ display:none !important; }

  body{ background:#fff; color:#000; font-size:11pt; }
  .shell{ display:block; padding:0; min-height:0; }
  .content{ padding:0; }
  .content > *{ animation:none !important; }

  /* Paper greys, not theme colours: these follow the sheet, not the screen. */
  .glass, .card, .stat, .auth-card{
    background:#fff !important; border:1px solid #ccc !important;
    box-shadow:none !important; backdrop-filter:none !important;
  }
  .glass::after, .stat::before, .card::before{ display:none; }

  .page-head{ position:static; padding:0; margin-bottom:10mm; }
  h1{ font-size:18pt; }
  a{ color:#000; text-decoration:none; }

  .table-wrap{ overflow:visible; border:0; box-shadow:none; }
  .table-wrap table{ min-width:0; }
  th{ background:#f2f2f2 !important; color:#000; }
  th, td{ padding:6pt 8pt; }
  /* Nothing should be cut in half by a page break. */
  tr, .card, .stat, .doc-row{ break-inside: avoid; }
  thead{ display: table-header-group; }
}

/* ==========================================================================
   Approval sheet — a page that exists to be printed
   ========================================================================== */

.sheet-wrap{ max-width:900px; margin:0 auto; padding:24px 20px 60px; }
.sheet-actions{ display:flex; justify-content:flex-end; gap:10px; margin-bottom:16px; }
.sheet{
  padding:40px 44px; border-radius:var(--radius-lg);
  background:var(--surface-solid); border:1px solid var(--line);
  box-shadow:var(--shadow-soft);
}
.sheet-head{
  display:flex; align-items:flex-start; justify-content:space-between;
  gap:24px; padding-bottom:20px; margin-bottom:24px;
  border-bottom:2px solid var(--accent-1);
}
.sheet-brand{ display:flex; align-items:center; gap:11px; }
.sheet-title{ text-align:right; }
.sheet-title h1{ font-size:19px; margin:0 0 4px; }
.sheet-number{
  margin:0; font-family:var(--font-mono); font-size:15px; font-weight:700;
  color:var(--accent-1);
}
.sheet-block{ margin-bottom:26px; }
.sheet-block h2{ font-size:14px; margin-bottom:10px; }
.sheet-table{ width:100%; border-collapse:collapse; background:transparent; }
.sheet-table th, .sheet-table td{
  padding:8px 0; text-align:left; vertical-align:top;
  border-bottom:1px solid var(--line); font-size:13.5px;
}
.sheet-table > tbody > tr > th, .sheet-table > tr > th{
  width:190px; font-size:12px; font-weight:600; letter-spacing:0;
  text-transform:none; color:var(--text-faint); background:transparent;
}
.sheet-amount{ font-family:var(--font-display); font-size:17px; font-weight:750; }
.sheet-note{ font-size:12.5px; color:var(--text-muted); margin-top:3px; }
.sheet-stages td{ font-size:14px; }
.sheet-result th, .sheet-result td{ border-bottom:0; padding-top:12px; }
.sheet-log thead th{
  font-size:11px; color:var(--text-faint); background:transparent;
  letter-spacing:.04em; text-transform:uppercase;
}
.sheet-log td{ font-size:12.5px; padding:6px 10px 6px 0; }
.sheet-foot{
  margin-top:28px; padding-top:14px; border-top:1px solid var(--line);
  font-size:11.5px; color:var(--text-faint);
}

/* On paper the page is the sheet: no chrome, no shadow, black on white, and
   a history that is allowed to break across sheets rather than be clipped. */
@media print{
  .sheet-wrap{ max-width:none; margin:0; padding:0; }
  .sheet-actions{ display:none !important; }
  .sheet{
    padding:0; border:0; border-radius:0; box-shadow:none !important;
    background:#fff !important; color:#000 !important;
  }
  .sheet-head{ border-bottom:2px solid #000; }
  .sheet-number, .sheet-brand .brand-text small{ color:#000 !important; }
  /* Printers drop backgrounds, and white letters on nothing vanish: on paper
     the tile is drawn as an outline instead. */
  .sheet-brand .brand-mark{
    background:none !important; box-shadow:none !important;
    border:2px solid #000; color:#000 !important;
  }
  .sheet-brand .brand-mark::after{ background:#000 !important; }
  .sheet-table th, .sheet-table td{ border-color:#ccc !important; color:#000 !important; }
  .sheet-block{ break-inside:avoid; }
  .sheet-log tr{ break-inside:avoid; }
}

/* ---------- Two-step confirmation ----------------------------------------
   One button opens a form with two panes. `hidden` does the switching, so the
   dialog works even if the script never loads — the second pane is simply
   visible below the first instead of after it. */
[hidden]{ display:none !important; }
.confirm-doc{
  font-family: var(--font-display); font-size:17px; font-weight:700;
  color:var(--text); font-variant-numeric: tabular-nums lining-nums;
  margin-bottom:8px;
}
.pin-why{ font-size:12.5px; line-height:1.45; margin-top:-4px; }

/* ---------- Data export --------------------------------------------------- */
.narrow-wide{ max-width:720px; }
.backup-actions{ display:flex; flex-wrap:wrap; gap:12px; margin:22px 0 6px; }
.backup-actions .btn{ flex:1; min-width:240px; }

/* ---------- Passkeys ------------------------------------------------------
   A registered device is a row, not a chip: it carries a name, when it was
   last used, and a way to remove it. */
.passkey-list{ list-style:none; margin:0 0 4px; padding:0; display:grid; gap:8px; }
.passkey-item{
  display:flex; align-items:center; gap:12px; padding:11px 14px;
  border:1px solid var(--border); border-radius: var(--radius-md);
  background: var(--input-bg); box-shadow: inset 0 1px 0 var(--sheen-soft);
}
.passkey-ico{
  width:34px; height:34px; flex:none; display:grid; place-items:center;
  border-radius:11px; font-size:15px;
  background: var(--accent-tint); color: var(--accent-1);
}
.passkey-text{ display:grid; min-width:0; flex:1; }
.passkey-text strong{ font-size:14px; font-weight:650; }
.passkey-text small{ font-size:12px; color:var(--text-faint); }
.passkey-item form{ margin:0; }

/* The device button leads, so it is the filled one; the PIN below it is the
   fallback and is styled as an ordinary field. */
.btn-passkey{ font-size:15.5px; }
.or-line{
  display:flex; align-items:center; gap:10px;
  margin:14px 0 12px; font-size:12.5px; color:var(--text-faint);
}
.or-line::before, .or-line::after{
  content:''; flex:1; height:1px; background: var(--line);
}

/* ---------- Money in several currencies -----------------------------------
   A total is a stack, not a number: one line per currency, because adding
   tenge to dollars would produce a figure nobody can act on. */
.money-stack{ display:grid; gap:1px; }
.money-line{ display:block; font-variant-numeric: tabular-nums lining-nums; }
/* Inside a stat tile the first line leads and the rest follow a step smaller,
   so four currencies still read as one answer rather than four headlines. */
.stat-value .money-line{ font-size:inherit; }
.stat-value .money-line ~ .money-line{ font-size:.72em; color:var(--text-muted); }
.stat-hint .money-stack{ display:inline-grid; vertical-align:bottom; }

/* ---------- Declared against read -----------------------------------------
   Two columns of the same three facts. The header row is written last in the
   markup and lifted above with `order`, so a screen reader meets the values
   before the column names rather than a bare pair of headings. */
.compare{ display:grid; gap:2px; }
.compare-head, .compare-row{
  display:grid; grid-template-columns: minmax(84px, 1fr) 1.2fr 1.2fr;
  gap:10px; align-items:baseline; padding:9px 12px; border-radius: var(--radius-sm);
}
.compare-head{
  order:-1; padding-bottom:2px;
  font-size:11px; font-weight:650; letter-spacing:.05em;
  text-transform:uppercase; color:var(--text-faint);
}
.compare-label{ font-size:12.5px; color:var(--text-muted); }
.compare-declared{ font-weight:650; color:var(--text); }
.compare-read{ color:var(--text-muted); }
.compare-read em{ font-style:normal; color:var(--text-faint); }

/* Only the row that actually disagrees is marked. Colouring the whole card
   would make a single wrong digit look like a wholly wrong document. */
.compare-row.is-off{ background: var(--tint-warn); }
.compare-row.is-off .compare-read{ color:var(--warn); font-weight:650; }
.card.has-mismatch{ border-color: color-mix(in srgb, var(--warn) 45%, var(--border)); }

@media (max-width: 560px){
  .compare-head{ display:none; }
  /* Stacked: the label stays in the row, so nothing has to name itself. */
  .compare-row{ grid-template-columns:1fr; gap:2px; padding:10px 12px; }
}

/* ==========================================================================
   Темы

   Их четыре, и это не четыре набора цветов «на вкус». Светлая и тёмная —
   выбор по освещению; «Бумага» — тёплый фон без синевы, для тех, кто читает
   документы часами; «Контраст» — чистый чёрный на белом, плотные границы и
   никакой прозрачности, для плохого экрана, проектора и слабого зрения.
   ========================================================================== */

/* ---------- Бумага ---------- */
[data-theme="sepia"]{
  color-scheme: light;
  --bg: #F4EFE3;
  --bg-elevated: #FBF7EE;
  --surface: rgba(255,252,245,.62);
  --surface-strong: rgba(250,245,234,.9);
  --surface-solid: #FBF7EE;
  --border: rgba(122,98,62,.18);
  --line: rgba(92,74,46,.16);
  --text: #2E2620;
  --text-muted: #6B5D4B;
  --text-faint: #9A8A73;
  --input-bg: rgba(255,253,247,.82);
  --sheen: rgba(255,255,255,.7);
  --sheen-soft: rgba(255,255,255,.28);
  --blob: .18;
}

/* ---------- Контраст ---------- */
[data-theme="contrast"]{
  color-scheme: light;
  --bg: #FFFFFF;
  --bg-elevated: #FFFFFF;
  --surface: #FFFFFF;
  --surface-strong: #F0F0F0;
  --surface-solid: #FFFFFF;
  --border: #000000;
  --line: #000000;
  --text: #000000;
  --text-muted: #1C1C1C;
  --text-faint: #333333;
  --input-bg: #FFFFFF;
  --sheen: transparent;
  --sheen-soft: transparent;
  --blob: 0;
  --accent-1: #0B3FA8;
  --accent-1-dark: #072A73;
  --accent-1-light: #0B3FA8;
  --accent-tint: #DDE6FA;
  --shadow-soft: none;
  --shadow-lift: none;
  --shadow-accent: none;
}
/* Прозрачность в контрастной теме мешает: текст читается по тому, что за ним. */
[data-theme="contrast"] .glass,
[data-theme="contrast"] .doc-row,
[data-theme="contrast"] .modal,
[data-theme="contrast"] .flash,
[data-theme="contrast"] .nav{
  backdrop-filter: none; -webkit-backdrop-filter: none;
  border-width: 2px; border-color: #000;
}
[data-theme="contrast"] .glass::after{ display: none; }
[data-theme="contrast"] .field-bg{ display: none; }
[data-theme="contrast"] .btn{ border: 2px solid #000; }
[data-theme="contrast"] .btn-primary{ background: var(--accent-1); border-color: #000; }
[data-theme="contrast"] th{ background: #E8E8E8; }

/* ---------- Выбор темы в настройках ---------- */
.theme-grid{
  display:grid; gap:12px; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr));
}
.theme-option input{ position:absolute; opacity:0; pointer-events:none; }
.theme-card{
  display:block; cursor:pointer; padding:12px; border-radius:var(--radius-md);
  border:1px solid var(--line); background:var(--surface-strong);
  transition: border-color var(--transition), transform 160ms var(--ease-ios);
}
.theme-card:active{ transform:scale(.98); }
.theme-option input:checked + .theme-card{
  border-color:var(--accent-1); box-shadow:0 0 0 3px var(--accent-tint);
}
/* Каждая тема показывает себя: полоски — фон, панель, текст и акцент именно
   той темы, а не текущей. Выбирать вслепую по названию — не выбирать. */
.theme-swatch{
  display:flex; height:46px; border-radius:var(--radius-sm); overflow:hidden;
  border:1px solid var(--line); margin-bottom:9px;
}
.theme-swatch i{ flex:1; display:block; }
.theme-swatch i:nth-child(3){ flex:.5; }
.theme-name{ font-size:13.5px; font-weight:650; display:block; }
.theme-hint{ font-size:11.5px; color:var(--text-faint); }

/* ==========================================================================
   Поля с числами
   ========================================================================== */

/* Сумма и БИН — это цифры, и читать их надо как цифры: моноширинные по
   ширине знака, чтобы разряды стояли столбиком, и крупнее обычного поля,
   потому что ошибка в одной цифре здесь стоит дороже опечатки в названии. */
.num-field{ position:relative; }
.num-field input{
  font-family: var(--font-display);
  font-size: 17px; font-weight: 650; letter-spacing: .02em;
  font-variant-numeric: tabular-nums lining-nums;
  padding-right: 54px;
}
.num-suffix{
  position:absolute; right:16px; top:50%; transform:translateY(-50%);
  font-size:12.5px; font-weight:700; color:var(--text-faint);
  pointer-events:none; font-variant-numeric: tabular-nums;
}
.num-field input:focus + .num-suffix{ color:var(--accent-1); }
/* Счётчик цифр у БИН: 12 — не «примерно двенадцать». */
.num-suffix.is-full{ color:var(--success); }

/* ==========================================================================
   iPhone
   ========================================================================== */

@media (max-width: 860px){
  /* Safari увеличивает страницу, когда фокус попадает в поле мельче 16px, и
     обратно уже не отматывает. Шестнадцать — это не про читаемость, это про
     то, чтобы экран не прыгал. */
  input[type=text], input[type=email], input[type=password], input[type=number],
  input[type=date], input[type=search], select, textarea{ font-size: 16px; }
  .num-field input{ font-size: 18px; }

  /* Панель вкладок не должна стоять на полосе жестов. */
  .nav{ padding-bottom: calc(8px + env(safe-area-inset-bottom)); }
  .shell{ padding-bottom: calc(96px + env(safe-area-inset-bottom)); }

  /* Кнопка, до которой нельзя промахнуться пальцем. */
  .btn, .chip-btn, .lang-btn, .theme-toggle, .field-toggle{ min-height: 44px; }
  .btn-sm{ min-height: 38px; }

  body{ overflow-x: hidden; }
  .page-head{ position: static; }
  .page-actions{ display:flex; gap:8px; flex-wrap:wrap; }
  .modal{ width: calc(100vw - 24px); padding: 22px 20px; }
  .modal-actions{ flex-direction: column-reverse; }
  .modal-actions .btn{ width: 100%; }
  .backup-actions .btn{ min-width: 0; }
  .facts{ grid-template-columns: 1fr; gap: 2px 0; }
  .facts dt{ margin-top: 8px; }
}

/* iOS Safari не показывает PDF внутри iframe — вместо документа остаётся
   серый прямоугольник. Поэтому на узком экране вместо рамки стоит кнопка,
   которая открывает файл во встроенной смотрелке, где он листается и
   масштабируется как положено. */
@media (max-width: 700px){
  .pdf-frame{ display: none; }
  .pdf-fallback{ display: flex; }
}
.pdf-fallback{
  display: none; flex-direction: column; align-items: center; gap: 10px;
  padding: 28px 20px; text-align: center;
  border: 1px dashed var(--line); border-radius: var(--radius-md);
  background: var(--surface-strong);
}
.pdf-fallback small{ color: var(--text-faint); font-size: 12.5px; }

/* Подпись шага внутри окна подтверждения: не `label` при поле, а заголовок
   над кнопкой, поэтому отступы свои. */
.field-label-plain{
  display:block; margin:14px 0 7px;
  font-size:12px; font-weight:600; color:var(--text-muted);
}

/* Поле, которое просит внимания: короткая подсветка вместо модального окна. */
.pin-input.is-off{
  border-color: var(--warn);
  box-shadow: 0 0 0 4px var(--tint-warn);
}

/* ==========================================================================
   Графики

   Геометрия — на рамках и флексе; SVG остался только там, где нужна кривая.
   Текста внутри рисунков нет: SVG с width:100% масштабирует подписи вместе с
   собой, и одна диаграмма рисовала текст вдвое крупнее другой. Подписи —
   обычный DOM, один кегль на всю страницу.

   Палитра проверена валидатором в обеих темах: ординальная шкала — один тон с
   монотонной светлотой, категориальная — три различимых при дальтонизме
   слота, статусная — отдельная, она никогда не изображает серию.
   ========================================================================== */

.viz{
  --viz-track: color-mix(in srgb, var(--text) 8%, transparent);
  --viz-seq: #2a78d6;
  --viz-o1: #86b6ef; --viz-o2: #5598e7; --viz-o3: #2a78d6;
  --viz-o4: #1c5cab; --viz-o5: #104281;
  --viz-c1: #2a78d6; --viz-c2: #eb6834; --viz-c3: #1baf7a;
  --viz-good: #0ca30c; --viz-warn: #fab219; --viz-crit: #d03b3b;
  --viz-idle: #8e8e93;
  --viz-radius: 4px;
}
/* Тёмная тема — не инверсия светлой, а собственные ступени тех же тонов,
   проверенные против тёмного фона. */
[data-theme="dark"] .viz{
  --viz-seq: #3987e5;
  --viz-o1: #cde2fb; --viz-o2: #9ec5f4; --viz-o3: #6da7ec;
  --viz-o4: #3987e5; --viz-o5: #256abf;
  --viz-c1: #3987e5; --viz-c2: #d95926; --viz-c3: #199e70;
}

/* ---------- Заливки ---------- */
.viz-bar-fill{ background: var(--viz-seq); }
.viz-step-1{ background: var(--viz-o1); }
.viz-step-2{ background: var(--viz-o2); }
.viz-step-3{ background: var(--viz-o3); }
.viz-step-4{ background: var(--viz-o4); }
.viz-step-5{ background: var(--viz-o5); }
.viz-cat-1{ background: var(--viz-c1); }
.viz-cat-2{ background: var(--viz-c2); }
.viz-cat-3{ background: var(--viz-c3); }
.viz-good{ background: var(--viz-good); }
.viz-warn{ background: var(--viz-warn); }
.viz-crit{ background: var(--viz-crit); }
.viz-idle{ background: var(--viz-idle); }

/* ---------- Полосы --------------------------------------------------------
   Скругляется только значащий конец: основание стоит на оси. Скруглить оба —
   слегка соврать о начале отсчёта. */
.viz-rows{ display:grid; gap:9px; }
.viz-row{
  display:grid; grid-template-columns: minmax(84px, 33%) 1fr auto;
  align-items:center; gap:12px;
}
.viz-row-label{
  font-size:12.5px; color:var(--text-muted);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.viz-row-track{
  position:relative; display:block; height:12px; min-width:40px;
  background: var(--viz-track); border-radius: var(--viz-radius);
}
.viz-row-fill{
  display:block; height:100%; min-width:3px;
  border-radius: 0 var(--viz-radius) var(--viz-radius) 0;
  transition: width 420ms var(--ease-ios);
}
.viz-row-value{
  font-family:var(--font-display); font-size:12.5px; font-weight:650;
  font-variant-numeric: tabular-nums; color:var(--text); white-space:nowrap;
}

/* ---------- Воронка ---------- */
.viz-funnel{ display:grid; gap:12px; }
.viz-funnel-row{
  display:grid; grid-template-columns: minmax(96px, 26%) 1fr 42px;
  align-items:center; gap:12px;
}
.viz-funnel-label{ font-size:13px; color:var(--text-muted); }
.viz-funnel-bar{ display:flex; align-items:center; gap:10px; min-width:0; }
.viz-funnel-fill{
  display:block; height:16px; min-width:3px;
  border-radius: 0 var(--viz-radius) var(--viz-radius) 0;
  transition: width 480ms var(--ease-ios);
}
.viz-funnel-value{
  font-family:var(--font-display); font-size:13.5px; font-weight:700;
  font-variant-numeric: tabular-nums; color:var(--text);
}
.viz-funnel-drop{
  font-family:var(--font-display); font-size:12px; font-weight:650;
  font-variant-numeric: tabular-nums; color:var(--danger); text-align:right;
}

/* ---------- Доли ---------- */
.viz-segments{
  display:flex; height:26px; border-radius: var(--viz-radius);
  overflow:hidden; gap:2px; background: var(--viz-track);
}
.viz-segment{ display:block; min-width:3px; }

.viz-legend{ display:flex; flex-wrap:wrap; gap:7px 16px; margin-top:12px; }
.viz-key{ display:inline-flex; align-items:center; gap:7px;
          font-size:12.5px; color:var(--text-muted); }
.viz-key b{ color:var(--text); font-variant-numeric:tabular-nums; }
.viz-dot{ width:10px; height:10px; border-radius:3px; flex:none; }

/* ---------- Столбцы ---------- */
.viz-columns{ display:flex; align-items:flex-end; gap:3px; height:132px; }
.viz-column{
  flex:1; display:flex; flex-direction:column; justify-content:flex-end;
  align-items:center; height:100%; min-width:0;
}
.viz-column-bar{
  width:100%; min-height:2px;
  border-radius: var(--viz-radius) var(--viz-radius) 0 0;
  transition: height 420ms var(--ease-ios);
}
.viz-column-tick{
  margin-top:6px; font-size:10px; color:var(--text-faint);
  font-variant-numeric: tabular-nums; height:12px;
}

/* ---------- Область ---------- */
.viz-area-wrap{ position:relative; height: var(--viz-h, 110px); }
.viz-area-svg{ display:block; width:100%; height:100%; }
.viz-area{ fill: var(--viz-seq); opacity:.15; }
/* vector-effect держит толщину линии постоянной, хотя SVG растянут по
   ширине: без него линия на широкой карточке становится тоньше. */
.viz-line{
  fill:none; stroke: var(--viz-seq); stroke-width:2;
  stroke-linejoin:round; stroke-linecap:round;
  vector-effect: non-scaling-stroke;
}
/* Точки — элементы поверх рисунка, поэтому остаются круглыми при любом
   растяжении. Кольцо цветом подложки не даёт им слиться с линией. */
.viz-point{
  position:absolute; width:9px; height:9px; margin:0 0 -4.5px -4.5px;
  border-radius:50%; background: var(--viz-seq);
  box-shadow: 0 0 0 2px var(--surface-solid);
}
.viz-axis-labels{
  display:flex; justify-content:space-between; align-items:baseline;
  margin-top:8px; font-size:11px; color:var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.viz-axis-peak{ color:var(--text-muted); font-weight:600; }

/* ---------- Измеритель ---------- */
.viz-meter{ margin-bottom:15px; }
.viz-meter:last-child{ margin-bottom:0; }
.viz-meter-head{
  display:flex; justify-content:space-between; align-items:baseline;
  gap:10px; margin-bottom:7px; font-size:13px; color:var(--text-muted);
}
.viz-meter-head b{ color:var(--text); font-variant-numeric:tabular-nums; }
.viz-meter .viz-row-track{ height:10px; }
.viz-meter small{ display:block; margin-top:6px; font-size:11.5px; color:var(--text-faint); }

/* ---------- Сетка карточек ---------- */
.chart-grid{
  display:grid; gap:16px; margin-bottom:16px;
  grid-template-columns:repeat(auto-fit, minmax(330px, 1fr));
}
.chart-card{ padding:20px 22px; display:flex; flex-direction:column; }
.chart-card h3{ margin-bottom:4px; }
.chart-note{ font-size:12px; color:var(--text-faint); margin:0 0 16px; }
.chart-wide{ grid-column:1 / -1; }
.chart-empty{ color:var(--text-faint); font-size:13px; padding:16px 0; }

@media (max-width: 860px){
  .viz-row{ grid-template-columns: minmax(72px, 40%) 1fr auto; gap:9px; }
  .viz-funnel-row{ grid-template-columns: minmax(84px, 34%) 1fr 36px; }
  .viz-columns{ height:104px; }
}

/* На печати графики остаются: это отчёт, а не украшение страницы. Фон
   печатается принудительно — без этого браузер выбрасывает заливки, и от
   диаграммы остаются пустые рамки. */
@media print{
  .chart-card{ break-inside:avoid; }
  .viz-row-fill, .viz-funnel-fill, .viz-segment, .viz-column-bar, .viz-dot{
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
}

/* Кнопка выхода в шапке — заметная, но не кричащая; отделена от действий страницы. */
.head-logout{ display:inline; }
.head-logout .btn{ color: var(--accent-1); }
.head-logout .btn:hover{ background: var(--accent-tint); }

/* --- Сайдбар: длинное меню скроллится, низ с аккаунтом и выходом закреплён --
   13 пунктов меню перерастали высоту экрана, и подвал (аккаунт + «Выход»)
   уходил за нижний край — кнопки выхода было не видно. Теперь прокручивается
   только список пунктов, а логотип сверху и подвал снизу стоят на месте. */
.sidebar{ min-height:0; }
.sidebar .nav{ flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden; }
/* flex:1 делает меню высотой во весь сайдбар, а сетка по умолчанию растягивает
   строки на всю свою высоту. У админа пунктов много, и это не видно; у
   сотрудника их три, и каждый вытягивался в плиту на треть экрана. Пункты
   прижаты к верху, остальное место остаётся пустым. */
.sidebar .nav{ align-content:start; }
.sidebar .nav{ scrollbar-width:thin; }
.sidebar .nav::-webkit-scrollbar{ width:6px; }
.sidebar .nav::-webkit-scrollbar-thumb{ background:var(--border-strong); border-radius:3px; }
.sidebar-foot{ margin-top:0; flex:none; padding-top:14px; border-top:1px solid var(--border); }

/* Кнопка выхода в подвале — заметная: акцентная рамка, заливка при наведении. */
.sidebar-foot form .btn{
  border:1px solid var(--accent-1); color:var(--accent-1); font-weight:700;
}
.sidebar-foot form .btn:hover{ background:var(--accent-1); color:#fff; }

/* --- Телефон: сайдбар — шапка, меню — панель вкладок внизу экрана ---------
   Две поправки к правилам выше, которые писались для компьютера.
   1. backdrop-filter у стеклянного сайдбара делает его контейнером для
      position:fixed внутри. Панель вкладок цеплялась не к низу экрана, а к
      самой шапке и закрывала логотип. Шапка стоит на фоне страницы, размывать
      под ней нечего — фильтр снимаем, и панель встаёт вниз, как задумано.
   2. `.sidebar .nav` выше запрещал прокрутку вбок, а на телефоне вкладки
      в одну строку не помещаются — возвращаем её. Разделитель над подвалом
      в строке шапки тоже лишний. */
@media (max-width: 860px){
  .sidebar{ backdrop-filter:none; -webkit-backdrop-filter:none; }
  .sidebar .nav{ flex:none; overflow-x:auto; overflow-y:hidden; }
  .sidebar-foot{ padding-top:0; border-top:0; }
}

/* --- Подпись рукой на финальном подтверждении (Admin 3) ------------------
   Поле — белый лист в любой теме: подпись рисуется тёмными чернилами и в
   таком же виде ложится на PDF, поэтому и на экране она на бумаге. */
.sign-field{ margin-top:4px; }
.sign-pad{
  position:relative; height:180px; border-radius:var(--radius-md);
  background:#fff; border:1.5px dashed var(--line);
  box-shadow: inset 0 1px 3px rgba(0,0,0,.05);
  transition: border-color var(--transition);
}
.sign-pad:hover{ border-color: var(--accent-1-light); }
.sign-pad.has-ink{ border-style:solid; border-color: var(--accent-1-light); }
.sign-pad.is-invalid{ border-color: var(--danger); }
.sign-canvas{
  display:block; width:100%; height:100%; border-radius:inherit;
  cursor:crosshair; touch-action:none;   /* палец рисует, а не листает окно */
}
/* Линия и подсказка — как на бланке: «подпись здесь». */
.sign-pad::after{
  content:""; position:absolute; left:22px; right:22px; bottom:40px;
  border-bottom:1px solid #D9DBE3; pointer-events:none;
}
.sign-hint{
  position:absolute; left:22px; bottom:16px; font-size:12px; color:#8A8F9C;
  pointer-events:none; transition: opacity var(--transition);
}
.sign-pad.has-ink .sign-hint{ opacity:0; }
.sign-clear{
  position:absolute; top:8px; right:8px; min-height:30px !important;
  padding:4px 10px; font-size:12px; color:#5A5A61; background:rgba(0,0,0,.04);
}
.sign-error{ margin:8px 0 0; color: var(--danger); font-size:13px; font-weight:600; }
.sign-field > small{ display:block; margin-top:8px; line-height:1.45; }

/* Что осталось после подписи: сама подпись, кто и секунда. */
.sign-record{
  display:flex; align-items:center; gap:16px; margin:16px 0 4px; padding:12px 14px;
  border:1px solid var(--line); border-radius:var(--radius-md); background:#fff;
}
.sign-record img{ width:132px; max-height:60px; object-fit:contain; flex:none; }
.sign-record figcaption{ display:grid; gap:2px; font-size:13px; color:#1c1f26; min-width:0; }
.sign-record .mono{ font-family:var(--font-mono); font-size:13.5px; font-weight:700; }
.sign-record small{ color:#6b707c; }
.sign-record .sign-warn{ color: var(--danger); }
.review-doc-links{ display:flex; gap:8px; flex-wrap:wrap; justify-content:flex-end; }
@media (max-width: 560px){
  .sign-pad{ height:160px; }
  .sign-record{ flex-direction:column; align-items:flex-start; }
}

/* Чья это дверь: на двух адресах — «для сотрудников» или «для администраторов». */
.portal-tag{
  display:table; margin:-14px auto 22px; padding:5px 12px; border-radius:var(--radius-pill);
  font-size:12px; font-weight:700; letter-spacing:.04em;
  background:var(--accent-tint); color:var(--accent-1);
}
.portal-tag.portal-admin{ background:rgba(27,63,146,.92); color:#fff; }

/* Ссылка «Нет учётки? Зарегистрироваться» под формой входа — и обратная. */
.auth-switch{ margin:18px 0 0; text-align:center; font-size:14px; color:var(--text-muted); }
.auth-switch a{ font-weight:700; }

/* Заявки на регистрацию у Super Admin: над таблицей людей, пока они есть. */
.pending-card{ padding:18px 20px; margin-bottom:18px; border:1.5px solid var(--accent-1-light); }
.pending-card h3{ margin:0 0 4px; }
.pending-list{ list-style:none; margin:12px 0 0; padding:0; display:grid; gap:10px; }
.pending-item{
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  padding:10px 12px; border-radius:var(--radius-sm); background:var(--surface-strong);
}
.pending-who{ display:grid; gap:2px; min-width:0; }
.pending-who small{ color:var(--text-muted); }
.pending-item form{ display:flex; gap:8px; }
