/* ═══════════════════════════════════════════════════════════════════════
   JIGYAASA — design system
   Fresh purple · generous curves · soft shadows · mobile first
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  /* brand */
  --pri:        #7C3AED;     /* fresh purple */
  --pri-600:    #6D28D9;
  --pri-700:    #5B21B6;
  --pri-300:    #C4B5FD;
  --pri-100:    #EDE9FE;
  --pri-50:     #F7F5FF;

  /* playful accents, taken from the logo */
  --red:    #E8342B;
  --blue:   #29A3E8;
  --yellow: #F5B700;
  --green:  #2FB344;
  --pink:   #EC4899;
  --teal:   #14B8A6;

  /* neutrals */
  --ink:     #1A1626;
  --ink-2:   #4B4560;
  --ink-3:   #7A7391;
  --line:    #EAE6F2;
  --line-2:  #F2EFF8;
  --bg:      #F6F4FB;
  --card:    #FFFFFF;

  /* status */
  --ok:   #2FB344;
  --warn: #F59E0B;
  --bad:  #E11D48;

  /* curves — softened, calmer than before */
  --r-xs: 8px;
  --r-sm: 10px;
  --r:    14px;
  --r-lg: 16px;
  --r-xl: 20px;
  --pill: 999px;

  /* Minimal: cards are defined by a hairline border, not a drop shadow.
     Shadows are reserved for things that truly float — modals, toasts,
     the open sidebar. No coloured shadows anywhere. */
  --bord: 1px solid var(--line);
  --sh-1: none;
  --sh-2: 0 8px 28px rgba(26,22,38,.12);
  --sh-pri: none;

  --side-w: 264px;
  --tab-h: 68px;

  --fs: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto,
        "Helvetica Neue", Arial, sans-serif;

  /* ── chart series ───────────────────────────────────────────────────
     Validated categorical order (violet, orange, aqua, yellow, magenta,
     green, blue, red). Adjacent-pair CVD ΔE ≥ 9.1 light / 8.4 dark and
     normal-vision ΔE ≥ 19.6, checked at 4, 6 and 8 series against these
     exact surfaces. Assign in slot order — never cycle, never re-order
     when a filter changes the series count. */
  --s1:#4a3aa7; --s2:#eb6834; --s3:#1baf7a; --s4:#eda100;
  --s5:#e87ba4; --s6:#008300; --s7:#2a78d6; --s8:#e34948;
  --grid:#EFECF6;          /* recessive gridlines */
  --axis:#B7B1C8;
  --tint-warn:#FFF6E0; --tint-ok:#E7F8EA; --tint-bad:#FFECEF; --tint-pri:#F7F5FF;
  color-scheme: light;
}

/* ── dark theme ───────────────────────────────────────────────────────
   Selected, not flipped: the series are the same eight hues re-stepped for
   the dark surface and validated against it. Declared twice on purpose —
   the media query follows the OS, the attribute follows the in-app toggle,
   and the toggle must win in both directions. */
@media (prefers-color-scheme: dark){
  :root:where(:not([data-theme="light"])){
    --ink:#EEEAF9; --ink-2:#BDB5D6; --ink-3:#8B83A6;
    --line:#312B48; --line-2:#272138;
    --bg:#141122; --card:#1C1930;
    --pri:#9B7BFF; --pri-600:#8B5CF6; --pri-700:#A78BFA;
    --pri-300:#5B4A8C; --pri-100:#2E2547; --pri-50:#241D3A;
    --bord:1px solid var(--line);
    --sh-1:none;
    --sh-2:0 10px 34px rgba(0,0,0,.5);
    --sh-pri:none;
    --s1:#9085e9; --s2:#d95926; --s3:#199e70; --s4:#c98500;
    --s5:#d55181; --s6:#008300; --s7:#3987e5; --s8:#e66767;
    --grid:#2A2440; --axis:#6C6485;
    --tint-warn:#3A2F14; --tint-ok:#14301B; --tint-bad:#3A1620; --tint-pri:#241D3A;
    color-scheme: dark;
  }
}
:root[data-theme="dark"]{
  --ink:#EEEAF9; --ink-2:#BDB5D6; --ink-3:#8B83A6;
  --line:#312B48; --line-2:#272138;
  --bg:#141122; --card:#1C1930;
  --pri:#9B7BFF; --pri-600:#8B5CF6; --pri-700:#A78BFA;
  --pri-300:#5B4A8C; --pri-100:#2E2547; --pri-50:#241D3A;
  --bord:1px solid var(--line);
  --sh-1:none;
  --sh-2:0 10px 34px rgba(0,0,0,.5);
  --sh-pri:none;
  --s1:#9085e9; --s2:#d95926; --s3:#199e70; --s4:#c98500;
  --s5:#d55181; --s6:#008300; --s7:#3987e5; --s8:#e66767;
  --grid:#2A2440; --axis:#6C6485;
  --tint-warn:#3A2F14; --tint-ok:#14301B; --tint-bad:#3A1620; --tint-pri:#241D3A;
  color-scheme: dark;
}

/* ── status tints ─────────────────────────────────────────────────────
   Defined once and reused by badges, calendar chips and callouts, so a
   colour never has to be restated per component. Dark is a separate set
   chosen against the dark card, not the light one dimmed. */
:root{
  --t-green-bg:#E7F8EA;  --t-green-fg:#1E7F31;
  --t-red-bg:#FFECEF;    --t-red-fg:#C01640;
  --t-yellow-bg:#FFF6E0; --t-yellow-fg:#95610A;
  --t-blue-bg:#E4F3FE;   --t-blue-fg:#1268A0;
  --t-teal-bg:#DEF7F4;   --t-teal-fg:#0C7A70;
  --t-pink-bg:#FCE7F3;   --t-pink-fg:#A81A67;
  --topbar-bg:#F6F4FB;
  --tabbar-bg:#FFFFFF;
  --skel-hi:#F8F6FC;
  --login-1:#EFE7FF; --login-2:#E4F3FF;
  --av1-bg:#FFE3E1; --av1-fg:#B4322A;  --av2-bg:#DFF0FE; --av2-fg:#14618F;
  --av3-bg:#FFF3D6; --av3-fg:#8A5B05;  --av4-bg:#DFF6E3; --av4-fg:#1D7A2F;
  --av5-bg:#F0E5FF; --av5-fg:#5B21B6;  --av6-bg:#FCE3F1; --av6-fg:#A81A67;
}
@media (prefers-color-scheme: dark){
  :root:where(:not([data-theme="light"])){
    --t-green-bg:#14301B;  --t-green-fg:#8CE0A2;
    --t-red-bg:#3A1620;    --t-red-fg:#FF9BAF;
    --t-yellow-bg:#3A2F14; --t-yellow-fg:#F4CE72;
    --t-blue-bg:#12304A;   --t-blue-fg:#90CDF4;
    --t-teal-bg:#123C38;   --t-teal-fg:#7EDCD2;
    --t-pink-bg:#3A1B2C;   --t-pink-fg:#F5A3C7;
    --topbar-bg:#141122;
    --tabbar-bg:#1C1930;
    --skel-hi:#241F38;
    --login-1:#241D3A; --login-2:#15263A;
    --av1-bg:#42221F; --av1-fg:#FFB4AE;  --av2-bg:#16304A; --av2-fg:#9BD1F5;
    --av3-bg:#3D3016; --av3-fg:#F5CE7C;  --av4-bg:#173523; --av4-fg:#93E0AA;
    --av5-bg:#2E2547; --av5-fg:#C4B5FD;  --av6-bg:#3A1B2C; --av6-fg:#F5A3C7;
  }
}
:root[data-theme="dark"]{
  --t-green-bg:#14301B;  --t-green-fg:#8CE0A2;
  --t-red-bg:#3A1620;    --t-red-fg:#FF9BAF;
  --t-yellow-bg:#3A2F14; --t-yellow-fg:#F4CE72;
  --t-blue-bg:#12304A;   --t-blue-fg:#90CDF4;
  --t-teal-bg:#123C38;   --t-teal-fg:#7EDCD2;
  --t-pink-bg:#3A1B2C;   --t-pink-fg:#F5A3C7;
  --topbar-bg:#141122;
  --tabbar-bg:#1C1930;
  --skel-hi:#241F38;
  --login-1:#241D3A; --login-2:#15263A;
  --av1-bg:#42221F; --av1-fg:#FFB4AE;  --av2-bg:#16304A; --av2-fg:#9BD1F5;
  --av3-bg:#3D3016; --av3-fg:#F5CE7C;  --av4-bg:#173523; --av4-fg:#93E0AA;
  --av5-bg:#2E2547; --av5-fg:#C4B5FD;  --av6-bg:#3A1B2C; --av6-fg:#F5A3C7;
}

*,*::before,*::after{ box-sizing:border-box; }
html,body{ height:100%; }
body{
  margin:0; font-family:var(--fs); color:var(--ink); background:var(--bg);
  -webkit-font-smoothing:antialiased; font-size:15px; line-height:1.38;
  overscroll-behavior-y:none;
}
h1,h2,h3,h4{ margin:0; font-weight:700; letter-spacing:-.02em; }
p{ margin:0 0 .6em; }
button{ font:inherit; color:inherit; }
a{ color:var(--pri-600); }
[hidden]{ display:none !important; }
::selection{ background:var(--pri-100); }

/* ── scrollbars ─────────────────────────────────────────────────────── */
*::-webkit-scrollbar{ width:10px; height:10px; }
*::-webkit-scrollbar-thumb{ background:var(--line); border-radius:var(--pill); border:3px solid transparent; background-clip:content-box; }
*::-webkit-scrollbar-thumb:hover{ background:var(--pri-300); background-clip:content-box; }
*::-webkit-scrollbar-track{ background:transparent; }

/* ═══════════════════════════════════════════════════════════════════════
   BOOT + LOGIN
   ═══════════════════════════════════════════════════════════════════════ */
#boot{
  position:fixed; inset:0; display:flex; flex-direction:column; gap:18px;
  align-items:center; justify-content:center; background:var(--bg); z-index:60;
}
.boot-logo{ width:150px; height:auto; }
#boot span{ color:var(--ink-3); font-size:14px; }
.spinner{
  width:30px; height:30px; border-radius:50%;
  border:3px solid var(--pri-100); border-top-color:var(--pri);
  animation:spin .8s linear infinite;
}
@keyframes spin{ to{ transform:rotate(360deg); } }

#login{
  min-height:100dvh; display:flex; flex-direction:column; gap:14px;
  align-items:center; justify-content:center; padding:24px 18px; background:var(--bg);
}
.login-card{
  width:100%; max-width:400px; background:var(--card); border-radius:var(--r-xl);
  padding:32px 26px 26px; border:var(--bord); text-align:center;
}
.login-logo{ width:170px; height:auto; margin-bottom:14px; }
.login-card h1{ font-size:23px; }
.login-card .sub{ color:var(--ink-3); font-size:13.5px; margin:6px 0 22px; }
.login-card form{ text-align:left; display:flex; flex-direction:column; gap:4px; }
.login-foot{ color:var(--ink-3); font-size:12.5px; }
.pw-wrap{ position:relative; }
.pw-eye{
  position:absolute; right:8px; top:50%; transform:translateY(-50%);
  background:none; border:0; font-size:16px; cursor:pointer; opacity:.5; padding:6px;
}
.msg{ font-size:13px; margin-top:12px; min-height:18px; }
.msg.err{ color:var(--bad); }
.msg.ok{ color:var(--ok); }

/* ═══════════════════════════════════════════════════════════════════════
   FORM CONTROLS
   ═══════════════════════════════════════════════════════════════════════ */
label{ display:block; font-size:12.5px; font-weight:600; color:var(--ink-2); margin:12px 0 5px; }
label .req{ color:var(--bad); }
input,select,textarea{
  width:100%; padding:12px 14px; font:inherit; font-size:15px; color:var(--ink);
  background:var(--card); border:1.5px solid var(--line);
  border-radius:var(--r-sm); outline:none; transition:border-color .15s, box-shadow .15s;
}
textarea{ min-height:84px; resize:vertical; line-height:1.45; }
input:focus,select:focus,textarea:focus{
  border-color:var(--pri-300); box-shadow:0 0 0 4px var(--pri-50);
}
input::placeholder,textarea::placeholder{ color:#B7B1C8; }
input[type=file]{ padding:9px 12px; background:var(--pri-50); border-style:dashed; }
select{
  appearance:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8'><path d='M1 1l5 5 5-5' stroke='%237A7391' stroke-width='2' fill='none' stroke-linecap='round'/></svg>");
  background-repeat:no-repeat; background-position:right 14px center; padding-right:36px;
}
.hint{ font-size:12px; color:var(--ink-3); margin-top:5px; }
.check{ display:flex; align-items:center; gap:10px; margin:12px 0; cursor:pointer; }
.check input{ width:20px; height:20px; accent-color:var(--pri); flex:none; }
.check span{ font-size:14px; }

/* ── buttons ─────────────────────────────────────────────────────────── */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  padding:11px 18px; border:1.5px solid transparent; border-radius:var(--pill);
  background:var(--card); color:var(--ink); font-size:14px; font-weight:600;
  cursor:pointer; white-space:nowrap; transition:transform .1s, background .12s, border-color .12s;
}
.btn:active{ transform:scale(.98); }
.btn:disabled{ opacity:.5; cursor:not-allowed; }
.btn.primary{ background:var(--pri); color:#fff; }
.btn.primary:hover{ background:var(--pri-600); }
.btn.ghost{ background:var(--pri-50); color:var(--pri-700); }
.btn.ghost:hover{ background:var(--pri-100); }
.btn.outline{ border-color:var(--line); background:var(--card); }
.btn.outline:hover{ border-color:var(--pri-300); color:var(--pri-700); }
.btn.danger{ background:var(--tint-bad); color:var(--bad); }
.btn.sm{ padding:7px 13px; font-size:13px; }
.btn.xs{ padding:5px 11px; font-size:12px; }
.btn.block{ width:100%; margin-top:20px; }
.link{
  background:none; border:0; color:var(--pri-600); font-size:13.5px;
  font-weight:600; cursor:pointer; padding:10px; text-decoration:none;
}
.icon-btn{
  position:relative; width:40px; height:40px; flex:none; display:grid; place-items:center;
  border:0; border-radius:var(--pill); background:var(--pri-50); font-size:17px;
  cursor:pointer; transition:background .15s;
}
.icon-btn:hover{ background:var(--pri-100); }
/* The bell's unread badge carries a number (1, 99+…), not just a presence
   dot, so it needs room for text — min-width/padding/line-height, not the
   old fixed 9px circle. Kept scoped to .icon-btn .dot (its only use) rather
   than a bare .dot rule: a bare .dot would lose the specificity fight to
   this selector and silently keep the old tiny-circle sizing underneath. */
.icon-btn .dot{
  position:absolute; top:-2px; right:-4px; min-width:17px; height:17px;
  padding:0 4px; border-radius:var(--pill);
  background:var(--red); color:#fff;
  font-size:11px; font-weight:700; line-height:17px; text-align:center;
}

/* ═══════════════════════════════════════════════════════════════════════
   APP SHELL
   ═══════════════════════════════════════════════════════════════════════ */
#app{ min-height:100dvh; }

#sidebar{
  position:fixed; inset:0 auto 0 0; width:var(--side-w); z-index:40;
  background:var(--card); border-right:1px solid var(--line);
  display:flex; flex-direction:column; padding:20px 14px 14px;
  transition:transform .16s ease-out;
}
.brand{ display:flex; align-items:center; gap:11px; padding:0 8px 18px; }
.brand img{ width:44px; height:44px; object-fit:contain; background:#fff; border-radius:10px; padding:3px; }
.brand strong{ display:block; font-size:16.5px; letter-spacing:-.02em; }
.brand small{ display:block; font-size:11.5px; color:var(--ink-3); margin-top:1px; }

#navDesktop{ flex:1; overflow-y:auto; display:flex; flex-direction:column; gap:2px; padding-bottom:10px; }
.nav-group{ font-size:10.5px; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-3); padding:16px 12px 6px; }
.nav-item{
  display:flex; align-items:center; gap:11px; padding:10px 12px; border:0;
  border-radius:var(--r-sm); background:none; font-size:14.5px; font-weight:550;
  color:var(--ink-2); cursor:pointer; text-align:left; width:100%; transition:background .12s, color .12s;
}
.nav-item .ic{ font-size:17px; width:22px; text-align:center; flex:none; }
.nav-item:hover{ background:var(--line-2); color:var(--ink); }
.nav-item.on{ background:var(--pri-50); color:var(--pri-700); font-weight:700; }
.nav-item .badge{ margin-left:auto; }

.side-foot{ border-top:1px solid var(--line); padding-top:10px; }
.who{
  display:flex; align-items:center; gap:10px; width:100%; padding:8px;
  border:0; border-radius:var(--r-sm); background:none; cursor:pointer; text-align:left;
}
.who:hover{ background:var(--line-2); }
.who-txt{ min-width:0; }
.who-txt strong{ display:block; font-size:14px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.who-txt small{ display:block; font-size:11.5px; color:var(--ink-3); }

#main{ margin-left:var(--side-w); min-height:100dvh; display:flex; flex-direction:column; }

#topbar{
  position:sticky; top:0; z-index:30; display:flex; align-items:center; gap:12px;
  padding:14px 22px; background:var(--topbar-bg);
  border-bottom:1px solid var(--line);
}
.tb-title{ flex:1; min-width:0; }
.tb-title h2{ font-size:20px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.tb-title small{ font-size:12.5px; color:var(--ink-3); }
.tb-actions{ display:flex; align-items:center; gap:8px; }
.branch-pick{
  width:auto; max-width:190px; padding:8px 32px 8px 13px; font-size:13px; font-weight:600;
  border-radius:var(--pill); background-color:var(--card);
}
#view{ flex:1; padding:20px 22px 40px; max-width:1240px; width:100%; margin:0 auto; }

#tabbar{ display:none; }
#scrim{
  position:fixed; inset:0; background:rgba(26,22,38,.42); z-index:39;
  animation:fade .1s;
}
@keyframes fade{ from{ opacity:0; } }

/* ── mobile ──────────────────────────────────────────────────────────── */
@media (max-width:899px){
  #sidebar{ transform:translateX(-100%); box-shadow:var(--sh-2); }
  #sidebar.open{ transform:none; }
  #main{ margin-left:0; padding-bottom:calc(var(--tab-h) + env(safe-area-inset-bottom)); }
  #topbar{ padding:12px 14px; }
  .tb-title h2{ font-size:18px; }
  #view{ padding:16px 14px 30px; }
  #tabbar{
    position:fixed; left:0; right:0; bottom:0; z-index:35; display:flex;
    height:calc(var(--tab-h) + env(safe-area-inset-bottom));
    padding-bottom:env(safe-area-inset-bottom);
    background:var(--tabbar-bg);
    border-top:1px solid var(--line);
  }
  .tab{
    flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:3px; border:0; background:none; cursor:pointer; color:var(--ink-3);
    font-size:10.5px; font-weight:650; padding:0 2px;
  }
  .tab .ic{ font-size:20px; line-height:1; }
  .tab.on{ color:var(--pri); }
  .tab span{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%; }
}
@media (min-width:900px){ .only-mobile{ display:none !important; } }
@media (max-width:899px){ .only-desktop{ display:none !important; } }

/* ═══════════════════════════════════════════════════════════════════════
   CARDS & LAYOUT
   ═══════════════════════════════════════════════════════════════════════ */
.card{
  background:var(--card); border-radius:var(--r-lg); padding:14px;
  border:var(--bord); margin-bottom:10px;
}
.card.tight{ padding:10px; }
.card.flat{ background:var(--bg); }
.scroll-y{ overflow-y:auto; }
ul.tight{ margin:6px 0 0; padding-left:20px; }
ul.tight li{ margin-bottom:2px; }
.card-h{ display:flex; align-items:center; gap:10px; margin-bottom:10px; }
.card-h h3{ font-size:16px; flex:1; min-width:0; }
.card-h .sub{ font-size:12.5px; color:var(--ink-3); font-weight:500; }

.grid{ display:grid; gap:12px; }
.g2{ grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); }
.g3{ grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); }
.g4{ grid-template-columns:repeat(auto-fit,minmax(168px,1fr)); }
.row{ display:flex; align-items:center; gap:10px; }
.row.wrap{ flex-wrap:wrap; }
/* Title on the left, actions on the right — used by every card header the
   foundation-spine screens add. Without this the two sides pack together. */
.row.between{ justify-content:space-between; }
.row.center{ align-items:center; }
/* Spacing utilities the markup already asks for. `gap` and `mb` mostly land on
   a .row or a .card that sets the same value itself, so they read as no-ops —
   but `mb` on a bare .row, and `mt`, had nothing behind them at all. Defining
   all three keeps the token meaning the same wherever it is written. */
.gap{ gap:10px; }
.mb{ margin-bottom:14px; }
.mt{ margin-top:14px; }
.spacer{ flex:1; }
.stack{ display:flex; flex-direction:column; gap:10px; }

.section-h{ display:flex; align-items:center; gap:10px; margin:22px 0 11px; }
.section-h h3{ font-size:14px; color:var(--ink-2); }
.section-h::after{ content:''; flex:1; height:1px; background:var(--line); }

/* ── stat tiles ──────────────────────────────────────────────────────── */
.stat{
  background:var(--card); border-radius:var(--r); padding:15px 15px 13px;
  border:var(--bord); position:relative;
}
.stat .k{ font-size:11px; font-weight:600; letter-spacing:.03em; text-transform:uppercase; color:var(--ink-3); }
.stat .v{ font-size:25px; font-weight:750; letter-spacing:-.03em; margin:6px 0 2px; }
.stat .d{ font-size:12px; color:var(--ink-3); }
/* the accent is a small dot, not a full bar — quieter, still colour-coded */
.stat .k::before{
  content:''; display:inline-block; width:7px; height:7px; border-radius:50%;
  background:var(--pri); margin-right:7px; vertical-align:1px;
}
.stat.blue .k::before{ background:var(--blue); }
.stat.green .k::before{ background:var(--green); }
.stat.yellow .k::before{ background:var(--yellow); }
.stat.red .k::before{ background:var(--red); }
.stat.pink .k::before{ background:var(--pink); }
.stat.teal .k::before{ background:var(--teal); }
.stat.tap{ cursor:pointer; transition:border-color .12s, background .12s; }
.stat.tap:hover{ border-color:var(--pri-300); background:var(--pri-50); }

/* ── chips / badges / pills ──────────────────────────────────────────── */
.badge{
  display:inline-flex; align-items:center; gap:5px; padding:3px 10px;
  border-radius:var(--pill); font-size:11.5px; font-weight:700;
  background:var(--pri-50); color:var(--pri-700); white-space:nowrap;
}
.badge.green{ background:var(--t-green-bg); color:var(--t-green-fg); }
.badge.red{   background:var(--t-red-bg); color:var(--t-red-fg); }
.badge.yellow{background:var(--t-yellow-bg); color:var(--t-yellow-fg); }
.badge.blue{  background:var(--t-blue-bg); color:var(--t-blue-fg); }
.badge.grey{  background:var(--line-2); color:var(--ink-3); }
.badge.teal{  background:var(--t-teal-bg); color:var(--t-teal-fg); }
.badge.pink{  background:var(--t-pink-bg); color:var(--t-pink-fg); }

.chips{ display:flex; gap:8px; overflow-x:auto; padding:2px 0 8px; scrollbar-width:none; }
.chips::-webkit-scrollbar{ display:none; }
.chip{
  flex:none; padding:8px 15px; border:1.5px solid var(--line); border-radius:var(--pill);
  background:var(--card); font-size:13px; font-weight:600; color:var(--ink-2); cursor:pointer;
  transition:all .14s; white-space:nowrap;
}
.chip:hover{ border-color:var(--pri-300); }
.chip.on{ background:var(--pri); border-color:var(--pri); color:#fff; box-shadow:var(--sh-pri); }

/* ── avatars ─────────────────────────────────────────────────────────── */
.av{
  width:40px; height:40px; flex:none; border-radius:var(--pill);
  background:var(--pri-100) center/cover no-repeat; color:var(--pri-700);
  display:inline-grid; place-items:center; font-size:14px; font-weight:800;
  border:0; cursor:pointer; overflow:hidden; letter-spacing:-.02em;
}
.av.sm{ width:34px; height:34px; font-size:12.5px; }
.av.lg{ width:60px; height:60px; font-size:20px; }
.av.xl{ width:82px; height:82px; font-size:27px; }
.av.c1{ background:var(--av1-bg); color:var(--av1-fg); }
.av.c2{ background:var(--av2-bg); color:var(--av2-fg); }
.av.c3{ background:var(--av3-bg); color:var(--av3-fg); }
.av.c4{ background:var(--av4-bg); color:var(--av4-fg); }
.av.c5{ background:var(--av5-bg); color:var(--av5-fg); }
.av.c6{ background:var(--av6-bg); color:var(--av6-fg); }

/* ── list rows ───────────────────────────────────────────────────────── */
.list{ display:flex; flex-direction:column; }
.item{
  display:flex; align-items:center; gap:12px; padding:12px 4px;
  border-bottom:1px solid var(--line-2); cursor:pointer; transition:background .12s;
  border-radius:var(--r-xs);
}
.item:last-child{ border-bottom:0; }
.item:hover{ background:var(--pri-50); }
.item.static{ cursor:default; }
.item.static:hover{ background:none; }
.item-b{ flex:1; min-width:0; }
.item-b strong{ display:block; font-size:14.5px; font-weight:650; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.item-b small{ display:block; font-size:12.5px; color:var(--ink-3); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.item-r{ text-align:right; flex:none; font-size:13px; color:var(--ink-3); }
.item-r strong{ display:block; font-size:14px; color:var(--ink); }
.chev{ color:#C9C3DA; font-size:18px; flex:none; }

/* .list-row: the notification centre's row. Same rhythm as .item above
   (padding, hairline separator, hover tint) but a real <button> — the brief
   calls for a plain-button click target here, and neither .item's markup
   nor its CSS existed for that shape, so this is a sibling pattern, not a
   duplicate of .item. */
.list-row{
  display:flex; align-items:center; gap:12px; width:100%; padding:9px 4px;
  border:0; border-bottom:1px solid var(--line-2); border-radius:var(--r-xs);
  background:none; font:inherit; color:inherit; text-align:left;
  cursor:pointer; transition:background .12s;
}
.list-row:last-child{ border-bottom:0; }
.list-row:hover{ background:var(--pri-50); }
.list-row .ic{ font-size:18px; width:24px; text-align:center; flex:none; }
.list-row .grow{ flex:1; min-width:0; }
/* --pri-50 is the light primary tint (same colour as --tint-pri, which also
   exists in this file); chosen over introducing a new token, per the brief. */
.list-row.unread{ background:var(--pri-50); }
.list-row.unread strong{ font-weight:700; }
.block{ display:block; }

/* ── tables ──────────────────────────────────────────────────────────── */
.tbl-wrap{ overflow-x:auto; border-radius:var(--r); border:1px solid var(--line); background:var(--card); }
table{ width:100%; border-collapse:collapse; font-size:13.5px; min-width:520px; }
thead th{
  text-align:left; padding:8px 12px; font-size:11px; font-weight:800;
  letter-spacing:.06em; text-transform:uppercase; color:var(--ink-3);
  background:var(--pri-50); white-space:nowrap; border-bottom:1px solid var(--line);
}
tbody td{ padding:8px 12px; border-bottom:1px solid var(--line-2); vertical-align:middle; }
tbody tr:last-child td{ border-bottom:0; }
tbody tr.tap{ cursor:pointer; }
tbody tr.tap:hover{ background:var(--pri-50); }
td.num,th.num{ text-align:right; font-variant-numeric:tabular-nums; }
td.nowrap{ white-space:nowrap; }

/* ── empty / loading ─────────────────────────────────────────────────── */
.empty{ text-align:center; padding:44px 20px; color:var(--ink-3); }
.empty .em{ font-size:42px; margin-bottom:10px; opacity:.75; }
.empty strong{ display:block; color:var(--ink-2); font-size:15px; margin-bottom:4px; }
.empty p{ font-size:13.5px; max-width:320px; margin:0 auto 14px; }
.skel{
  background:linear-gradient(90deg,var(--line-2) 25%,var(--skel-hi) 50%,var(--line-2) 75%);
  background-size:200% 100%; border-radius:var(--r-xs);
  height:14px; margin:9px 0;
}
@keyframes shimmer{ to{ background-position:-200% 0; } }

/* ═══════════════════════════════════════════════════════════════════════
   MODALS / SHEETS
   ═══════════════════════════════════════════════════════════════════════ */
.modal-back{
  position:fixed; inset:0; z-index:50; background:rgba(26,22,38,.5);
  display:flex; align-items:center; justify-content:center; padding:20px;
  animation:fade .1s;
}
.modal{
  width:100%; max-width:520px; max-height:88dvh; background:var(--card);
  border-radius:var(--r-xl); box-shadow:var(--sh-2); display:flex; flex-direction:column;
  animation:pop .12s ease-out;
}
.modal.wide{ max-width:800px; }
@keyframes pop{ from{ opacity:0; transform:translateY(14px) scale(.97); } }
.modal-h{ display:flex; align-items:flex-start; gap:12px; padding:22px 22px 12px; }
.modal-h h3{ font-size:18px; flex:1; }
.modal-h small{ display:block; font-size:12.5px; color:var(--ink-3); font-weight:500; margin-top:3px; }
.modal-b{ padding:0 22px; overflow-y:auto; flex:1; }
.modal-b > :first-child > label:first-child{ margin-top:0; }
.modal-f{ display:flex; gap:10px; padding:18px 22px 22px; }
.modal-f .btn{ flex:1; }
.x{ width:32px; height:32px; border:0; border-radius:var(--pill); background:var(--line-2);
    font-size:16px; cursor:pointer; color:var(--ink-3); flex:none; }
.x:hover{ background:var(--line); }

@media (max-width:640px){
  .modal-back{ align-items:flex-end; padding:0; }
  .modal{ max-width:none; max-height:92dvh; border-radius:var(--r-xl) var(--r-xl) 0 0;
          animation:slideup .14s ease-out; }
  @keyframes slideup{ from{ transform:translateY(100%); } }
  .modal-f{ padding-bottom:calc(22px + env(safe-area-inset-bottom)); }
}

/* ── toasts ──────────────────────────────────────────────────────────── */
#toastHost{
  position:fixed; left:50%; transform:translateX(-50%); bottom:calc(var(--tab-h) + 20px);
  z-index:70; display:flex; flex-direction:column; gap:8px; align-items:center;
  pointer-events:none; width:max-content; max-width:92vw;
}
@media (min-width:900px){ #toastHost{ bottom:24px; } }
.toast{
  padding:11px 18px; border-radius:var(--pill); background:var(--ink); color:var(--bg);
  font-size:13.5px; font-weight:600; box-shadow:var(--sh-2); animation:pop .12s ease-out;
}
.toast.ok{ background:#1E7F31; }
.toast.err{ background:#C01640; }

/* ═══════════════════════════════════════════════════════════════════════
   FEATURE BITS
   ═══════════════════════════════════════════════════════════════════════ */

/* hero — a plain card, not a coloured banner. Quiet header for a screen. */
.hero{
  border-radius:var(--r-lg); padding:18px; color:var(--ink); margin-bottom:14px;
  background:var(--card); border:var(--bord); position:relative;
}
.hero .h-top{ display:flex; align-items:center; gap:13px; position:relative; z-index:1; }
.hero h2{ font-size:19px; }
.hero small{ color:var(--ink-3); font-size:13px; }
.hero .h-stats{ display:flex; gap:26px; margin-top:16px; padding-top:14px; border-top:var(--bord); }
.hero .h-stats div span{ display:block; font-size:11px; color:var(--ink-3); text-transform:uppercase; letter-spacing:.04em; font-weight:600; }
.hero .h-stats div strong{ font-size:18px; }

/* child switcher */
.kid-strip{ display:flex; gap:10px; overflow-x:auto; padding:2px 0 10px; scrollbar-width:none; }
.kid-strip::-webkit-scrollbar{ display:none; }
.kid{
  flex:none; display:flex; flex-direction:column; align-items:center; gap:6px;
  padding:8px 6px 6px; border:0; background:none; cursor:pointer; width:74px;
}
.kid .av{ width:52px; height:52px; font-size:17px; border:3px solid transparent; transition:border-color .15s; }
.kid.on .av{ border-color:var(--pri); }
.kid small{ font-size:11.5px; font-weight:600; color:var(--ink-3);
  max-width:70px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.kid.on small{ color:var(--pri-700); }

/* the 15-parameter rating grid */
.param{ padding:14px 0; border-bottom:1px solid var(--line-2); }
.param:last-child{ border-bottom:0; }
.param-h{ display:flex; align-items:baseline; gap:8px; margin-bottom:3px; }
.param-h strong{ font-size:14px; flex:1; }
.param-h .badge{ flex:none; }
.param .helper{ font-size:12px; color:var(--ink-3); margin-bottom:9px; }
.rate{ display:flex; gap:6px; }
.rate button{
  flex:1; padding:8px 0; border:1.5px solid var(--line); border-radius:var(--r-xs);
  background:var(--card); font-size:12.5px; font-weight:700; color:var(--ink-3); cursor:pointer;
  transition:all .13s;
}
.rate button:hover{ border-color:var(--pri-300); }
.rate button.on{ background:var(--pri); border-color:var(--pri); color:#fff; }
.rate-legend{ display:flex; gap:6px; font-size:10px; color:var(--ink-3); margin-top:6px; }
.rate-legend span{ flex:1; text-align:center; }

/* score bars (published anecdotal view) */
.bar-row{ display:flex; align-items:center; gap:10px; padding:7px 0; }
.bar-row .nm{ flex:1; font-size:13.5px; min-width:0; }
.bar{ width:104px; height:8px; border-radius:var(--pill); background:var(--line-2); overflow:hidden; flex:none; }
.bar i{ display:block; height:100%; border-radius:var(--pill); background:var(--pri); }
.bar-row .sc{ width:34px; text-align:right; font-size:12.5px; font-weight:700; color:var(--pri-700); }

/* photo gallery */
.gal{ display:grid; grid-template-columns:repeat(auto-fill,minmax(108px,1fr)); gap:8px; }
.gal figure{ margin:0; position:relative; aspect-ratio:1; border-radius:var(--r-sm);
  overflow:hidden; background:var(--line-2); cursor:pointer; }
.gal img{ width:100%; height:100%; object-fit:cover; display:block; }
.gal .vid{ position:absolute; inset:auto 6px 6px auto; background:rgba(0,0,0,.55);
  color:#fff; border-radius:var(--pill); font-size:10px; padding:2px 7px; font-weight:700; }
.lightbox{ position:fixed; inset:0; z-index:80; background:rgba(10,8,16,.94);
  display:flex; align-items:center; justify-content:center; padding:16px; animation:fade .1s; }
.lightbox img,.lightbox video{ max-width:100%; max-height:86dvh; border-radius:var(--r); }
.lightbox .cap{ position:absolute; left:0; right:0; bottom:22px; text-align:center;
  color:#fff; font-size:13.5px; padding:0 20px; }
.lightbox .x{ position:absolute; top:16px; right:16px; background:rgba(255,255,255,.16); color:#fff; }

/* timeline */
.tl{ position:relative; padding-left:26px; }
.tl::before{ content:''; position:absolute; left:7px; top:6px; bottom:6px; width:2px; background:var(--line); }
.tl-item{ position:relative; padding:0 0 20px; }
.tl-item::before{
  content:''; position:absolute; left:-23px; top:5px; width:12px; height:12px;
  border-radius:50%; background:var(--pri); border:2.5px solid var(--card); box-shadow:0 0 0 2px var(--pri-100);
}
.tl-item.done::before{ background:var(--green); box-shadow:0 0 0 2px #DFF6E3; }
.tl-item.todo::before{ background:var(--line); box-shadow:0 0 0 2px var(--line-2); }
.tl-item strong{ font-size:14px; }
.tl-item small{ display:block; font-size:12.5px; color:var(--ink-3); }

/* check in / out */
.io{ display:flex; align-items:center; gap:12px; padding:12px; border-radius:var(--r);
     border:1.5px solid var(--line); margin-bottom:9px; background:var(--card); }
.io.in{ border-color:var(--t-green-fg); background:var(--t-green-bg); }
.io.out{ border-color:var(--line); background:var(--card); }
.io-t{ font-variant-numeric:tabular-nums; font-size:12.5px; color:var(--ink-3); }

/* van tracking map-ish strip */
.route{ display:flex; align-items:center; padding:16px 0 8px; overflow-x:auto; }
.route-stop{ flex:none; text-align:center; width:88px; position:relative; }
.route-stop::before{
  content:''; position:absolute; top:9px; left:-50%; width:100%; height:3px; background:var(--line);
}
.route-stop:first-child::before{ display:none; }
.route-stop.done::before{ background:var(--green); }
.route-dot{ width:20px; height:20px; margin:0 auto 6px; border-radius:50%;
  background:var(--card); border:3px solid var(--line); position:relative; z-index:1; }
.route-stop.done .route-dot{ background:var(--green); border-color:var(--green); }
.route-stop.now .route-dot{ background:var(--pri); border-color:var(--pri);
  box-shadow:0 0 0 5px var(--pri-100); }
@keyframes pulse{ 50%{ box-shadow:0 0 0 10px rgba(124,58,237,0); } }
.route-stop small{ font-size:11px; color:var(--ink-3); display:block; line-height:1.3; }
.route-stop.now small{ color:var(--pri-700); font-weight:700; }

/* receipt */
.receipt{ background:var(--card); border-radius:var(--r); padding:24px;
  border:1px solid var(--line); font-size:13.5px; }
.receipt .r-head{ text-align:center; border-bottom:2px dashed var(--line); padding-bottom:16px; margin-bottom:16px; }
.receipt .r-head img{ width:110px; margin-bottom:8px; }
.receipt .r-head h3{ font-size:16px; }
.receipt .r-head small{ color:var(--ink-3); font-size:12px; }
.receipt dl{ display:grid; grid-template-columns:auto 1fr; gap:7px 16px; margin:0 0 16px; }
.receipt dt{ color:var(--ink-3); font-size:12.5px; }
.receipt dd{ margin:0; text-align:right; font-weight:600; }
.receipt .r-total{ display:flex; justify-content:space-between; padding:13px 0;
  border-top:2px dashed var(--line); border-bottom:2px dashed var(--line); font-size:16px; font-weight:800; }
.receipt .r-foot{ text-align:center; color:var(--ink-3); font-size:11.5px; margin-top:16px; }

@media print{
  @page{ margin:12mm; }
  #sidebar,#topbar,#tabbar,.modal-f,.no-print,#scrim,#toastHost{ display:none !important; }
  #main{ margin:0; } #view{ padding:0; }
  .modal-back{ position:static; background:none; padding:0; backdrop-filter:none; display:block; }
  .modal{ max-width:none; max-height:none; box-shadow:none; animation:none; border-radius:0; }
  .modal-b{ overflow:visible !important; max-height:none !important; padding:0; }
  .modal-h .x{ display:none !important; }
  .receipt{ border:0; padding:0; }
  body{ background:#fff; }

  /* Printing a receipt / certificate / report card: the page behind the
     dialog must not print too, or you get the dashboard on page 1 and the
     receipt on page 2. `printing` is set by printModal() just before
     window.print() and removed straight after. */
  body.printing #app{ display:none !important; }
  body.printing #modalHost .modal-back:not(:last-child){ display:none !important; }
}

/* progress meter */
.meter{ height:9px; border-radius:var(--pill); background:var(--line-2); overflow:hidden; }
.meter i{ display:block; height:100%; background:var(--pri); border-radius:var(--pill); transition:width .2s; }
.meter.green i{ background:var(--green); }
.meter.red i{ background:var(--bad); }
.meter.yellow i{ background:var(--yellow); }

/* ── calendar ───────────────────────────────────────────────────────── */
.cal-grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:4px; }
.cal-head{ margin-bottom:6px; }
.cal-head div{ text-align:center; font-size:10.5px; font-weight:800; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-3); padding:4px 0; }
.cal-cell{
  min-height:88px; border:1px solid var(--line-2); border-radius:var(--r-xs);
  padding:5px; cursor:pointer; overflow:hidden; transition:border-color .12s, background .12s;
  display:flex; flex-direction:column; gap:3px;
}
.cal-cell:hover{ border-color:var(--pri-300); background:var(--pri-50); }
.cal-cell.empty{ border:0; background:none; cursor:default; }
.cal-cell.sun .cal-n{ color:var(--bad); }
.cal-cell.today{ border-color:var(--pri); background:var(--pri-50); }
.cal-cell.today .cal-n{ background:var(--pri); color:#fff; border-radius:var(--pill); }
.cal-n{ font-size:12px; font-weight:700; color:var(--ink-2); min-width:20px; height:20px;
  display:inline-grid; place-items:center; }
.cal-evs{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.cal-ev{
  font-size:10px; font-weight:650; padding:2px 5px; border-radius:5px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  background:var(--pri-100); color:var(--pri-700);
}
.cal-ev.red{ background:var(--t-red-bg); color:var(--t-red-fg); }
.cal-ev.green{ background:var(--t-green-bg); color:var(--t-green-fg); }
.cal-ev.yellow{ background:var(--t-yellow-bg); color:var(--t-yellow-fg); }
.cal-ev.blue{ background:var(--t-blue-bg); color:var(--t-blue-fg); }
.cal-ev.teal{ background:var(--t-teal-bg); color:var(--t-teal-fg); }
.cal-ev.pink{ background:var(--t-pink-bg); color:var(--t-pink-fg); }
.cal-more{ font-size:9.5px; color:var(--ink-3); padding-left:5px; }
@media (max-width:640px){
  .cal-cell{ min-height:62px; padding:3px; }
  .cal-ev{ font-size:0; padding:0; height:5px; border-radius:3px; }
  .cal-more{ display:none; }
}

/* phone number + WhatsApp */
.ph{ display:inline-flex; align-items:center; gap:7px; }
.wa-btn{
  display:inline-grid; place-items:center; width:26px; height:26px; flex:none;
  border-radius:var(--pill); background:#25D366; color:#fff; text-decoration:none;
  transition:transform .12s, filter .12s;
}
.wa-btn:hover{ transform:scale(1.08); filter:brightness(1.06); }
.wa-btn:active{ transform:scale(.94); }
.wa-btn svg{ display:block; }
.item-r .wa-btn, .toolbar .wa-btn{ vertical-align:middle; }

/* tinted callouts — theme-aware, replaces hard-coded pastel hexes */
[tint="warn"]{ background:var(--tint-warn) !important; }
[tint="ok"]{   background:var(--tint-ok)   !important; }
[tint="bad"]{  background:var(--tint-bad)  !important; }
[tint="pri"]{  background:var(--tint-pri)  !important; }
[tint="bad"] strong{ color:var(--bad); }

/* ── SVG charts ─────────────────────────────────────────────────────── */
.viz{ position:relative; }
.viz svg{ display:block; width:100%; height:auto; overflow:visible; }
.viz .gridline{ stroke:var(--grid); stroke-width:1; }
.viz .axis-lbl{ fill:var(--ink-3); font-size:11px; font-family:var(--fs); }
.viz .val-lbl{ fill:var(--ink-2); font-size:11px; font-weight:700; font-family:var(--fs); }
.viz .dot{ stroke:var(--card); stroke-width:2; }
.viz .hit{ fill:transparent; cursor:crosshair; }
.viz .crosshair{ stroke:var(--axis); stroke-width:1; stroke-dasharray:3 3; opacity:0; }
.viz.on .crosshair{ opacity:1; }

.viz-tip{
  position:absolute; z-index:5; pointer-events:none; opacity:0;
  transform:translate(-50%,-115%); transition:opacity .12s;
  background:var(--ink); color:var(--bg); border-radius:var(--r-xs);
  padding:7px 10px; font-size:12px; font-weight:600; white-space:nowrap;
  box-shadow:var(--sh-2);
}
.viz-tip.on{ opacity:1; }
.viz-tip b{ display:block; font-size:11px; opacity:.75; font-weight:600; margin-bottom:2px; }
.viz-tip i{ display:inline-block; width:9px; height:9px; border-radius:3px; margin-right:6px; }

/* legend — always present for 2+ series */
.viz-key{ display:flex; flex-wrap:wrap; gap:6px 16px; margin-top:12px; font-size:12.5px; color:var(--ink-2); }
.viz-key span{ display:inline-flex; align-items:center; gap:7px; }
.viz-key i{ width:11px; height:11px; border-radius:4px; flex:none; }

/* horizontal bars — better for long class names */
.hbar{ display:flex; flex-direction:column; gap:9px; }
.hbar-row{ display:grid; grid-template-columns:96px 1fr auto; align-items:center; gap:10px; font-size:13px; }
.hbar-row .nm{ color:var(--ink-2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.hbar-track{ background:var(--line-2); border-radius:var(--pill); height:16px; overflow:hidden; }
.hbar-track i{ display:block; height:100%; border-radius:var(--pill); min-width:3px; }
.hbar-row b{ font-variant-numeric:tabular-nums; font-size:13px; min-width:34px; text-align:right; }

.spark{ display:block; width:100%; height:30px; overflow:visible; }

/* mini bar chart for dashboards */
.chart{ display:flex; align-items:flex-end; gap:7px; height:130px; padding-top:10px; }
.chart .col{ flex:1; display:flex; flex-direction:column; justify-content:flex-end;
  align-items:center; gap:6px; height:100%; }
.chart .col i{ display:block; width:100%; max-width:34px; border-radius:var(--r-xs) var(--r-xs) 3px 3px;
  background:var(--pri); min-height:3px; }
.chart .col small{ font-size:10.5px; color:var(--ink-3); text-align:center; line-height:1.2; }
.chart .col b{ font-size:11px; color:var(--ink-2); }

/* donut */
.donut{ width:118px; height:118px; border-radius:50%; flex:none;
  display:grid; place-items:center; position:relative; }
.donut::after{ content:''; position:absolute; inset:15px; border-radius:50%; background:var(--card); }
.donut .dv{ position:relative; z-index:1; text-align:center; }
.donut .dv strong{ display:block; font-size:21px; font-weight:800; letter-spacing:-.03em; }
.donut .dv small{ font-size:10.5px; color:var(--ink-3); }

.legend{ display:flex; flex-direction:column; gap:7px; font-size:13px; }
.legend div{ display:flex; align-items:center; gap:8px; }
.legend i{ width:11px; height:11px; border-radius:4px; flex:none; }
.legend .spacer{ flex:1; }
.legend b{ font-variant-numeric:tabular-nums; }

/* file drop */
.drop{
  border:2px dashed var(--pri-300); border-radius:var(--r); padding:26px 16px;
  text-align:center; background:var(--pri-50); cursor:pointer; transition:background .15s;
}
.drop:hover{ background:var(--pri-100); }
.drop .em{ font-size:30px; display:block; margin-bottom:6px; }
.drop small{ color:var(--ink-3); font-size:12.5px; }

/* thumbs strip while uploading */
.thumbs{ display:flex; gap:8px; flex-wrap:wrap; margin-top:12px; }
.thumbs figure{ margin:0; width:70px; height:70px; border-radius:var(--r-xs);
  overflow:hidden; position:relative; background:var(--line-2); }
.thumbs img{ width:100%; height:100%; object-fit:cover; }
.thumbs .rm{ position:absolute; top:2px; right:2px; width:20px; height:20px; border:0;
  border-radius:50%; background:rgba(0,0,0,.6); color:#fff; font-size:11px; cursor:pointer; line-height:1; }

/* segmented control */
.seg{ display:flex; background:var(--line-2); border-radius:var(--pill); padding:3px; gap:2px; }
.seg button{ flex:1; padding:8px 12px; border:0; border-radius:var(--pill); background:none;
  font-size:13px; font-weight:600; color:var(--ink-3); cursor:pointer; transition:color .12s, background .12s; white-space:nowrap; }
.seg button.on{ background:var(--card); color:var(--pri-700); }

/* search bar */
.search{ position:relative; margin-bottom:14px; }
.search input{ padding-left:40px; border-radius:var(--pill); }
.search::before{ content:'🔍'; position:absolute; left:14px; top:50%; transform:translateY(-50%);
  font-size:14px; opacity:.45; pointer-events:none; }

/* ── the one search box: children, staff, screens ─────────────────────
   Its own backdrop rather than #scrim, because the scrim's single click
   handler closes the sidebar and hides itself — which would leave this
   panel floating over a page with nothing behind it. Below .modal-back
   (50) on purpose, so the staff card opens over the results. */
#srBox{
  position:fixed; inset:0; z-index:48; background:rgba(26,22,38,.42);
  display:flex; justify-content:center; align-items:flex-start;
  padding:72px 16px 16px; animation:fade .1s;
}
.sr-panel{
  width:100%; max-width:560px; background:var(--card); border-radius:var(--r-xl);
  box-shadow:var(--sh-2); padding:14px 14px 6px; max-height:78dvh;
  display:flex; flex-direction:column; animation:pop .12s ease-out;
}
.sr-panel .search{ margin-bottom:10px; flex:0 0 auto; }
.sr-out{ overflow-y:auto; padding-bottom:10px; }
.sr-sec label{
  display:block; font-size:11px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-3); margin:8px 2px 4px;
}
.sr-out .item{ width:100%; text-align:left; border:0; background:none; font:inherit; }
@media (max-width:560px){ #srBox{ padding:56px 10px 10px; } .sr-panel{ max-height:86dvh; } }

/* the top-bar trigger */
#searchBtn{ font-size:15px; }

/* fab */
.fab{
  position:fixed; right:18px; bottom:calc(var(--tab-h) + 18px + env(safe-area-inset-bottom));
  z-index:36; width:54px; height:54px; border:0; border-radius:var(--pill);
  background:var(--pri); color:#fff; font-size:25px; line-height:1;
  box-shadow:0 4px 16px rgba(26,22,38,.18); cursor:pointer; display:grid; place-items:center;
  transition:transform .12s, background .12s;
}
.fab:hover{ background:var(--pri-600); }
.fab:active{ transform:scale(.93); }
@media (min-width:900px){ .fab{ bottom:26px; right:26px; } }

/* the language picker: header-sized on the login screen, full width in a form */
.lang-pick{ width:auto; min-width:140px; padding:9px 32px 9px 13px; font-size:13.5px;
  border-radius:var(--pill); background-color:var(--card); }
#loginLang{ margin-top:10px; }

/* ── working in a past academic year ─────────────────────────────────
   Deliberately not a toast and not a modal. It has to be true for as long
   as the state is true: everything created while it shows is stamped with
   that year, and the person who most needs telling is the one who forgot
   they switched an hour ago. */
#yearBar{ padding:0 22px; max-width:1240px; width:100%; margin:14px auto 0; }
.year-bar{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:10px 14px; border-radius:var(--r-lg);
  background:var(--tint-warn); border:1px solid var(--warn);
  font-size:13.5px; line-height:1.5;
}
.year-bar > span{ flex:1; min-width:200px; }
@media (max-width:899px){ #yearBar{ padding:0 14px; } }

/* ── the floating dock: quick create + help ──────────────────────────
   Stacked bottom-right in the same corner the screens' own .fab uses —
   paintFabs() empties this dock on screens that have one, so the two are
   never both there. The dock itself is not a layer: each button keeps
   position:fixed, so the stack survives the dock being emptied. */
#fabDock{ position:fixed; inset:auto 0 0 auto; z-index:37; }
.fab.help{
  right:18px; bottom:calc(var(--tab-h) + 82px + env(safe-area-inset-bottom));
  width:44px; height:44px; font-size:19px; font-weight:700;
  background:var(--card); color:var(--pri-700); box-shadow:var(--sh-1);
  border:1px solid var(--line);
}
.fab.help:hover{ background:var(--line-2); }
#quickFab{ transition:transform .14s, background .12s; }
#quickFab.on{ transform:rotate(45deg); }
.quick-menu{
  position:fixed; right:18px; bottom:calc(var(--tab-h) + 82px + env(safe-area-inset-bottom));
  z-index:37; display:flex; flex-direction:column; gap:6px; align-items:stretch;
  background:var(--card); border:1px solid var(--line); border-radius:var(--r-lg);
  box-shadow:var(--sh-2); padding:6px; min-width:210px; animation:pop .12s ease-out;
  /* Seven items come to about 330px. On a short laptop window — 450px tall
     with a tab bar under it — that ran off the top of the screen and the
     first two items could not be reached at all. */
  max-height:min(62dvh, 420px); overflow-y:auto;
}
.quick-menu.hidden{ display:none; }
.quick-item{
  display:flex; align-items:center; gap:10px; width:100%; text-align:left;
  padding:10px 12px; border:0; border-radius:var(--r-sm); background:none;
  font:inherit; font-size:14px; font-weight:600; color:var(--ink); cursor:pointer;
}
.quick-item:hover{ background:var(--line-2); }
/* the help button moves up out of the menu's way when both are shown */
#fabDock:has(#quickMenu) .fab.help{
  bottom:calc(var(--tab-h) + 22px + env(safe-area-inset-bottom)); right:82px;
}
@media (min-width:900px){
  .fab.help{ bottom:90px; right:26px; }
  .quick-menu{ bottom:90px; right:26px; }
  #fabDock:has(#quickMenu) .fab.help{ bottom:30px; right:90px; }
}

/* form grid used by the modal form engine */
.fgrid{ display:grid; grid-template-columns:1fr 1fr; gap:0 14px; align-items:start; }
.fgrid > .full{ grid-column:1 / -1; }
.fgrid > .section-h{ grid-column:1 / -1; }
@media (max-width:560px){ .fgrid{ grid-template-columns:1fr; } .fgrid > *{ grid-column:1 / -1; } }

/* page toolbar: search + filters + actions */
.toolbar{ display:flex; flex-wrap:wrap; align-items:center; gap:10px; margin-bottom:14px; }
.toolbar .search{ flex:1; min-width:190px; margin:0; }
.toolbar select{ width:auto; min-width:130px; padding:10px 34px 10px 13px;
  font-size:13.5px; border-radius:var(--pill); }

/* key/value detail block */
.kv{ display:grid; grid-template-columns:auto 1fr; gap:9px 18px; font-size:13.5px; }
.kv dt{ color:var(--ink-3); }
.kv dd{ margin:0; font-weight:600; text-align:right; overflow-wrap:anywhere; }

/* misc */
.mono{ font-variant-numeric:tabular-nums; }
.muted{ color:var(--ink-3); }
.tiny{ font-size:12px; }
.strong-num{ font-size:17px; font-weight:800; letter-spacing:-.02em; }
.divider{ height:1px; background:var(--line); margin:16px 0; }
.center{ text-align:center; }
.right{ text-align:right; }
.pointer{ cursor:pointer; }
.nowrap{ white-space:nowrap; }
.wrap-any{ overflow-wrap:anywhere; }
.pre{ white-space:pre-wrap; }

/* ── Motion ────────────────────────────────────────────────────────────
   The app runs on whatever phone a teacher already owns, often a cheap
   Android, and the screens people use most are long lists. So motion here
   is functional only: something appearing, something loading. Nothing
   decorative, nothing that runs forever.

   Two infinite animations were removed rather than shortened — a shimmer
   on every loading skeleton and a pulsing dot on the live van stop. Both
   repainted continuously for as long as they were on screen, which on a
   list of 160 children is the single most expensive thing the CSS did.
   Every backdrop-filter: blur() went for the same reason. Each one forces a
   composite on every frame, and the top bar and tab bar are on screen
   permanently, so theirs ran during every scroll. The bars are now opaque
   rather than frosted, which is the only visible change.

   Anyone who has asked their device to reduce motion gets none at all. */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}
