/* ==========================================================================
   Effred ecosystem — design system
   --------------------------------------------------------------------------
   One shell, seven portals. The grammar is deliberately inherited from the
   SSL Certificate Manager: a 46 px sticky strip of navigation, pill tabs, a
   dense data grid, Inter + JetBrains Mono, light by default with a dark
   toggle. What is new here is the ecosystem layer — portal cards, a product
   switcher, the rainbow profile ring, and a load strip that also reports
   itself as a circle inside the nav.

   Labels are short on purpose. A column is "Joined", not "Date of joining".
   Anything longer than two words belongs in a tooltip, not on the screen.

   Every time on screen is India Standard Time.
   ========================================================================== */

/* -- Light (default) ------------------------------------------------------
   One palette, retuned. The product used to be blue on grey; it is now green
   on a soft sage ground, which is the one change that reaches all 117 screens
   without any of them being edited — every part of the kit reads its colour
   from here rather than carrying its own.

   Two rules survived the retune unchanged, because both are about legibility
   rather than taste: the semantic colours are TEXT colours and are dark
   enough for a 9 px pill to clear 4.5:1 on its own tint, and the graph tones
   are a second, brighter set for marks that only need 3:1. Never swap one for
   the other.
   -------------------------------------------------------------------------- */
:root{
  /* surfaces. --bg is the page, --bg2 every card on it. The page is tinted
     and the card is white, which is what gives a screen of cards its edges
     without a border having to do all the work. */
  --bg:#EDF1EF; --bg2:#fff; --bg3:#E8EFEB; --bgH:#DFE8E3; --bgI:#F5F8F6;
  --bd:#E0E7E3; --bdL:#EDF2EF;
  /* ink */
  --tx:#16261F; --tx2:#3C4A44;
  /* Muted text. #64756D is what the new palette started at and it cleared
     4.5:1 on white and 4.17:1 on the tinted card ground — which is where
     most of it actually sits: every .ki-sub, .cd-s, .hint and .agd-s in
     the product is muted text on --bg3 or on the page. Two steps darker
     clears 4.5:1 against all four surfaces the kit puts it on. */
  --tx3:#5A6B63;
  /* Brand and semantics. These are TEXT colours — on a 9 px status pill they
     have to clear 4.5:1 against their own tint, which is why the greens and
     ambers are darker here than the portal accents below. */
  --ac:#0E7A5C; --acBg:#E3F0EA; --acD:#0A5C46;
  --gn:#12704F; --gnBg:#E4F1EA;
  --am:#8A5206; --amBg:#FCEFDF;
  --rd:#AF3418; --rdBg:#FBEAE4;
  --bl:#1F5F9E; --blBg:#E9F1F8;
  --vi:#5744BC; --viBg:#EFEDFB;
  --te:#0A6E72; --teBg:#E2F1F1;
  --or:#A0521B; --orBg:#FBEEE3;
  --sl:#44564F; --slBg:#E9EEEB;
  /* Graph tones. Also GRAPHIC — a 3 px bar, a 2 px line, an arc. The text
     tones above are dark because a 9 px label on a tint has to clear 4.5:1;
     a chart drawn in them looks like mud, so these are the same hues at the
     saturation a chart wants. Never use one of these for text. */
  --g-gn:#12996F; --g-rd:#E4572E; --g-am:#D98324; --g-bl:#2F6FB8;
  --g-vi:#6C5CE0; --g-te:#0E9AA0; --g-gy:#9EAAA4;
  /* Portal accents. These are GRAPHIC colours — icon strokes and 3 px rails,
     which need 3:1, not 4.5:1. Keeping them vivid is what stops the seven
     portals from turning into seven shades of the house green. */
  --p-dash:#0E7A5C; --p-ems:#0E9AA0; --p-hrms:#5B58D6; --p-acct:#12996F;
  --p-docs:#B98311; --p-amc:#DD6B20; --p-legal:#7358CC; --p-admin:#44564F;
  /* shape. Rounder than it was: 6 px on a control next to a 14 px card read
     as two different products sharing a page. */
  --r:9px; --rl:11px; --rx:14px; --rp:999px;
  /* Shadows are tinted with the ink rather than pure black. On a sage ground
     a neutral-black shadow greys the edge of every card. */
  --sh:0 1px 2px rgba(22,38,31,.05);
  --shM:0 4px 14px rgba(22,38,31,.07);
  --shL:0 18px 46px rgba(22,38,31,.14);
  --ring:0 0 0 3px var(--acBg);
  /* type */
  --f:'Plus Jakarta Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --fm:'JetBrains Mono',ui-monospace,Consolas,monospace;
  --nav-h:56px;
}


/* -- Base ----------------------------------------------------------------- */
*{margin:0;padding:0;box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{font-family:var(--f);background:var(--bg);color:var(--tx);font-size:13px;
  min-height:100vh;-webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  /* Figures line up in a column. Every screen in this product is a column of
     numbers, and proportional digits make a total look ragged. */
  font-variant-numeric:tabular-nums;
  /* The disambiguation the old face got from Inter's cv05/cv08/cv11 comes
     from the mono face here instead: every code somebody reads aloud and
     types back — EMP0011, an IFSC, a UTR — is rendered in .mono, where a
     `1`, an `l` and an `I` are three different shapes by construction. The
     cvXX axes were Inter's alone and did nothing once the face changed. */
  font-optical-sizing:auto;
  line-height:1.5;text-rendering:optimizeLegibility}
::selection{background:var(--ac);color:#fff}
a{color:var(--ac);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4{line-height:1.25;letter-spacing:-.022em;font-weight:600}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--bd);border-radius:5px}
::-webkit-scrollbar-thumb:hover{background:var(--tx3)}
:focus-visible{outline:2px solid var(--ac);outline-offset:1px}
svg.i{width:14px;height:14px;flex-shrink:0;stroke:currentColor;fill:none;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.btn svg.i{width:13px;height:13px}
.ico-btn svg.i{width:13px;height:13px}
.tab svg.i{width:13px;height:13px}
.empty svg.i{width:24px;height:24px}
.pc-ic svg.i{width:19px;height:19px;stroke-width:1.7}
.ki-ic svg.i{width:15px;height:15px}

/* Density is a user preference; it only ever changes padding, never type. */
body[data-density="compact"] table.dt td{padding:4px 9px}
body[data-density="relaxed"] table.dt td{padding:10px 12px}

/* == 1. Load strip + nav circle ============================================
   Two views of one state. The strip answers "is something happening"; the
   circle in the nav answers "is it still happening" once the strip has run
   to 90% and parked there. */
#loadbar{position:fixed;top:0;left:0;height:2px;width:0;z-index:2000;
  background:linear-gradient(90deg,var(--ac),var(--te) 45%,var(--vi));
  box-shadow:0 0 10px var(--ac);opacity:1;
  transition:width .25s cubic-bezier(.2,.7,.3,1),opacity .35s}
#loadbar.done{opacity:0}
.navspin{width:15px;height:15px;border-radius:50%;flex-shrink:0;
  border:1.8px solid var(--bd);border-top-color:var(--ac);
  animation:spin .62s linear infinite;opacity:0;
  transition:opacity .2s;margin:0 2px}
.navspin.on{opacity:1}
@keyframes spin{to{transform:rotate(360deg)}}
.ld-spin{display:inline-block;width:16px;height:16px;border:2px solid var(--bd);
  border-top-color:var(--ac);border-radius:50%;animation:spin .62s linear infinite}
.loader-w{display:flex;align-items:center;justify-content:center;padding:38px;
  gap:9px;color:var(--tx3);font-size:11px;font-weight:600}

/* == 2. Top navigation strip =============================================== */
.nav{position:sticky;top:0;z-index:120;background:var(--bg2);
  border-bottom:1px solid var(--bd)}
.nav-in{display:flex;align-items:center;height:var(--nav-h);padding:0 16px;gap:9px;
  max-width:1860px;margin:0 auto}
.nav-brand{font-weight:700;font-size:15px;letter-spacing:-.028em;white-space:nowrap;
  display:flex;align-items:center;gap:9px;color:var(--tx);flex-shrink:0}
.nav-brand:hover{text-decoration:none;opacity:.82}
.nav-logo{height:28px;width:auto;display:block}
.nav-mark{width:32px;height:32px;border-radius:10px;display:grid;place-items:center;
  background:linear-gradient(150deg,var(--ac),var(--acD));color:#fff;font-size:14px;
  font-weight:700;letter-spacing:-.02em;flex-shrink:0}
/* The drawn mark sits a little heavier than a UI icon: at 17 px on a coloured
   tile a 1.9 stroke goes thin and the arms start to disappear. */
.nav-mark svg.i{width:17px;height:17px;stroke-width:2.2}

/* == The name lockup =======================================================
   A product name with "by Effred" under it, set small.

   It exists because the two things are not the same claim. "007 AI Agent" is
   what the thing is called; "by Effred" is who stands behind it, and on a
   customer's own portal that second line is the only place the word Effred
   appears at all. Setting them on one line made the maker part of the name;
   stacking them at two different sizes says one is the name and the other is
   the maker, which is what a lockup is for.

   Deliberately not a badge, a pill or a ribbon — it is two lines of type. */
.lk{display:flex;flex-direction:column;justify-content:center;min-width:0;
  line-height:1.05;gap:1px}
.lk-n{font-size:15px;font-weight:700;letter-spacing:-.028em;color:var(--tx);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lk-b{font-size:9px;font-weight:600;letter-spacing:.32px;color:var(--tx3);
  white-space:nowrap}
.lk.sm .lk-n{font-size:13px} .lk.sm .lk-b{font-size:8.5px}
.lk.lg .lk-n{font-size:21px;letter-spacing:-.035em} .lk.lg .lk-b{font-size:10px}
.sep{width:1px;height:16px;background:var(--bd);flex-shrink:0}
/* The tenant chip. Which company am I inside — always answerable at a glance. */
.nav-tenant{display:flex;align-items:center;gap:6px;padding:3px 8px 3px 4px;
  border:1px solid var(--bd);border-radius:var(--rp);background:var(--bgI);
  font-size:11px;font-weight:500;white-space:nowrap;flex-shrink:0;cursor:pointer;
  color:var(--tx)}
.nav-tenant:hover{border-color:var(--tx3);text-decoration:none}
.nav-tenant .tn-av{width:17px;height:17px;border-radius:50%;display:grid;
  place-items:center;font-size:8px;font-weight:600;color:#fff;background:var(--sl)}
.nav-tenant .tn-host{font-family:var(--fm);font-size:9.5px;color:var(--tx3);font-weight:500}
.nav-tag{font-size:9px;font-weight:600;color:var(--tx2);letter-spacing:.7px;
  text-transform:uppercase;white-space:nowrap;flex-shrink:0}
.gap{flex:1;min-width:4px}

/* Global search sits in the strip, not on the page. Ctrl/Cmd-K focuses it. */
.nav-search{display:flex;align-items:center;gap:8px;padding:0 12px;height:36px;
  border:1px solid var(--bd);border-radius:var(--rl);background:var(--bgI);
  min-width:170px;max-width:420px;flex:1;color:var(--tx3);cursor:text;
  transition:border-color .14s,background .14s}
.nav-search:hover{border-color:var(--ac);background:var(--bg2)}
.nav-search input{flex:1;border:none;outline:none;background:none;font-family:var(--f);
  font-size:12.5px;font-weight:500;color:var(--tx);min-width:0;height:auto;padding:0}
.nav-search input:focus{box-shadow:none;border:none}
.kbd{font-family:var(--fm);font-size:8.5px;font-weight:600;color:var(--tx3);
  border:1px solid var(--bd);border-bottom-width:2px;border-radius:4px;
  padding:1px 4px;background:var(--bg2);white-space:nowrap}

/* Icon actions: bell, approvals, help. Counts ride on the corner. */
.nav-ico{position:relative;width:34px;height:34px;display:inline-flex;
  align-items:center;justify-content:center;border-radius:var(--rl);
  border:1px solid transparent;background:none;color:var(--tx2);cursor:pointer;
  flex-shrink:0;transition:background .12s,color .12s}
.nav-ico:hover{background:var(--bg3);color:var(--tx);text-decoration:none}
.nav-ico .dot{position:absolute;top:4px;right:4px;min-width:14px;height:14px;
  padding:0 3px;border-radius:var(--rp);background:var(--rd);color:#fff;
  font-size:8px;font-weight:600;display:grid;place-items:center;
  border:1.5px solid var(--bg2);line-height:1}
.nav-ico .dot.am{background:var(--am)}
.nav-ico.on{background:var(--bg3);color:var(--tx)}


/* A trial counting down, in the strip.
   -------------------------------------------------------------------------
   Amber for most of the last week and red for the last two days, because the
   difference between "soon" and "now" is the only thing this control has to
   communicate. It is a link, not a banner: it goes to the one screen where
   the renewal actually happens. */
.trial-chip{display:inline-flex;align-items:center;height:28px;padding:0 11px;
  border-radius:var(--rp);background:var(--amBg);color:var(--am);
  font-size:11px;font-weight:600;white-space:nowrap;flex-shrink:0;
  border:1px solid color-mix(in srgb,var(--am) 26%,transparent)}
.trial-chip:hover{text-decoration:none;background:var(--am);color:#fff}
.trial-chip.hot{background:var(--rdBg);color:var(--rd);
  border-color:color-mix(in srgb,var(--rd) 30%,transparent)}
.trial-chip.hot:hover{background:var(--rd);color:#fff}
@media(max-width:900px){.trial-chip{display:none}}

/* == 3. Product switcher =================================================== */
.sw{position:relative;flex-shrink:0}
.sw-btn{display:inline-flex;align-items:center;gap:8px;height:36px;padding:0 13px;
  border:1px solid var(--bd);border-radius:var(--rl);background:var(--bgI);
  color:var(--tx);font-family:var(--f);font-size:12.5px;font-weight:600;cursor:pointer;
  white-space:nowrap;transition:background .12s,border-color .12s}
.sw-btn:hover{background:var(--bg3);border-color:var(--ac)}
.sw-btn .car{width:5px;height:5px;border-right:1.6px solid var(--tx3);
  border-bottom:1.6px solid var(--tx3);transform:translateY(-2px) rotate(45deg)}
.sw.open .sw-btn{border-color:var(--ac);box-shadow:var(--ring)}
/* Wide enough that every product name sits on one line. At 376px the two
   long names wrapped and every card in the column below them sat at a
   different height; the cure is width, not a smaller font. Clamped to the
   viewport on a phone. */
.sw-pop{position:absolute;top:43px;left:0;z-index:300;width:560px;
  max-width:calc(100vw - 26px);
  background:var(--bg2);border:1px solid var(--bd);border-radius:var(--rx);
  box-shadow:var(--shL);padding:9px;display:none;animation:pop .14s ease-out}
.sw.open .sw-pop{display:block}
.sw-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px}
.sw-i{display:flex;align-items:center;gap:11px;padding:10px 11px;border-radius:10px;
  cursor:pointer;color:var(--tx);border:1px solid transparent;min-width:0}
.sw-i:hover{background:var(--bg3);text-decoration:none}
.sw-i.on{background:var(--acBg);border-color:var(--ac)}
.sw-i.off{opacity:.4;cursor:not-allowed}
.sw-i .ic{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  color:#fff;flex-shrink:0}
.sw-i > span:not(.ic){min-width:0}
.sw-i .nm{display:block;font-size:12.5px;font-weight:600;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(max-width:620px){.sw-grid{grid-template-columns:1fr}}
/* Was `.sb`, which is also the class on every table's search box — a
   bordered 28px flex row with a 190px minimum. The subtitle inherited all
   of it and rendered as a grey input inside every card in the switcher,
   which is also what forced the popover wider than its content. Two
   components must not share a class name. */
.sw-i .sw-sub{display:block;font-size:9.5px;color:var(--tx3);font-weight:500;
  margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sw-foot{border-top:1px solid var(--bdL);margin-top:6px;padding:7px 9px 3px;
  font-size:9.5px;color:var(--tx3);font-weight:600;display:flex;
  justify-content:space-between;align-items:center}
@keyframes pop{from{opacity:0;transform:translateY(-6px) scale(.985)}}

/* == 4. Profile — the ring =================================================
   This was a seven-stop rainbow conic gradient with a blur behind it that lit
   up on hover and rotated while the session refreshed. It was the one piece of
   pure decoration in the product and it sat in the top right corner of every
   screen, which is the most-looked-at thirty pixels a business application
   has. Six colours that mean nothing, next to a status pill whose colours mean
   everything, teaches people that colour here is ornament.

   It is now a ring in the company's own accent, one colour, still. The company
   colour is already the one thing on the page that identifies whose portal
   this is, so the avatar carries it rather than competing with it. It still
   turns while the session is being refreshed — that is a state, not a
   flourish — and it is still a 2 px inset so the face inside stays a circle. */
.pf{position:relative;flex-shrink:0}
.av-ring{width:30px;height:30px;border-radius:50%;padding:2px;cursor:pointer;
  background:var(--acBg);box-shadow:inset 0 0 0 1.5px var(--ac);
  display:grid;place-items:center;transition:box-shadow .18s;position:relative}
.av-ring:hover{box-shadow:inset 0 0 0 1.5px var(--ac),0 0 0 3px var(--acBg)}
.av-ring.spin{background:conic-gradient(from 0deg,var(--ac) 0deg,
  var(--acBg) 120deg,var(--ac) 360deg);
  animation:ringspin 1.1s linear infinite;box-shadow:none}
@keyframes ringspin{to{transform:rotate(360deg)}}
.av-ring > .av-in{width:100%;height:100%;border-radius:50%;background:var(--bg2);
  padding:1.5px;display:grid;place-items:center}
.av-ring .av-face{width:100%;height:100%;border-radius:50%;object-fit:cover;
  display:grid;place-items:center;font-size:10.5px;font-weight:600;color:#fff;
  background:var(--sl);letter-spacing:-.02em}
.av-ring.sm{width:24px;height:24px}
.av-ring.sm .av-face{font-size:8.5px}
.av-ring.lg{width:48px;height:48px}
.av-ring.lg .av-face{font-size:16px}
.av-ring.xl{width:74px;height:74px;padding:3px}
.av-ring.xl .av-face{font-size:24px}
/* Somebody who is not the signed-in user. No accent — the ring is what says
   "this is you", so a colleague's avatar must not wear it. */
.av-ring.mute{background:var(--bg3);box-shadow:inset 0 0 0 1px var(--bd)}
.av-ring.mute:hover{box-shadow:inset 0 0 0 1px var(--bd)}
.pf-pop{position:absolute;top:38px;right:0;z-index:300;width:270px;
  max-width:calc(100vw - 20px);
  background:var(--bg2);border:1px solid var(--bd);border-radius:var(--rx);
  box-shadow:var(--shL);display:none;overflow:hidden;animation:pop .14s ease-out}
.pf.open .pf-pop{display:block}
.pf-head{padding:12px;display:flex;gap:10px;align-items:center;
  border-bottom:1px solid var(--bdL);background:var(--bgI)}
/* Every child of this row is pinned. The head is 270 px wide and holds a
   48 px avatar, so the text has about 170 px — and a full name is a string
   with spaces in it, which wraps to three lines and pushes the head open,
   while an email address is one unbroken token, which pushes it sideways.
   Both were happening. The block is a flex child with min-width:0, the name
   is one line with an ellipsis, and the address wraps by character. */
.pf-hb{flex:1;min-width:0}
.pf-nm{font-size:12.5px;font-weight:600;line-height:1.3;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.pf-ml{font-size:9.5px;color:var(--tx3);font-weight:600;margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pf-rl{font-size:9px;color:var(--tx3);font-weight:600;margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  text-transform:uppercase;letter-spacing:.5px}
.pf-list{padding:5px}
.pf-i{display:flex;align-items:center;gap:9px;padding:7px 9px;border-radius:7px;
  font-size:11.5px;font-weight:500;color:var(--tx);cursor:pointer;min-width:0}
.pf-i > span.lb{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.pf-i:hover{background:var(--bg3);text-decoration:none}
.pf-i.dg{color:var(--rd)}
.pf-i .rt{margin-left:auto;flex:none;font-size:9px;color:var(--tx3);
  font-weight:600;font-variant-numeric:tabular-nums}
.pf-sep{height:1px;background:var(--bdL);margin:5px 0}

/* Avatar stack — teams, panels, watchers. */
.av-stack{display:flex;align-items:center}
.av-stack > *{margin-left:-7px;border:2px solid var(--bg2);border-radius:50%}
.av-stack > *:first-child{margin-left:0}
.av{width:24px;height:24px;border-radius:50%;display:grid;place-items:center;
  font-size:9px;font-weight:600;color:#fff;background:var(--sl);flex-shrink:0;
  letter-spacing:-.02em}
/* The same disc, holding a photograph instead of initials. object-fit is what
   stops a portrait being squashed into a circle. */
img.av{object-fit:cover;background:var(--bg3)}
.av.sm{width:20px;height:20px;font-size:8px}
.av.lg{width:34px;height:34px;font-size:12px}
.av-more{background:var(--bg3);color:var(--tx2)}

/* == 5. Buttons ============================================================ */
.btn{display:inline-flex;align-items:center;gap:6px;padding:0 13px;height:34px;
  border-radius:var(--rl);font-family:var(--f);font-size:12px;font-weight:600;
  border:1px solid var(--bd);background:var(--bg2);color:var(--tx2);
  cursor:pointer;white-space:nowrap;flex-shrink:0;text-decoration:none;
  transition:background .12s,border-color .12s,color .12s,box-shadow .12s}
.btn:hover{background:var(--bgH);text-decoration:none;color:var(--tx);
  border-color:var(--bgH)}
.btn-p{background:var(--ac);color:#fff;border-color:var(--ac)}
.btn-p:hover{background:var(--acD);border-color:var(--acD);color:#fff;
  box-shadow:0 2px 8px color-mix(in srgb,var(--ac) 26%,transparent)}
.btn-dark{background:var(--tx);color:var(--bg2);border-color:var(--tx)}
.btn-dark:hover{opacity:.86;color:var(--bg2)}
.btn-gn{background:var(--gn);color:#fff;border-color:var(--gn)}
.btn-gn:hover{color:#fff;opacity:.88}
.btn-rd{background:var(--rd);color:#fff;border-color:var(--rd)}
.btn-rd:hover{color:#fff;opacity:.88}
.btn-gh{border-color:transparent;background:none}
.btn-gh:hover{background:var(--bg3)}
.btn-sm{height:27px;padding:0 10px;font-size:11px;gap:5px;border-radius:var(--r)}
.btn-lg{height:40px;padding:0 18px;font-size:13.5px;border-radius:12px}
.btn-w{width:100%;justify-content:center}
.btn:disabled,.btn.dis{opacity:.42;cursor:not-allowed;pointer-events:none}
.btn.busy{position:relative;color:transparent!important}
.btn.busy svg.i{visibility:hidden}
.btn.busy::after{content:'';position:absolute;inset:0;margin:auto;width:12px;
  height:12px;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;
  border-radius:50%;animation:spin .6s linear infinite}
.btn:not(.btn-p):not(.btn-dark):not(.btn-gn):not(.btn-rd).busy::after{
  border-color:var(--bd);border-top-color:var(--ac)}
.ico-btn{width:32px;height:32px;display:inline-flex;align-items:center;
  justify-content:center;border:1px solid var(--bd);border-radius:var(--rl);
  background:var(--bg2);color:var(--tx2);cursor:pointer;flex-shrink:0}
.ico-btn:hover{border-color:var(--tx3);color:var(--tx)}
.ico-btn.danger:hover{border-color:var(--rd);color:var(--rd)}
.ico-btn.bare{border-color:transparent;background:none}
.ico-btn.bare:hover{background:var(--bg3)}
.btn-grp{display:inline-flex}
.btn-grp .btn{border-radius:0;margin-left:-1px}
.btn-grp .btn:first-child{border-radius:var(--r) 0 0 var(--r);margin-left:0}
.btn-grp .btn:last-child{border-radius:0 var(--r) var(--r) 0}

/* == 6. Page frame ========================================================= */
.main{max-width:1860px;margin:0 auto;padding:18px 18px 34px}
.main.narrow{max-width:1180px}
/* A form at 840 was two columns of 400, which is narrow for a label above
   an input and cramped for three. 1040 gives three honest columns. */
.main.form{max-width:1040px}
.main.wide{max-width:100%}
/* Optional left rail for portals with many sections. Collapses to icons. */
.shell{display:flex;align-items:flex-start;gap:0;max-width:1860px;margin:0 auto}
/* The rail is a column, so it is drawn as one: a hairline down its right
   edge, a little more width, and its own quiet ground. Without the line it
   floated in the page and the eye had to find the boundary from the ragged
   right-hand ends of the labels. */
/* The rail is pinned and scrolls on its own.

   `position:sticky` with `top:var(--nav-h)` and a height of exactly the
   viewport below the nav is what stops it travelling up the page with the
   content: on a long screen the rail used to disappear off the top, so
   getting from the bottom of a payroll run to another section meant scrolling
   all the way back up first.

   Its own overflow is `auto` and its scrollbar is hidden. A 6 px track down
   the left of every screen is a second vertical line beside the border that
   is already there, and on the twenty screens whose rail fits without
   scrolling it was a groove drawn for nothing. Scrolling still works — wheel,
   trackpad, keyboard and touch are all untouched; only the gutter is gone,
   and `overscroll-behavior:contain` stops a flick inside the rail carrying on
   into the page behind it. */
.side{width:232px;flex-shrink:0;padding:14px 11px 30px;position:sticky;
  top:var(--nav-h);height:calc(100vh - var(--nav-h));overflow-y:auto;
  overscroll-behavior:contain;
  background:var(--bg2);border-right:1px solid var(--bd);scrollbar-width:none;
  -ms-overflow-style:none}
.side::-webkit-scrollbar{width:0;height:0;display:none}
.side.mini{width:58px;padding:14px 8px 30px}
.side-t{font-size:9.5px;font-weight:600;color:var(--tx3);text-transform:uppercase;
  letter-spacing:1.05px;padding:17px 11px 6px;line-height:1}
.side-t:first-child{padding-top:4px}
.side.mini .side-t,.side.mini .sd-lb,.side.mini .sd-ct{display:none}
.side.mini .sd{justify-content:center;padding:8px 0}
/* 500 for a label, 600 for the one you are on. It was the other way round —
   every row you were NOT on rendered heavier than the row you were, so the
   rail read as a list of ten equally-shouted destinations with one quiet one.
   The house rule is 600 for titles and values, 500 for labels. */
.sd{display:flex;align-items:center;gap:11px;padding:8.5px 11px;border-radius:10px;
  font-size:13px;font-weight:500;color:var(--tx2);cursor:pointer;
  margin-bottom:2px;position:relative;letter-spacing:-.008em;
  transition:background .12s,color .12s}
.sd .ic{display:flex;align-items:center;color:var(--tx3);flex-shrink:0}
.sd:hover{background:var(--bg3);color:var(--tx);text-decoration:none}
.sd:hover .ic{color:var(--tx2)}
.sd.on{background:var(--acBg);color:var(--acD);font-weight:600}
.sd.on .ic{color:var(--ac)}
.sd-lb{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sd-ct{font-size:10px;font-weight:600;color:var(--tx2);background:var(--bg3);
  border-radius:var(--rp);padding:1.5px 7px;flex-shrink:0;
  font-variant-numeric:tabular-nums}
.sd:hover .sd-ct{background:var(--bg2)}
.sd.on .sd-ct{background:var(--bg2);color:var(--ac)}
.sd-ct.hot{background:var(--rdBg);color:var(--rd)}
/* The fold at the foot of the rail. Folded, a row is its icon and the label
   floats out on hover — the same fact, shown on demand instead of always. */
.side-min{display:flex;align-items:center;gap:11px;width:100%;margin-top:12px;
  padding:8.5px 11px;border:0;background:none;border-radius:10px;
  color:var(--tx3);font-family:var(--f);font-size:12.5px;font-weight:500;
  cursor:pointer;letter-spacing:-.008em}
.side-min:hover{background:var(--bg3);color:var(--tx)}
.side-min .ic{display:flex;align-items:center;flex-shrink:0}
.side.mini .side-min{justify-content:center;padding:8.5px 0}
.side.mini .side-min .ic svg.i{transform:rotate(180deg)}
.side.mini .sd{position:relative}
.side.mini .sd:hover .sd-lb{display:block;position:absolute;
  left:calc(100% + 9px);top:50%;transform:translateY(-50%);
  background:var(--tx);color:var(--bg2);font-size:11px;font-weight:500;
  padding:4px 10px;border-radius:7px;white-space:nowrap;z-index:60;
  overflow:visible;pointer-events:none}
@media (max-width:1023px){.side-min{display:none}
  .side.mini{width:100%;padding:14px 11px 30px}
  .side.mini .side-t,.side.mini .sd-lb,.side.mini .sd-ct{display:revert}}
.side + .main{flex:1;min-width:0;padding-left:20px}
/* The narrow-screen rail lives in section 26 with the rest of the responsive
   rules, so there is one place that decides what happens below 1023px rather
   than two that fight over it. */

/* Page header: breadcrumb, title, status, meta, actions. */
.ph{display:flex;align-items:flex-start;gap:14px;margin-bottom:16px;flex-wrap:wrap}
.ph-l{flex:1;min-width:220px}
.crumb{display:flex;align-items:center;gap:5px;font-size:9.5px;font-weight:600;
  color:var(--tx3);margin-bottom:4px;flex-wrap:wrap}
.crumb a{color:var(--tx3)}
.crumb a:hover{color:var(--tx2);text-decoration:none}
.crumb .cs{opacity:.5}
.ph h1{font-size:22px;font-weight:700;letter-spacing:-.032em;display:flex;
  align-items:center;gap:9px;flex-wrap:wrap}
.ph-meta{font-size:10.5px;color:var(--tx3);font-weight:500;margin-top:5px;
  display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.ph-meta .mono{font-family:var(--fm)}
.ph-act{display:flex;align-items:center;gap:6px;flex-wrap:wrap}

/* == 7. Portal cards — the dashboard's front door ==========================
   A card is a door, not a report. No coloured rail down the edge and no
   blinking dot: the accent lives in the icon tile alone, and anything waiting
   is said in words with a count. Colour is used once per card, quietly. */
.pgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:14px}
@media(max-width:1400px){.pgrid{grid-template-columns:repeat(3,1fr)}}
@media(max-width:1040px){.pgrid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.pgrid{grid-template-columns:1fr}}
.pc{position:relative;background:var(--bg2);border:1px solid var(--bd);
  border-radius:14px;padding:16px 17px 14px;box-shadow:var(--sh);
  cursor:pointer;overflow:hidden;display:flex;flex-direction:column;
  min-height:158px;text-align:left;font-family:var(--f);color:var(--tx);
  transition:border-color .18s,box-shadow .18s,transform .18s}
.pc:hover{border-color:var(--pa,var(--ac));box-shadow:var(--shM);
  transform:translateY(-1px);text-decoration:none}
.pc:active{transform:none}
.pc-top{display:flex;align-items:flex-start;gap:12px;margin-bottom:14px}
/* The one place the portal's colour appears. A soft tint, a 1 px keyline of
   the same hue, and the icon stroked in it. */
.pc-ic{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;
  color:var(--pa,var(--ac));
  background:color-mix(in srgb,var(--pa,var(--ac)) 9%,transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--pa,var(--ac)) 18%,transparent);
  flex-shrink:0}
.pc-nm{font-size:13.5px;font-weight:600;letter-spacing:-.02em;line-height:1.25}
.pc-sb{font-size:10.5px;color:var(--tx3);font-weight:400;margin-top:3px;line-height:1.4}
.pc-go{margin-left:auto;color:var(--tx3);opacity:0;flex-shrink:0;
  transition:opacity .18s,transform .18s;transform:translateX(-4px)}
.pc:hover .pc-go{opacity:.8;transform:none}
.pc-nums{display:flex;gap:20px;margin-top:auto;padding-top:4px}
.pc-n{min-width:0}
.pc-n-v{font-size:21px;font-weight:600;letter-spacing:-.035em;line-height:1;
  font-variant-numeric:tabular-nums}
.pc-n-l{font-size:9px;font-weight:500;color:var(--tx3);text-transform:uppercase;
  letter-spacing:.6px;margin-top:5px;white-space:nowrap}
.pc-n.hot .pc-n-v{color:var(--rd)}
.pc-n.warn .pc-n-v{color:var(--am)}
.pc-n.ok .pc-n-v{color:var(--gn)}
/* What is waiting. A count and a noun, on a quiet keyline. Never animated --
   a pulsing dot on eight cards at once is a fairground, not a dashboard. */
.pc-need{margin:14px -17px -14px;padding:9px 17px;border-top:1px solid var(--bdL);
  font-size:10.5px;font-weight:500;color:var(--tx2);display:flex;
  align-items:center;gap:7px}
.pc-need .ct{font-weight:600;color:var(--tx);font-variant-numeric:tabular-nums}
.pc-need.hot{color:var(--rd)}
.pc-need.hot .ct{color:var(--rd)}
.pc-need.warn{color:var(--am)}
.pc-need.warn .ct{color:var(--am)}
.pc-need.calm{color:var(--tx3)}
/* Entitled to the company, but not to this person. */
.pc.lock{cursor:not-allowed;opacity:.6;background:var(--bgI)}
.pc.lock:hover{transform:none;box-shadow:var(--sh);border-color:var(--bd)}
.pc.lock .pc-ic{color:var(--tx3);background:var(--bg3);box-shadow:none}
.pc.lock .pc-nums{visibility:hidden}
.pc-lockchip{position:absolute;top:16px;right:16px;display:inline-flex;
  align-items:center;gap:5px;font-size:9px;font-weight:500;
  letter-spacing:.3px;color:var(--tx3)}
/* Portal accent binding */
.pc[data-p="dash"]{--pa:var(--p-dash)} .pc[data-p="ems"]{--pa:var(--p-ems)}
.pc[data-p="hrms"]{--pa:var(--p-hrms)} .pc[data-p="acct"]{--pa:var(--p-acct)}
.pc[data-p="docs"]{--pa:var(--p-docs)} .pc[data-p="amc"]{--pa:var(--p-amc)}
.pc[data-p="legal"]{--pa:var(--p-legal)} .pc[data-p="admin"]{--pa:var(--p-admin)}
.sw-i[data-p="dash"] .ic{background:var(--p-dash)}
.sw-i[data-p="ems"] .ic{background:var(--p-ems)}
.sw-i[data-p="hrms"] .ic{background:var(--p-hrms)}
.sw-i[data-p="acct"] .ic{background:var(--p-acct)}
.sw-i[data-p="docs"] .ic{background:var(--p-docs)}
.sw-i[data-p="amc"] .ic{background:var(--p-amc)}
.sw-i[data-p="legal"] .ic{background:var(--p-legal)}
.sw-i[data-p="admin"] .ic{background:var(--p-admin)}

/* == 8. KPI tiles ========================================================== */
.kg{display:grid;grid-template-columns:repeat(6,1fr);gap:11px;margin-bottom:13px}
.kg.k6{grid-template-columns:repeat(6,1fr)}
.kg.k5{grid-template-columns:repeat(5,1fr)}
.kg.k4{grid-template-columns:repeat(4,1fr)}
.kg.k3{grid-template-columns:repeat(3,1fr)}
/* Four tiles go to two columns, not three. Three columns of four leaves the
   last one alone in a row beside a hole, and which tile is orphaned changes
   with the screen — the same raggedness §4 rules out for card stacks. Six and
   five still take three, because 3+3 and 3+2 both end level enough. */
@media(max-width:1160px){.kg,.kg.k6,.kg.k5{grid-template-columns:repeat(3,1fr)}
  .kg.k4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.kg,.kg.k6,.kg.k5,.kg.k4,.kg.k3{grid-template-columns:repeat(2,1fr)}}
.ki{background:var(--bg2);border:1px solid var(--bd);border-radius:var(--rx);
  padding:16px 17px;box-shadow:var(--sh);position:relative;text-align:left;
  font-family:var(--f);color:var(--tx);display:block;
  transition:transform .15s,border-color .15s,box-shadow .15s}
.ki.drill{cursor:pointer}
.ki.drill:hover{border-color:var(--ac);transform:translateY(-2px);box-shadow:var(--shM)}
a.ki:hover,button.ki{text-decoration:none}
button.ki{width:100%;border:1px solid var(--bd);cursor:pointer}

/* A tile carrying a chart is a two-column row: the reading on the left, the
   shape on the right. The chart is `flex:none` and the text `min-width:0`,
   because a long label next to a fixed-width SVG is exactly the shape that
   pushes a card sideways. */
.ki-g{display:flex;align-items:flex-end;gap:12px}
.ki-g .ki-b{flex:1;min-width:0}
.ki-g .ki-c{flex:none;line-height:0}
.ki-c svg.spk{display:block;overflow:visible}
@media(max-width:1060px){
  /* Below this the tile is narrow enough that the chart crowds the figure.
     The figure is the point; the chart goes. */
  .ki-g .ki-c{display:none}
}
.ki-lb{font-size:9.5px;font-weight:600;color:var(--tx3);text-transform:uppercase;
  letter-spacing:.7px;margin-bottom:9px;display:flex;align-items:center;gap:5px;
  min-width:0}
.ki-lb svg.i{width:12px;height:12px;opacity:.8}
/* The figure carries the tile. It is the one piece of type in the product
   that is allowed to be large, because it is the only one people read from
   across a desk rather than up close. */
.ki-v{font-size:31px;font-weight:600;letter-spacing:-.045em;line-height:1;
  font-variant-numeric:tabular-nums;display:flex;align-items:baseline;gap:6px;
  min-width:0;white-space:nowrap}
/* A long value steps down rather than wrapping. `overflow-wrap:anywhere` was
   right for a label and wrong for a figure: it splits ₹4,79,85,400 across two
   lines mid-number, which is not a number any more. Two steps, because one
   was not enough for a crore with a currency mark in front of it. */
.ki-v.long{font-size:25px;letter-spacing:-.035em}
.ki-v.xlong{font-size:20px;letter-spacing:-.02em}
.ki-v .un{font-size:12px;font-weight:500;color:var(--tx3);letter-spacing:0}
.ki-v .trend{align-self:center}
.ki-sub{margin-top:6px}
.ki-sub{font-size:10px;color:var(--tx3);margin-top:7px;font-weight:500;
  display:flex;align-items:center;gap:5px}
/* Tone reaches the tile, not only the figure.
   -------------------------------------------------------------------------
   A coloured number on a white tile is a number somebody has to already be
   looking at to notice. These are the same tints the status pills use, which
   is what keeps a green here meaning what a green means everywhere else — and
   the pairing is already proved: --gn on --gnBg clears 4.5:1.

   The strength is deliberately not uniform. A tile that is *fine* gets the
   faintest wash there is, enough to give a row of six some warmth and depth;
   a tile that wants somebody gets the full tint. A dashboard where every tile
   is coloured equally is a dashboard where the colour has stopped saying
   anything, which is the failure mode this is avoiding rather than the effect
   it is going for. */
.ki.ok .ki-v{color:var(--gn)} .ki.warn .ki-v{color:var(--am)}
.ki.crit .ki-v{color:var(--rd)} .ki.acc .ki-v{color:var(--ac)}
.ki.info .ki-v{color:var(--bl)} .ki.vi .ki-v{color:var(--vi)}
.ki.te .ki-v{color:var(--te)} .ki.or .ki-v{color:var(--or)}
/* The tile stays white, and its colour arrives as a chip.

   A tinted card and a tinted chip are not the same claim. A whole card washed
   in amber says "this one is a problem"; a 30 px amber square holding a wallet
   says "this one is about money". A home screen has four tiles that are all
   perfectly fine and still want telling apart at a glance, so identity is
   carried by the chip and the card is left alone — which also keeps a genuine
   warning legible, because it is then the only tinted card in the row.

   So: `.ki-ic` is always coloured, and the two backgrounds below are still
   reserved for a tile that actually wants somebody. */
.ki.warn{background:var(--amBg);border-color:color-mix(in srgb,var(--am) 26%,var(--bd))}
.ki.crit{background:var(--rdBg);border-color:color-mix(in srgb,var(--rd) 26%,var(--bd))}

/* The chip. Same 30 px rounded square the task rows and the date chips use,
   so a screen of cards has one shape for "an icon that means something". */
.ki-ic{width:30px;height:30px;border-radius:9px;flex:none;display:grid;
  place-items:center;background:var(--bg3);color:var(--tx2);margin-bottom:10px}
.ki-ic svg.i{width:15px;height:15px;opacity:1}
.ki.ok .ki-ic{background:var(--gnBg);color:var(--gn)}
.ki.acc .ki-ic{background:var(--acBg);color:var(--ac)}
.ki.info .ki-ic{background:var(--blBg);color:var(--bl)}
.ki.vi .ki-ic{background:var(--viBg);color:var(--vi)}
.ki.te .ki-ic{background:var(--teBg);color:var(--te)}
.ki.or .ki-ic{background:var(--orBg);color:var(--or)}
.ki.warn .ki-ic{background:var(--bg2);color:var(--am)}
.ki.crit .ki-ic{background:var(--bg2);color:var(--rd)}
/* With a chip above it the label no longer carries an icon of its own. */
.ki-ic + .ki-lb svg.i{display:none}
/* No rail down the edge. A 3 px coloured bar on a tinted tile is the second
   time the same fact is said, and six of them in a row is a ribbon — which is
   the one piece of decoration §4 rules out by name. The tint carries the
   tone; the figure carries the reading. */
/* An arrow, and nothing else. It used to carry a number as well, which is
   the same number the sub-line under it already says in words — "+12" above
   "+12 from last week". The arrow answers "which way" at a glance and the
   line answers "by how much, since when"; saying it twice makes the tile
   look like it is shouting. */
.trend{display:inline-flex;align-items:center;font-weight:600;font-size:9px;
  flex:none}
.trend svg.i{width:11px;height:11px;fill:currentColor;stroke:none}
.trend.up{color:var(--g-gn)} .trend.dn{color:var(--g-rd)}
.trend.flat{color:var(--tx3)}

/* == Small charts ==========================================================
   Four shapes with no library behind them. See EF.sparkBars / sparkArea /
   arcGauge / ring — the geometry is in the kit, this is only how they sit. */
.spk{flex:none}
.rng{position:relative;display:inline-grid;place-items:center;flex:none}
.rng svg{position:absolute;inset:0}
.rng-v{position:relative;font-size:12px;font-weight:600;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums}

/* A legend that is a row of words, for a chart small enough not to need a
   box round it. */
.lg2{display:flex;flex-wrap:wrap;gap:5px 13px;margin-top:9px}
.lg2 span{display:inline-flex;align-items:center;gap:5px;font-size:10px;
  font-weight:600;color:var(--tx3)}
.lg2 i{width:7px;height:7px;border-radius:2px;flex:none}

/* == 9. Cards and grids ==================================================== */
.cd{background:var(--bg2);border:1px solid var(--bd);border-radius:var(--rx);
  overflow:hidden;box-shadow:var(--sh);margin-bottom:12px}
.cd-h{padding:14px 17px;border-bottom:1px solid var(--bdL);display:flex;
  align-items:center;justify-content:space-between;gap:9px;flex-wrap:wrap}
.cd-t{font-size:13.5px;font-weight:600;letter-spacing:-.022em;display:flex;
  align-items:center;gap:8px}
.cd-s{font-size:9.5px;color:var(--tx3);font-weight:500}
.cd-bd{padding:16px 17px}
.cd-bd.flush{padding:0}
/* A card whose content sits directly inside it — no .cd-h, no .cd-bd —
   still gets the card's padding. The header/body pair is the contract, but
   a dozen screens predate it, and content flush against overflow:hidden is
   content with its first letter cut off: "IDENTITY" reading "DENTITY" on
   the company page is how this was found. */
.cd:not(:has(> .cd-h)):not(:has(> .cd-bd)){padding:16px 17px}
.cd-f{padding:10px 15px;border-top:1px solid var(--bdL);background:var(--bgI);
  font-size:10.5px;font-weight:500;color:var(--tx3);display:flex;
  justify-content:space-between;align-items:center;gap:8px}
.g2{display:grid;grid-template-columns:1fr 1fr;gap:13px;margin-bottom:13px}
/* An odd last child spans, rather than sitting alone in half a row with a
   hole beside it. `:nth-last-child(1):nth-child(odd)` is "the last one, and
   there is an odd number of them". */
.g2 > :last-child:nth-child(odd){grid-column:1 / -1}
.g3{display:grid;grid-template-columns:repeat(3,1fr);gap:13px;margin-bottom:13px}
.g21{display:grid;grid-template-columns:2fr 1fr;gap:13px;margin-bottom:13px}

/* == A card area that balances itself =====================================
   A dashboard laid out as two grid columns, each holding its own stack of
   cards, is ragged by construction: the two stacks are independent, so one
   ends 260 px above the other and the difference is a hole. Which stack is
   short changes per company — a firm with one department has a 100 px chart
   card, a firm with nine has a 300 px one — so no hand-tuned split is right
   for everybody.

   Flowing them balances instead of being balanced. The browser fills the
   columns to equal height whatever arrives, and `break-inside: avoid` keeps
   a card whole. Cards keep their own order, so the important one is still
   first — first in the left column rather than first on the page.

   Not grid masonry: that is still behind a flag in most browsers, and this
   has done the same job since 2012. */
/* A row of cards that ends level.
   -------------------------------------------------------------------------
   Three cards side by side, each as tall as the tallest — because a row whose
   bottoms are 80 px apart reads as three things that failed to line up rather
   than as one row. The body takes the slack, so every header stays at the top
   of its own card. */
.lvl{align-items:stretch}
.lvl > .cd{display:flex;flex-direction:column;margin-bottom:0}
.lvl > .cd > .cd-bd{flex:1}
/* A card that spans the row is on its own and has nothing to be level with,
   so it keeps its natural height rather than stretching to a row of one. */
.lvl > .cd:last-child:nth-child(odd){display:block}

.cols{columns:2;column-gap:13px;margin-bottom:13px}
.cols > *{break-inside:avoid;-webkit-column-break-inside:avoid;
  page-break-inside:avoid;margin:0 0 13px;display:block;width:100%}
/* `display:block` above beats the browser's own [hidden] rule, so a card a
   screen deliberately did not draw would come back as an empty box. */
.cols > [hidden]{display:none}
.cols3{columns:3}
@media(max-width:1060px){.cols,.cols3{columns:1}}
@media(min-width:1061px) and (max-width:1400px){.cols3{columns:2}}
.g12{display:grid;grid-template-columns:1fr 2fr;gap:9px;margin-bottom:9px}
@media(max-width:1000px){.g2,.g3,.g21,.g12{grid-template-columns:1fr}}
.chart-wrap{position:relative;height:236px}
.chart-wrap.sm{height:172px}
.chart-wrap.lg{height:310px}

/* == 10. Tabs, segments ==================================================== */
/* Wrap, never clip. The strip used to scroll with the scrollbar hidden, so
   a screen whose tabs outgrew it simply lost the last ones — seven tabs on
   the company page showed five and nothing said so. A second row is ugly
   for a moment; an unreachable tab is broken for ever. */
.tabs{display:flex;flex-wrap:wrap;gap:1px;background:var(--bg3);
  border-radius:10px;padding:3px;margin-bottom:11px;width:max-content;
  max-width:100%}
.tab{border:none;background:none;font-family:var(--f);font-size:12px;font-weight:500;
  color:var(--tx2);padding:7px 16px;border-radius:7px;cursor:pointer;
  white-space:nowrap;display:flex;align-items:center;gap:6px}
.tab:hover{color:var(--tx)}
.tab.on{background:var(--bg2);color:var(--tx);box-shadow:var(--sh)}
.tab .cnt{background:var(--tx3);color:var(--bg2);border-radius:var(--rp);padding:0 5px;
  font-size:8.5px;font-weight:600;min-width:15px;text-align:center;line-height:15px}
.tab.on .cnt{background:var(--ac);color:#fff}
.tab .cnt.rd{background:var(--rd);color:#fff}
/* Underline tabs for record detail pages. */
.utabs{display:flex;gap:2px;border-bottom:1px solid var(--bd);margin-bottom:12px;
  overflow-x:auto;scrollbar-width:none}
.utabs::-webkit-scrollbar{display:none}
.utab{border:none;background:none;font-family:var(--f);font-size:11.5px;font-weight:500;
  color:var(--tx3);padding:8px 12px;cursor:pointer;white-space:nowrap;
  border-bottom:2px solid transparent;margin-bottom:-1px;display:flex;
  align-items:center;gap:6px}
.utab:hover{color:var(--tx2)}
.utab.on{color:var(--tx);border-bottom-color:var(--ac)}

/* == 11. Toolbar, filters ================================================== */
.toolbar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding:8px 12px;
  border-bottom:1px solid var(--bd);background:var(--bg2)}
.sb{display:flex;align-items:center;gap:7px;padding:0 10px;height:28px;
  border:1px solid var(--bd);border-radius:var(--r);background:var(--bg);
  min-width:190px;flex:1;max-width:330px}
.sb svg{color:var(--tx3)}
.sb input{flex:1;border:none;outline:none;font-family:var(--f);font-size:11.5px;
  background:none;color:var(--tx);padding:0;min-width:0;height:auto}
.sb input:focus{box-shadow:none;border:none}
.sel{appearance:none;
  background:var(--bg3) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%239aa1ad'/%3E%3C/svg%3E") no-repeat right 7px center;
  border:1px solid var(--bd);border-radius:var(--r);padding:0 24px 0 10px;height:30px;
  font-family:var(--f);font-size:11.5px;font-weight:500;color:var(--tx);cursor:pointer;
  width:auto}
option{background:var(--bg2);color:var(--tx)}
.chip{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:500;
  padding:4px 11px;border-radius:var(--rp);background:var(--bg3);color:var(--tx2);
  border:1px solid var(--bd);cursor:pointer;white-space:nowrap}
/* The red is for a chip that removes a filter — the X reading. A chip that
   *selects* one is a different control and must not promise a delete. */
.chip:hover{border-color:var(--rd);color:var(--rd)}
.chip.st{cursor:default} .chip.st:hover{border-color:var(--bd);color:var(--tx2)}
.chip.on{background:var(--acBg);border-color:var(--ac);color:var(--ac)}
.chip.on:hover,.chip-row.pick .chip:hover{border-color:var(--ac);color:var(--ac)}
.chip .n{font-variant-numeric:tabular-nums;opacity:.7;font-weight:600}
.chip-row{display:flex;gap:5px;flex-wrap:wrap;padding:7px 12px;
  border-bottom:1px solid var(--bd);background:var(--bg2);align-items:center}
/* The same row of chips used as a page control rather than a table header:
   no bar, no border, no background. Two screens wanted it, which is the bar
   for putting a shape in the kit rather than in a page. */
.ph-act .chip-row{padding:0;border:0;background:none}
/* Quick-range segment — the control people reach for first. */
.qf{display:inline-flex;background:var(--bg3);border-radius:9px;padding:3px;gap:1px}
.qf button{border:none;background:none;font-family:var(--f);font-size:11px;
  font-weight:500;color:var(--tx2);padding:6px 13px;border-radius:6px;cursor:pointer;
  white-space:nowrap}
.qf button:hover{color:var(--tx)}
.qf button.on{background:var(--bg2);color:var(--tx);box-shadow:var(--sh)}
.qf button.on.crit{color:var(--rd)} .qf button.on.warn{color:var(--am)}
/* Bulk-action bar, appears when rows are selected. */
.bulk{display:flex;align-items:center;gap:8px;padding:7px 12px;background:var(--acBg);
  border-bottom:1px solid var(--ac);font-size:11px;font-weight:500;color:var(--ac);
  flex-wrap:wrap}

/* == 12. Data grid ========================================================= */
.rtw{overflow:auto;max-height:calc(100vh - 290px);min-height:260px;position:relative;
  background:var(--bg2)}
.rtw.short{max-height:340px;min-height:0}
.rtw.auto{max-height:none;min-height:0}
.grid-ov{position:absolute;inset:0;display:none;align-items:center;
  justify-content:center;gap:9px;
  background:color-mix(in srgb,var(--bg2) 74%,transparent);z-index:5;
  font-size:11px;font-weight:500;color:var(--tx2)}
.rtw.loading .grid-ov{display:flex}
table.dt{border-collapse:separate;border-spacing:0;font-size:11.5px;white-space:nowrap;
  width:max-content;min-width:100%}
table.dt th{position:sticky;top:0;z-index:3;background:var(--bg3);color:var(--tx2);
  font-weight:600;text-transform:uppercase;letter-spacing:.4px;font-size:8.5px;
  padding:0;text-align:left;border-bottom:1.5px solid var(--bd);
  border-right:1px solid var(--bd)}
.th-in{display:flex;align-items:center;gap:5px;padding:7px 10px;cursor:pointer;
  user-select:none;white-space:nowrap}
.th-in:hover{color:var(--tx)}
.th-in.plain{cursor:default}
.th-lb{flex:1;overflow:hidden;text-overflow:ellipsis}
.th-arrow{font-size:8px;opacity:.35}
.th-arrow.on{opacity:1;color:var(--tx)}
.th-f{width:11px;height:11px;flex-shrink:0;cursor:pointer;color:var(--tx3);
  fill:currentColor}
.th-f:hover,.th-f.on{color:var(--ac)}
table.dt td{padding:7px 10px;border-bottom:1px solid var(--bdL);
  border-right:1px solid var(--bdL);color:var(--tx);vertical-align:middle;
  max-width:440px;overflow:hidden;text-overflow:ellipsis}
table.dt td.num{text-align:right;font-family:var(--fm);font-weight:600}
table.dt td.mono{font-family:var(--fm)}
table.dt tbody tr{cursor:pointer}
table.dt tbody tr:hover td{background:var(--bg3)}
table.dt tbody tr.sel td{background:var(--acBg)}
table.dt tbody tr.mut td{color:var(--tx3)}
table.dt tfoot td{background:var(--bg3);font-weight:600;border-top:1.5px solid var(--bd);
  position:sticky;bottom:0;z-index:2}
.sticky-l{position:sticky;left:0;background:var(--bg2);z-index:2;
  border-right:1.5px solid var(--bd)}
table.dt th.sticky-l{z-index:4;background:var(--bg3)}
table.dt tbody tr:hover .sticky-l{background:var(--bg3)}
table.dt tbody tr.sel .sticky-l{background:var(--acBg)}
.sticky-r{position:sticky;right:0;background:var(--bg2);
  border-left:1.5px solid var(--bd);z-index:2}
table.dt th.sticky-r{z-index:4;background:var(--bg3)}
table.dt tbody tr:hover .sticky-r{background:var(--bg3)}
table.dt tbody tr.sel .sticky-r{background:var(--acBg)}
.row-act{display:flex;gap:4px;justify-content:flex-end}
.sub{font-size:9px;color:var(--tx3);font-weight:600}
.cbx{accent-color:var(--ac);width:13px;height:13px;cursor:pointer}
/* Two-line identity cell: avatar, name, secondary. Used in every directory. */
.idc{display:flex;align-items:center;gap:8px;min-width:0}
.idc-b{min-width:0}
.idc-n{font-weight:500;font-size:11px;overflow:hidden;text-overflow:ellipsis}
.idc-s{font-size:9px;color:var(--tx3);font-weight:600;overflow:hidden;
  text-overflow:ellipsis;margin-top:1px}
/* Number + proportional bar, so magnitude is visible while scanning. */
.dl{display:flex;align-items:center;gap:7px;justify-content:flex-end}
.dl-n{font-family:var(--fm);font-weight:500}
.dl-bar{width:36px;height:4px;border-radius:2px;background:var(--bg3);
  overflow:hidden;flex-shrink:0}
.dl-bar i{display:block;height:100%;border-radius:2px;background:var(--ac)}
/* Column filter popup + column chooser */
.fdd{position:fixed;z-index:400;background:var(--bg2);border:1px solid var(--bd);
  border-radius:9px;box-shadow:var(--shM);min-width:215px;max-width:300px;
  max-height:340px;display:none;flex-direction:column}
.fdd.show{display:flex}
.fdd-h{padding:7px 10px;border-bottom:1px solid var(--bd)}
.fdd-h input{width:100%;padding:0 8px;height:27px;border:1px solid var(--bd);
  border-radius:5px;font-size:10.5px;background:var(--bg);color:var(--tx);outline:none}
.fdd-b{flex:1;overflow-y:auto;padding:4px 0;min-height:60px}
.fdd-i{display:flex;align-items:center;gap:7px;padding:5px 12px;font-size:10.5px;
  cursor:pointer}
.fdd-i:hover{background:var(--bg3)}
.fdd-i input{accent-color:var(--ac);width:13px;height:13px}
.fdd-f{padding:6px 10px;border-top:1px solid var(--bd);display:flex;gap:6px;
  justify-content:flex-end}
.colpick{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:2px}
.colpick label{display:flex;align-items:center;gap:7px;padding:5px 8px;border-radius:5px;
  font-size:11px;cursor:pointer;font-weight:600}
.colpick label:hover{background:var(--bg3)}
.colpick input{accent-color:var(--ac);width:13px;height:13px}

/* == 13. Pagination ======================================================== */
.pgw{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:7px 12px;border-top:1px solid var(--bd);flex-wrap:wrap;background:var(--bg2)}
.pg-btn{min-width:24px;height:24px;padding:0 8px;border:1px solid var(--bd);
  border-radius:5px;background:var(--bg2);color:var(--tx2);font-size:10px;
  font-weight:500;cursor:pointer}
.pg-btn:hover:not(:disabled){border-color:var(--tx3);color:var(--tx)}
.pg-btn.on{background:var(--ac);color:#fff;border-color:var(--ac)}
.pg-btn:disabled{opacity:.4;cursor:not-allowed}
.pg-info{font-size:10px;color:var(--tx3);font-weight:600}

/* == 14. Status: tags, dots, pills ========================================= */
.tg{display:inline-flex;align-items:center;gap:5px;padding:2.5px 9px;
  border-radius:var(--rp);font-size:10px;font-weight:600;white-space:nowrap;
  letter-spacing:.1px}
.tg::before{content:'';width:5px;height:5px;border-radius:50%;background:currentColor;
  flex-shrink:0;opacity:.85}
.tg.nodot::before{display:none}
.tg-gn{background:var(--gnBg);color:var(--gn)} .tg-am{background:var(--amBg);color:var(--am)}
.tg-rd{background:var(--rdBg);color:var(--rd)} .tg-bl{background:var(--blBg);color:var(--bl)}
.tg-vi{background:var(--viBg);color:var(--vi)} .tg-ac{background:var(--acBg);color:var(--ac)}
.tg-te{background:var(--teBg);color:var(--te)} .tg-or{background:var(--orBg);color:var(--or)}
.tg-gy{background:var(--bg3);color:var(--tx2)}
.tg.lg{font-size:10.5px;padding:3px 10px}
.tg.sq{border-radius:5px}
/* Priority + severity marks */
.pri{display:inline-flex;align-items:center;gap:4px;font-size:9.5px;font-weight:600}
.pri i{width:3px;height:11px;border-radius:2px;background:currentColor;display:block}
.pri.p1{color:var(--rd)} .pri.p2{color:var(--am)} .pri.p3{color:var(--bl)}
.pri.p4{color:var(--tx3)}
/* Progress */
.prg{height:6px;border-radius:4px;background:var(--bg3);overflow:hidden;min-width:52px}
.prg i{display:block;height:100%;border-radius:3px;background:var(--ac);
  transition:width .35s ease-out}
.prg.gn i{background:var(--gn)} .prg.am i{background:var(--am)} .prg.rd i{background:var(--rd)}
.prg.lg{height:8px}

/* == 15. Modals and drawers ================================================ */
.mm{position:fixed;inset:0;z-index:300;background:rgba(6,8,12,.48);display:none;
  align-items:center;justify-content:center;backdrop-filter:blur(3px);padding:18px}
.mm.show{display:flex}
.md{background:var(--bg2);border:1px solid var(--bd);border-radius:var(--rx);
  width:100%;max-width:900px;max-height:calc(100vh - 52px);display:flex;
  flex-direction:column;box-shadow:var(--shL);animation:mdin .15s ease-out}
/* Widened across the board. Every dialog in this product is a form, and a
   form dialog at 820 put a two-column row at 380 each with a 9 px gutter,
   which is where a label like Reporting manager wraps and the row goes
   ragged. */
.md.lg{max-width:1180px} .md.sm{max-width:520px} .md.xl{max-width:1400px}
@keyframes mdin{from{opacity:0;transform:translateY(-10px) scale(.99)}}
.md-h{display:flex;align-items:flex-start;justify-content:space-between;
  padding:15px 22px;border-bottom:1px solid var(--bd);gap:10px}
.md-t{font-size:14px;font-weight:600;letter-spacing:-.02em;display:flex;
  align-items:center;gap:8px}
.md-s{font-size:9.5px;color:var(--tx3);font-weight:600;margin-top:3px}
.md-x{width:26px;height:26px;display:grid;place-items:center;border:none;
  background:var(--bg3);color:var(--tx3);cursor:pointer;border-radius:6px;flex-shrink:0}
.md-x:hover{color:var(--tx)}
.md-b{flex:1;overflow-y:auto;padding:18px 22px}
.md-b.flush{padding:0}
.md-f{padding:14px 22px;border-top:1px solid var(--bd);display:flex;
  justify-content:flex-end;gap:8px;flex-wrap:wrap;align-items:center}
.md-f .gap{flex:1}
/* Right drawer for quick view / quick edit. */
.dw{position:fixed;inset:0;z-index:300;display:none}
.dw.show{display:block}
.dw-bg{position:absolute;inset:0;background:rgba(6,8,12,.4)}
.dw-p{position:absolute;top:0;right:0;bottom:0;width:min(640px,100%);
  background:var(--bg2);border-left:1px solid var(--bd);display:flex;
  flex-direction:column;box-shadow:var(--shL);animation:dwin .18s ease-out}
.dw-p.wide{width:min(960px,100%)}
@keyframes dwin{from{transform:translateX(28px);opacity:.4}}
/* Label/value detail grid. Each fact is its own soft tile rather than a
   cell in a hairline lattice: the lattice doubled its borders against the
   frame, drew a rule under the last row, and left a ragged hole where the
   final row ran short — three faults for the price of drawing lines
   between things that were never a table. */
.dv{display:grid;grid-template-columns:repeat(auto-fill,minmax(238px,1fr));
  gap:9px}
.dv-i{padding:10px 13px;border:1px solid var(--bdL);border-radius:9px;
  background:var(--bgI);min-width:0}
/* A value nobody has filled in. Grey and lighter, so a half-complete record
   reads as gaps to fill rather than as a wall of identical rows. */
.dv-v.none{color:var(--tx3);font-weight:400}
/* The control that asks to change a value sits with it, not in its own
   column — a column of buttons beside a column of facts is a table, and this
   is not one. */
.dv-i .fw{display:flex;align-items:center;gap:8px;min-width:0}
.dv-i .fw .v{flex:1;min-width:0;overflow-wrap:anywhere}
.dv-i .fw .tg,.dv-i .fw .ico-btn{flex:none}
.dv-l{font-size:9.5px;font-weight:600;color:var(--tx3);text-transform:uppercase;
  letter-spacing:.5px;margin-bottom:6px}
.dv-v{font-size:13px;font-weight:600;line-height:1.5;white-space:pre-wrap;
  overflow-wrap:anywhere;word-break:normal;min-height:20px}
.dv-v.mono{font-family:var(--fm)}
.dv-i.wide{grid-column:1/-1}
.sec-t{font-size:8.5px;font-weight:600;color:var(--tx3);text-transform:uppercase;
  letter-spacing:.7px;margin:15px 0 7px;display:flex;align-items:center;gap:8px}
.sec-t::after{content:'';flex:1;height:1px;background:var(--bdL)}

/* Facts about one thing: label left, value right, aligned down the column.
   Lives here rather than in a page because a drawer, a profile and a confirm
   box all want the same shape, and three copies drift. */
.kv{display:grid;grid-template-columns:max-content 1fr;gap:9px 18px;
  font-size:12.5px;align-items:baseline;margin:0}
.kv dt{color:var(--tx3);white-space:nowrap;font-weight:500}
.kv dd{color:var(--tx);margin:0;min-width:0;overflow-wrap:anywhere;
  font-weight:500}
.kv dd.mono{font-family:var(--fm);font-size:11.5px}
/* `.wide` sets a FLOOR on the label column, not a fixed width.
   -------------------------------------------------------------------------
   It was `104px 1fr`, and `dt` is `white-space:nowrap` — so any label longer
   than 104px at 12 px overflowed its own cell and sat on top of its value.
   "On this band since" and "Last promoted" both do, which is why the profile
   read as two columns that had come apart.

   `minmax(104px, max-content)` keeps short lists lining up at a common width,
   which is the whole reason the modifier exists, and lets a long label push
   the column out rather than spill over it. */
.kv.wide{grid-template-columns:minmax(104px,max-content) 1fr}
/* A row that has come back empty says so once, quietly, rather than being
   left blank — a gap in a column of facts reads as a rendering fault. */
.kv dd.none{color:var(--tx3);font-weight:400}
.sec-t:first-child{margin-top:0}
/* Headline block on a detail modal — the one number that matters. */
.hero{display:flex;align-items:center;gap:15px;padding:13px 16px;border-radius:var(--rl);
  margin-bottom:13px;border:1px solid var(--bd);background:var(--bgI)}
.hero.crit{background:var(--rdBg);border-color:var(--rd)}
.hero.warn{background:var(--amBg);border-color:var(--am)}
.hero.info{background:var(--blBg);border-color:var(--bl)}
.hero.ok{background:var(--gnBg);border-color:var(--gn)}
.hero-n{font-size:31px;font-weight:600;line-height:1;letter-spacing:-.04em}
.hero-t{font-size:12.5px;font-weight:600}
.hero-s{font-size:10px;color:var(--tx2);margin-top:3px;font-weight:600}

/* == 16. Forms ============================================================= */
.fld{margin-bottom:14px}
.fld label,label.lbl{display:block;font-size:9.5px;font-weight:600;color:var(--tx3);
  text-transform:uppercase;letter-spacing:.7px;margin-bottom:6px}
.fld label .req,label.lbl .req{color:var(--rd);margin-left:2px}
.fld input,.fld select,.fld textarea,
input[type=text],input[type=email],input[type=date],input[type=time],input[type=number],
input[type=search],input[type=password],input[type=tel],input[type=url],select,textarea{
  width:100%;padding:0 12px;height:38px;border:1px solid var(--bd);border-radius:var(--rl);
  font-family:var(--f);font-size:13px;font-weight:500;background:var(--bgI);color:var(--tx);
  outline:none;transition:border-color .12s,background .12s,box-shadow .12s}
textarea{padding:10px 12px;height:auto;resize:vertical;min-height:88px;line-height:1.6}
.fld input:focus,.fld select:focus,.fld textarea:focus,
input:focus,select:focus,textarea:focus{border-color:var(--ac);box-shadow:var(--ring);
  background:var(--bg2)}
input:disabled,select:disabled,textarea:disabled{opacity:.55;cursor:not-allowed}
input[type=color]{width:100%;height:32px;padding:2px;cursor:pointer}
input[type=range]{width:100%;accent-color:var(--ac);padding:0;height:auto}
.fld-row2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.fld-row3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.fld-row4{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
@media(max-width:680px){.fld-row2,.fld-row3,.fld-row4{grid-template-columns:1fr}}
.hint{font-size:10px;color:var(--tx3);margin-top:5px;font-weight:500;text-transform:none;
  letter-spacing:0;line-height:1.5}
.err-txt{font-size:10px;color:var(--rd);margin-top:5px;display:none;font-weight:500}
.fld.has-err input,.fld.has-err select,.fld.has-err textarea,.fld.has-err .ss-toggle{
  border-color:var(--rd)}
.fld.has-err .err-txt{display:block}
/* Input with a fixed prefix or suffix: rupee, per cent, .effred.com */
.ig{display:flex;align-items:stretch}
.ig .pfx,.ig .sfx{display:flex;align-items:center;padding:0 9px;background:var(--bg3);
  border:1px solid var(--bd);font-size:11px;font-weight:500;color:var(--tx2);
  white-space:nowrap}
.ig .pfx{border-right:none;border-radius:var(--r) 0 0 var(--r)}
.ig .sfx{border-left:none;border-radius:0 var(--r) var(--r) 0;font-family:var(--fm);
  font-size:10.5px}
.ig input{border-radius:0}
.ig > input:first-child{border-radius:var(--r) 0 0 var(--r)}
.ig > input:last-child{border-radius:0 var(--r) var(--r) 0}
.check{display:flex;align-items:flex-start;gap:10px;cursor:pointer;padding:11px 13px;
  border:1px solid var(--bd);border-radius:var(--rl);background:var(--bgI);
  transition:border-color .12s,background .12s}
.check:hover{border-color:var(--ac);background:var(--bg2)}
.check input{margin-top:1px;accent-color:var(--ac);width:14px;height:14px;flex-shrink:0}
.check-title{font-weight:600;font-size:12px;color:var(--tx);display:block}
.check-sub{font-size:10px;color:var(--tx3);margin-top:3px;display:block;font-weight:500;
  line-height:1.5}
/* Toggle switch for settings rows */
.sw-t{width:36px;height:20px;border-radius:10px;background:var(--bg3);
  border:1px solid var(--bd);position:relative;cursor:pointer;flex-shrink:0;
  transition:background .18s,border-color .18s}
.sw-t::after{content:'';position:absolute;top:1px;left:1px;width:16px;height:16px;
  border-radius:50%;background:var(--bg2);box-shadow:var(--sh);transition:left .18s}
.sw-t.on{background:var(--ac);border-color:var(--ac)}
.sw-t.on::after{left:17px}
.set-row{display:flex;align-items:center;gap:13px;padding:11px 0;
  border-bottom:1px solid var(--bdL)}
.set-row:last-child{border-bottom:none}
.set-b{flex:1;min-width:0}
.set-n{font-size:12.5px;font-weight:600}
.set-d{font-size:10.5px;color:var(--tx3);margin-top:3px;font-weight:500;line-height:1.55}
/* Section tabs inside a form dialog */
.ftabs{display:flex;gap:1px;background:var(--bg3);border-radius:7px;padding:2px;
  margin-bottom:13px;width:max-content;max-width:100%;overflow-x:auto}
.ftab{border:none;background:none;font-family:var(--f);font-size:11px;font-weight:500;
  color:var(--tx2);padding:6px 14px;border-radius:5px;cursor:pointer;white-space:nowrap}
.ftab.on{background:var(--bg2);color:var(--tx);box-shadow:var(--sh)}
.ftab.err{color:var(--rd)}
.ftab.err::after{content:'\00B7';margin-left:4px;font-size:15px;line-height:0}
.fpane{display:none}
.fpane.on{display:block;animation:fadeIn .16s ease-out}
/* Searchable select */
.ss{position:relative}
.ss-toggle{width:100%;padding:0 26px 0 11px;height:34px;background:var(--bg);
  color:var(--tx);border:1px solid var(--bd);border-radius:var(--r);font-size:12.5px;
  cursor:pointer;text-align:left;font-family:var(--f);position:relative;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;
  align-items:center;gap:7px}
.ss-toggle:after{content:"";position:absolute;right:10px;top:50%;width:5px;height:5px;
  border-right:1.5px solid var(--tx3);border-bottom:1.5px solid var(--tx3);
  transform:translateY(-70%) rotate(45deg)}
.ss-toggle.placeholder{color:var(--tx3)}
.ss-panel{position:fixed;z-index:1000;background:var(--bg2);border:1px solid var(--bd);
  border-radius:9px;box-shadow:var(--shL);display:none;flex-direction:column;
  overflow:hidden;min-width:220px;max-width:460px}
.ss.open .ss-panel{display:flex}
.ss.open .ss-toggle{border-color:var(--ac);box-shadow:var(--ring)}
.ss-search{flex:0 0 auto;padding:7px;border-bottom:1px solid var(--bd)}
.ss-search input{padding:0 9px;height:30px;font-size:11.5px}
.ss-list{flex:1 1 auto;min-height:0;overflow-y:auto;padding:4px}
.ss-opt{padding:7px 10px;border-radius:5px;cursor:pointer;font-size:12px;display:flex;
  align-items:center;gap:8px}
.ss-opt:hover,.ss-opt.hl{background:var(--bg3)}
.ss-opt.sel{color:var(--ac);font-weight:500}
.ss-empty{padding:13px;text-align:center;color:var(--tx3);font-size:10.5px}
.ss-foot{flex:0 0 auto;padding:6px 8px;border-top:1px solid var(--bd);display:flex;gap:6px}
.ss-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:5px}
.tag{background:var(--bg3);border:1px solid var(--bd);border-radius:var(--rp);
  padding:2px 8px;font-size:9.5px;font-weight:500;display:inline-flex;
  align-items:center;gap:5px}
.tag button{background:none;border:none;color:var(--tx3);cursor:pointer;font-size:12px;
  line-height:1;padding:0}
.tag button:hover{color:var(--rd)}
/* Upload */
.upload-zone{border:1.5px dashed var(--bd);border-radius:var(--rx);padding:22px;
  text-align:center;cursor:pointer;background:var(--bg)}
.upload-zone:hover,.upload-zone.drag{border-color:var(--ac);background:var(--acBg)}
.upload-zone p{font-size:11.5px;color:var(--tx2);font-weight:500;display:flex;
  align-items:center;justify-content:center;gap:8px}
.upload-zone .us{font-size:9.5px;color:var(--tx3);font-weight:500;margin-top:4px;
  display:block}
.file-row{display:flex;align-items:center;gap:9px;padding:8px 10px;
  border:1px solid var(--bd);border-radius:var(--r);background:var(--bg2);margin-top:6px}
.file-ic{width:28px;height:28px;border-radius:6px;display:grid;place-items:center;
  background:var(--bg3);color:var(--tx2);flex-shrink:0;font-size:8px;font-weight:600;
  font-family:var(--fm)}
/* Role / option picker cards */
.roles{display:grid;grid-template-columns:repeat(3,1fr);gap:9px}
@media(max-width:700px){.roles{grid-template-columns:1fr}}
.role-c{border:1px solid var(--bd);border-radius:var(--rl);padding:11px 13px;
  cursor:pointer;background:var(--bg2);text-align:left;font-family:var(--f);
  color:var(--tx);transition:border-color .14s,background .14s}
.role-c:hover{border-color:var(--ac)}
.role-c.on{border-color:var(--ac);background:var(--acBg)}
.role-c-t{font-size:11.5px;font-weight:600;display:flex;align-items:center;gap:7px}
.role-c-d{font-size:9.5px;color:var(--tx2);margin-top:5px;line-height:1.55;font-weight:500}

/* == 17. Stepper / wizard ================================================== */
.stp{display:flex;align-items:center;gap:0;margin-bottom:16px;overflow-x:auto;
  scrollbar-width:none;padding-bottom:2px}
.stp::-webkit-scrollbar{display:none}
.stp-i{display:flex;align-items:center;gap:8px;flex-shrink:0}
.stp-n{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;
  font-size:9.5px;font-weight:600;background:var(--bg3);color:var(--tx3);
  border:1px solid var(--bd);flex-shrink:0}
.stp-i.on .stp-n{background:var(--ac);color:#fff;border-color:var(--ac)}
.stp-i.dn .stp-n{background:var(--gn);color:#fff;border-color:var(--gn)}
.stp-l{font-size:10.5px;font-weight:500;color:var(--tx3);white-space:nowrap}
.stp-i.on .stp-l{color:var(--tx)} .stp-i.dn .stp-l{color:var(--tx2)}
.stp-bar{width:34px;height:1.5px;background:var(--bd);margin:0 10px;flex-shrink:0}
.stp-i.dn + .stp-bar{background:var(--gn)}

/* == 18. Timeline / activity / approvals =================================== */
.tl{position:relative;padding-left:17px}
.tl::before{content:'';position:absolute;left:4px;top:5px;bottom:5px;width:1px;
  background:var(--bd)}
.tl-i{position:relative;padding:0 0 13px 0}
.tl-i:last-child{padding-bottom:0}
.tl-i::before{content:'';position:absolute;left:-16px;top:4px;width:8px;height:8px;
  border-radius:50%;background:var(--ac);border:2px solid var(--bg2)}
.tl-i.ok::before{background:var(--gn)} .tl-i.warn::before{background:var(--am)}
.tl-i.rd::before{background:var(--rd)} .tl-i.mut::before{background:var(--tx3)}
.tl-s{font-size:11.5px;font-weight:600;line-height:1.5}
.tl-s b{font-weight:600}
.tl-m{font-size:9px;color:var(--tx3);margin-top:2px;font-weight:600}
/* Approval chain — a compact horizontal read of who is next. */
.chain{display:flex;align-items:center;gap:0;flex-wrap:wrap}
.chain-s{display:flex;align-items:center;gap:7px;padding:5px 9px;
  border:1px solid var(--bd);border-radius:var(--rp);background:var(--bg2);
  font-size:10px;font-weight:500}
.chain-s.dn{border-color:var(--gn);color:var(--gn);background:var(--gnBg)}
.chain-s.now{border-color:var(--am);color:var(--am);background:var(--amBg)}
.chain-s.rj{border-color:var(--rd);color:var(--rd);background:var(--rdBg)}
.chain-a{width:16px;height:1.5px;background:var(--bd);flex-shrink:0}
/* Approval card — one component, used in the inbox, on records and in email. */
.apc{border:1px solid var(--bd);border-radius:var(--rl);background:var(--bg2);
  padding:11px 13px;margin-bottom:7px;display:flex;gap:12px;align-items:flex-start}
.apc:hover{border-color:var(--tx3)}
.apc-b{flex:1;min-width:0}
.apc-t{font-size:12px;font-weight:600;letter-spacing:-.02em}
.apc-m{font-size:9.5px;color:var(--tx3);font-weight:600;margin-top:3px;display:flex;
  gap:9px;flex-wrap:wrap}
.apc-a{display:flex;gap:6px;flex-shrink:0;align-items:center}
.apc-amt{font-family:var(--fm);font-size:14px;font-weight:600;white-space:nowrap}
/* SLA pip */
.sla{display:inline-flex;align-items:center;gap:4px;font-size:9px;font-weight:600}
.sla.ok{color:var(--gn)} .sla.warn{color:var(--am)} .sla.br{color:var(--rd)}

/* == 19. Board (kanban) ==================================================== */
.kb{display:flex;gap:9px;overflow-x:auto;padding-bottom:8px;align-items:flex-start}
.kb-c{width:274px;flex-shrink:0;background:var(--bgI);border:1px solid var(--bd);
  border-radius:var(--rl);display:flex;flex-direction:column;
  max-height:calc(100vh - 250px)}
.kb-h{padding:9px 11px;border-bottom:1px solid var(--bd);display:flex;
  align-items:center;gap:7px}
.kb-t{font-size:10.5px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;
  color:var(--tx2)}
.kb-n{font-size:9px;font-weight:600;background:var(--bg3);border-radius:var(--rp);
  padding:1px 6px;color:var(--tx2)}
.kb-sum{margin-left:auto;font-family:var(--fm);font-size:10px;font-weight:500;
  color:var(--tx3)}
.kb-b{padding:7px;overflow-y:auto;flex:1;min-height:60px}
.kbc{background:var(--bg2);border:1px solid var(--bd);border-radius:9px;padding:9px 10px;
  margin-bottom:6px;cursor:pointer;box-shadow:var(--sh)}
.kbc:hover{border-color:var(--ac)}
.kbc-t{font-size:11.5px;font-weight:500;line-height:1.35;margin-bottom:6px}
.kbc-m{font-size:9px;color:var(--tx3);font-weight:600;display:flex;align-items:center;
  gap:8px;flex-wrap:wrap;margin-top:6px}

/* == 20. Calendar ========================================================== */
.cal{border:1px solid var(--bd);border-radius:var(--rl);overflow:hidden;
  background:var(--bg2)}
.cal-hd{display:grid;grid-template-columns:repeat(7,1fr);background:var(--bg3)}
.cal-hd div{padding:6px 8px;font-size:8.5px;font-weight:600;color:var(--tx2);
  text-transform:uppercase;letter-spacing:.5px;text-align:center;
  border-right:1px solid var(--bd)}
.cal-hd div:last-child{border-right:none}
.cal-gd{display:grid;grid-template-columns:repeat(7,1fr)}
.cal-d{min-height:82px;padding:5px 6px;border-right:1px solid var(--bdL);
  border-bottom:1px solid var(--bdL);position:relative}
.cal-d:nth-child(7n){border-right:none}
.cal-d.off{background:var(--bgI)}
.cal-d.today{background:var(--acBg)}
.cal-n{font-size:10px;font-weight:600;color:var(--tx2);margin-bottom:4px}
.cal-d.today .cal-n{color:var(--ac)}
.cal-e{font-size:9px;font-weight:500;padding:2px 5px;border-radius:4px;margin-bottom:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}

/* == 21. Feedback: banners, toasts, tooltips, empty ======================== */
.banner{max-width:1860px;margin:9px auto 0;padding:8px 13px;font-size:10.5px;
  font-weight:500;background:var(--amBg);color:var(--am);border:1px solid var(--am);
  border-radius:var(--r);display:flex;gap:8px;align-items:center}
.banner.info{background:var(--blBg);color:var(--bl);border-color:var(--bl)}
.banner.rd{background:var(--rdBg);color:var(--rd);border-color:var(--rd)}
.banner.gn{background:var(--gnBg);color:var(--gn);border-color:var(--gn)}
.banner .gap{flex:1}
/* Impersonation runs edge to edge above everything, and is impossible to miss. */
/* Pinned to one red in both themes. The dark palette's --rd is a light coral
   that white text cannot sit on, and this is the one bar that must never be
   hard to read. */
.imp{background:#a72d2d;color:#fff;font-size:10.5px;font-weight:600;padding:6px 14px;
  display:flex;align-items:center;gap:9px;position:sticky;top:0;z-index:130}
.imp .btn{background:#fff;border-color:#fff;color:#a72d2d}
.imp .btn:hover{background:#f2e6e6;border-color:#f2e6e6;color:#8f2626}
.toast-w{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:1200;
  display:flex;flex-direction:column;gap:7px;align-items:center;max-width:92%}
.toast{background:var(--bg2);border:1px solid var(--bd);border-radius:9px;
  padding:10px 18px;font-size:11.5px;font-weight:600;box-shadow:var(--shM);
  animation:tin .18s ease-out;display:flex;align-items:flex-start;gap:10px;min-width:250px}
.toast.ok{border-color:var(--gn)} .toast.err{border-color:var(--rd)}
.toast.warn{border-color:var(--am)}
.toast-ic{flex-shrink:0;margin-top:1px;color:var(--ac)}
.toast.ok .toast-ic{color:var(--gn)} .toast.err .toast-ic{color:var(--rd)}
.toast.warn .toast-ic{color:var(--am)}
.toast-title{font-weight:600;font-size:11.5px}
.toast-msg{color:var(--tx2);font-size:10.5px;font-weight:500;margin-top:2px;line-height:1.5}
@keyframes tin{from{opacity:0;transform:translateY(10px)}}
.tip{position:fixed;z-index:1400;max-width:270px;padding:7px 10px;background:#16181d;
  color:#f2f3f5;border-radius:7px;font-size:11px;line-height:1.45;font-weight:500;
  pointer-events:none;opacity:0;transform:translateY(-3px);
  transition:opacity .13s,transform .13s;box-shadow:0 8px 22px -8px rgba(0,0,0,.5)}
.tip.show{opacity:1;transform:none}
.empty{font-size:11px;color:var(--tx3);text-align:center;padding:34px 20px}
/* Inside a dashboard card, one quiet line. The full poster — icon tile,
   heading, sentence — is for a whole screen with nothing on it; in a card it
   is 120 px of nothing next to a card that is full, which is what makes a
   quiet week look like a broken product. */
.cd-bd > .empty{padding:14px 0;text-align:left;display:flex;align-items:center;
  gap:9px;min-height:0}
.cd-bd > .empty .empty-ic{width:26px;height:26px;border-radius:8px;flex:none;
  margin:0}
.cd-bd > .empty .empty-ic svg.i{width:14px;height:14px}
.cd-bd > .empty .big{margin:0;font-size:11.5px}
.cd-bd > .empty .btn{margin:0 0 0 auto}
.empty .big{font-size:12.5px;font-weight:600;color:var(--tx2);margin-bottom:5px}
.empty .btn{margin-top:11px}
.empty-ic{width:44px;height:44px;border-radius:13px;background:var(--bg3);color:var(--tx3);
  display:grid;place-items:center;margin:0 auto 11px}
/* Skeletons */
@keyframes shimmer{0%{background-position:-560px 0}100%{background-position:560px 0}}
.sk{background:linear-gradient(90deg,var(--bg3) 25%,var(--bgH) 50%,var(--bg3) 75%);
  background-size:560px 100%;animation:shimmer 1.25s infinite linear;border-radius:5px;
  height:11px}
.sk-kpi{height:66px;border-radius:var(--rl);border:1px solid var(--bd)}
.sk-card{height:250px;border-radius:var(--rx);border:1px solid var(--bd)}
.sk-pc{height:146px;border-radius:var(--rx);border:1px solid var(--bd)}
.sk-row{height:29px;border-radius:5px;margin-bottom:5px}
@keyframes fadeIn{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
.fade-in{animation:fadeIn .2s ease-out}

/* == 22. Bars and donut (chart fallback) =================================== */
.bars{display:flex;flex-direction:column;gap:7px}
.bar-row{display:grid;grid-template-columns:minmax(80px,160px) 1fr 56px;gap:10px;
  align-items:center;font-size:10.5px}
.bar-row.drill{cursor:pointer}
.bar-row.drill:hover .bar-fill{opacity:.8}
.bar-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
.bar-track{height:8px;background:var(--bg3);border-radius:4px;overflow:hidden}
.bar-fill{height:100%;background:var(--ac);border-radius:4px;transition:width .35s}
.bar-val{text-align:right;font-family:var(--fm);font-weight:500;font-size:10px}
.donut{width:126px;height:126px;border-radius:50%;flex-shrink:0;position:relative;
  display:grid;place-items:center}
.donut::after{content:'';position:absolute;inset:17px;border-radius:50%;
  background:var(--bg2)}
.donut-c{position:relative;z-index:1;text-align:center}
.donut-v{font-size:19px;font-weight:600;letter-spacing:-.03em;line-height:1}
.donut-l{font-size:8px;font-weight:600;color:var(--tx3);text-transform:uppercase;
  letter-spacing:.5px;margin-top:3px}
.lgd{display:flex;flex-direction:column;gap:6px}
.lgd-i{display:flex;align-items:center;gap:8px;font-size:10.5px;font-weight:600}
.lgd-i .sw2{width:9px;height:9px;border-radius:3px;flex-shrink:0}
.lgd-i .vl{margin-left:auto;font-family:var(--fm);font-weight:500}

/* == 23. Auth / public shell =============================================== */
.auth{min-height:100vh;display:grid;place-items:center;padding:22px;background:var(--bg)}
.auth-c{width:100%;max-width:408px}
.auth-card{background:var(--bg2);border:1px solid var(--bd);border-radius:18px;
  padding:30px 30px 26px;box-shadow:var(--shM)}
.auth h1{font-size:23px;font-weight:700;letter-spacing:-.035em;margin-bottom:6px}
.auth-s{font-size:11.5px;color:var(--tx2);margin-bottom:20px;line-height:1.55;
  font-weight:500}
.auth-ft{text-align:center;font-size:9.5px;color:var(--tx3);margin-top:16px;font-weight:600}
.otp{display:flex;gap:8px;justify-content:center}
.otp input{width:42px;height:50px;text-align:center;font-size:19px;font-weight:600;
  font-family:var(--fm);padding:0}
/* Password strength meter */
.pw{display:flex;gap:4px;margin-top:7px}
.pw i{flex:1;height:3px;border-radius:2px;background:var(--bg3)}
.pw.s1 i:nth-child(1){background:var(--rd)}
.pw.s2 i:nth-child(-n+2){background:var(--am)}
.pw.s3 i:nth-child(-n+3){background:var(--bl)}
.pw.s4 i{background:var(--gn)}

/* == 24. Footer ============================================================ */
.ft{text-align:center;padding:20px 0 8px;font-size:9.5px;color:var(--tx3);
  font-weight:500}
.ft .dot{opacity:.4;margin:0 6px}
/* The maker's mark. Smaller than the company's own name and on its own line,
   because it is a credit and not a co-signature. */
.ft-by{display:block;font-size:8.5px;font-weight:500;color:var(--tx3);
  opacity:.7;margin-top:3px;letter-spacing:.2px}

/* == 25. Utilities ========================================================= */
.muted{color:var(--tx3)} .small{font-size:9.5px} .right{text-align:right}
.center{text-align:center} .nowrap{white-space:nowrap} .hidden{display:none!important}
.mono{font-family:var(--fm)} .bold{font-weight:600}
.flex{display:flex;align-items:center;gap:7px}
.wrap{flex-wrap:wrap} .col{flex-direction:column;align-items:stretch}
.between{justify-content:space-between} .grow{flex:1;min-width:0}
.mt0{margin-top:0} .mt8{margin-top:8px} .mt12{margin-top:12px} .mt16{margin-top:16px}
.mb0{margin-bottom:0} .mb8{margin-bottom:8px} .mb12{margin-bottom:12px}
.sep-h{height:1px;background:var(--bd);margin:13px 0}
.pre{font-family:var(--fm);font-size:10.5px;background:var(--bg);border:1px solid var(--bd);
  border-radius:8px;padding:11px;white-space:pre-wrap;margin-top:10px;max-height:270px;
  overflow:auto;line-height:1.6}
.gn-t{color:var(--gn)} .rd-t{color:var(--rd)} .am-t{color:var(--am)} .ac-t{color:var(--ac)}
.cur{font-family:var(--fm);font-weight:500;font-variant-numeric:tabular-nums}
.micro{font-size:8.5px;color:var(--tx3);font-weight:500;letter-spacing:.3px;
  text-transform:uppercase}

/* == 26. Responsive + print ================================================ */
@media(max-width:1023px){
  /* The rail used to slide off the left edge below this width and wait for a
     `.open` class that nothing ever added — so on every tablet and every
     phone the whole left-hand navigation simply was not there, and there was
     no control anywhere to bring it back.

     It becomes a strip of chips above the page instead. That needs no toggle,
     cannot be stranded in the closed state, and takes one line of height. */
  .shell{flex-direction:column;align-items:stretch}
  .side{position:static;height:auto;max-height:none;width:100%;
    border-right:0;border-bottom:1px solid var(--bd);
    display:flex;flex-wrap:wrap;gap:4px;padding:9px 12px;overflow:visible}
  .side-t{width:100%;padding:5px 2px 2px}
  /* One heading is orientation; five are a wall of eight-pixel capitals. */
  .side-t:not(:first-child){display:none}
  .sd{width:auto;margin:0;border:1px solid var(--bd);background:var(--bg);
    padding:5px 10px}
  .sd.on{border-color:var(--ac)}
  /* `.main` carries `margin:0 auto` so it centres on a wide screen. An auto
     margin on the cross axis of a flex container switches off stretch, so
     once `.shell` stacks into a column the main pane stopped being 100% wide
     and became as wide as its widest child instead — which for any screen
     with a data table on it meant the whole page scrolled sideways and the
     `.rtw` wrapper that exists to scroll the table never got the chance.
     Explicit width, no auto margin, below this width. */
  .side + .main,.main{padding-left:0;width:100%;margin-left:0;margin-right:0;
    min-width:0;max-width:100%}
  /* The wrapper, not just the label inside it. */
  .srch,.nav-search{display:none}
  .nav-tenant .tn-host{display:none}
}
@media(max-width:860px){
  .nav-tag,.sw-btn .lb{display:none}
  /* The Admin button keeps its icon and loses its word, and the help icon
     goes — it is reachable from inside the page. Both used to wait until
     560 px, which is a hundred pixels below where the strip actually runs
     out of room. */
  #efHelp{display:none}
  .nav-in > .btn{padding:0 9px;font-size:0;gap:0}
  .nav-in > .btn svg.i{width:15px;height:15px}
  .ph h1{font-size:19px}
  .hail-h{font-size:20px}
  .rtw{max-height:none}
  .kg,.kg.k6,.kg.k5,.kg.k4,.kg.k3{grid-template-columns:1fr 1fr}
}
@media(max-width:700px){
  /* The top strip carries a brand, a switcher, a search box, three icon
     actions, an Admin button and a profile ring. At this width that is more
     than fits, and what it did was push the profile ring off the right-hand
     edge — the one control that gets somebody signed out.

     So the strip drops to what cannot be reached any other way. The Admin
     button keeps its icon and loses its word; the tenant chip and the help
     icon go, because both are reachable from inside the page. */
  .nav-in{padding:0 8px;gap:5px}
  /* The brand is the one thing here that can give ground: it has a mark
     beside it and the company name is on every page anyway. Everything else
     in the strip is a control, and a control pushed off the right-hand edge
     is a control nobody can reach. */
  .nav-brand{font-size:13.5px;min-width:0;overflow:hidden;
    text-overflow:ellipsis;flex-shrink:1}
  .nav-brand .nav-mark{width:28px;height:28px;border-radius:9px;font-size:12px}
  .lk-n{font-size:13px}
  .nav-ico{width:30px}
  #efHelp{display:none}
  .nav-tenant{display:none}
  .nav-in > .btn{padding:0 8px;font-size:0;gap:0}
  .nav-in > .btn svg.i{width:15px;height:15px}
  .ph-act{width:100%}
  .ph-act .btn{flex:1;justify-content:center}
  .kg,.kg.k6,.kg.k5,.kg.k4,.kg.k3{grid-template-columns:1fr}
  .sm-i{min-width:100%}
  .md-b,.md-h,.md-f{padding-left:14px;padding-right:14px}
}
@media(prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
  .av-ring.spin{animation:none}
}
@media print{
  .nav,.imp,.side,.btn,.tabs,.toolbar,.pgw,.ft,.dm,.chip-row,.nav-ico,.pf,#loadbar{
    display:none!important}
  body{background:#fff}
  .cd,.ki,.pc{box-shadow:none;break-inside:avoid}
}

/* == 22. Search, the bell, the org chart and the week grid =================
   Everything here belongs to a control that existed in the nav and did
   nothing: the search box, the bell, and the two shapes the self-service
   screens needed that the kit did not carry — a reporting tree and a week
   of hours. */

/* -- The search results popover ------------------------------------------ */
.srch{position:relative;flex:1;max-width:340px;min-width:120px}
.srch .nav-search{width:100%}
.srch-pop{position:absolute;top:34px;left:0;right:0;z-index:320;
  max-height:min(72vh,520px);overflow:auto;background:var(--bg2);
  border:1px solid var(--bd);border-radius:var(--rx);box-shadow:var(--shL);
  padding:5px;display:none;animation:pop .14s ease-out}
.srch.open .srch-pop{display:block}
.srch-g{font-size:9px;font-weight:600;color:var(--tx3);letter-spacing:.4px;
  text-transform:uppercase;padding:8px 9px 4px}
.srch-r{display:flex;align-items:center;gap:9px;padding:6px 9px;border-radius:7px;
  color:var(--tx);cursor:pointer;text-decoration:none}
.srch-r:hover,.srch-r.on{background:var(--bg3);text-decoration:none}
.srch-r.on{outline:1px solid var(--ac);outline-offset:-1px}
.srch-r .ic{width:22px;height:22px;border-radius:6px;background:var(--bg3);
  color:var(--tx2);display:grid;place-items:center;flex-shrink:0}
.srch-r .ic svg.i{width:13px;height:13px}
.srch-r .tx{min-width:0;flex:1}
/* Two spans in a flex row render on one line without this. Fixed five times. */
.srch-r .t{display:block;font-size:11.5px;font-weight:500;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.srch-r .s{display:block;font-size:9px;color:var(--tx3);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.srch-note{padding:16px 12px;text-align:center;font-size:11px;color:var(--tx3);
  font-weight:500}
.srch-all{display:flex;align-items:center;gap:7px;margin-top:4px;padding:8px 9px;
  border-top:1px solid var(--bdL);font-size:10.5px;font-weight:600;
  color:var(--ac);cursor:pointer}
.srch-all:hover{text-decoration:none;background:var(--bg3);border-radius:0 0 9px 9px}
.srch-all svg.i{width:13px;height:13px}

/* -- The bell ------------------------------------------------------------- */
.bell{position:relative;flex-shrink:0}
.bell-pop{position:absolute;top:34px;right:0;z-index:320;width:308px;
  background:var(--bg2);border:1px solid var(--bd);border-radius:var(--rx);
  box-shadow:var(--shL);display:none;overflow:hidden;animation:pop .14s ease-out}
.bell.open .bell-pop{display:block}
.bell-h{padding:9px 12px;border-bottom:1px solid var(--bdL);background:var(--bgI);
  font-size:11.5px;font-weight:600;display:flex;align-items:center;
  justify-content:space-between;gap:8px}
.bell-l{max-height:340px;overflow:auto;padding:4px}
.bell-i{display:block;padding:8px 9px;border-radius:7px;color:var(--tx);
  cursor:pointer;position:relative}
.bell-i:hover{background:var(--bg3);text-decoration:none}
.bell-i.new{background:var(--acBg)}
.bell-i.new:hover{background:var(--acBg);filter:brightness(.98)}
.bell-i .t{display:block;font-size:11.5px;font-weight:500;line-height:1.35}
.bell-i .s{display:block;font-size:9.5px;color:var(--tx3);font-weight:500;
  margin-top:2px;line-height:1.4}
.bell-i .w{display:block;font-size:8.5px;color:var(--tx3);font-weight:600;
  margin-top:3px;letter-spacing:.2px}
.bell-f{display:block;padding:8px;text-align:center;border-top:1px solid var(--bdL);
  font-size:10.5px;font-weight:600;color:var(--ac);cursor:pointer}
.bell-f:hover{background:var(--bg3);text-decoration:none}

/* -- The org chart --------------------------------------------------------
   Top down: one box at the root, a drop, a bar across the children, a drop
   into each. Built out of nested lists and four ::before/::after rules rather
   than an SVG, so it reads in reporting order to a screen reader, prints, and
   keeps every node a real link.

   The trick is that each child <li> draws half the horizontal bar on its own
   side. First child draws the right half, last child the left half, and the
   ones between draw both — which is what makes the bar stop at the outermost
   children instead of running past them. */
.og{overflow:auto;padding:8px 2px 20px}
.og-in{display:inline-block;min-width:100%}
.og ul{list-style:none;margin:0;padding:0;display:flex;justify-content:center}
.og-root{padding-top:0}
.og li{position:relative;padding:26px 12px 0;text-align:center;
  display:flex;flex-direction:column;align-items:center}
.og-root > li{padding-top:0}

/* The drop into this box from the bar above it. */
.og li::before{content:'';position:absolute;top:0;left:50%;width:1px;height:26px;
  background:var(--bd)}
.og-root > li::before{display:none}
/* Half a bar on each side, so the run stops at the outermost child. */
.og li::after{content:'';position:absolute;top:0;height:1px;background:var(--bd);
  left:0;right:0}
.og li:first-child::after{left:50%}
.og li:last-child::after{right:50%}
.og li:only-child::after{display:none}
/* The drop out of a box towards its children. */
.og li > ul{position:relative;padding-top:26px}
.og li > ul::before{content:'';position:absolute;top:0;left:50%;width:1px;
  height:26px;background:var(--bd)}

.og-c{display:inline-block}
.og-b{display:flex;flex-direction:column;align-items:center;gap:3px;
  width:192px;padding:14px 12px 12px;border:1px solid var(--bd);
  border-radius:var(--rx);background:var(--bg2);color:var(--tx);
  box-shadow:var(--sh);transition:border-color .15s,box-shadow .15s,
  transform .15s}
a.og-b:hover{border-color:var(--ac);box-shadow:var(--shM);
  transform:translateY(-1px);text-decoration:none}
.og-c.top .og-b{border-color:var(--ac);background:var(--acBg)}
.og-c.me .og-b{border-color:var(--ac);box-shadow:var(--ring)}
.og-b .av{margin-bottom:5px}
.og-n{display:block;font-size:12.5px;font-weight:600;letter-spacing:-.015em;
  line-height:1.3;max-width:100%;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
/* The title may take two lines before it clips: "Senior Operations
   Coordinator" cut to "Senior Operations C…" was most of what "the cards do
   not read well" meant on a real company's chart. */
.og-t{display:block;font-size:10.5px;color:var(--tx2);font-weight:500;
  line-height:1.35;max-width:100%;overflow:hidden;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical}
.og-d{display:block;font-size:9px;color:var(--tx3);font-weight:600;
  margin-top:2px;text-transform:uppercase;letter-spacing:.3px;max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.og-k{display:inline-block;margin-top:5px;padding:1px 7px;border-radius:var(--rp);
  background:var(--bg3);color:var(--tx2);font-size:8.5px;font-weight:600}
/* The fold control under a card with a team below it. A shut branch is
   tinted, so a chart folded to its top row says where the rest went. */
.og-fold{margin-top:5px;padding:2px 9px;border-radius:var(--rp);
  border:1px solid var(--bd);background:var(--bg2);color:var(--tx3);
  font-size:9px;font-weight:600;cursor:pointer;font-family:var(--f);
  line-height:1.6;transition:border-color .14s,color .14s}
.og-fold:hover{border-color:var(--ac);color:var(--ac)}
.og-fold.shut{background:var(--acBg);color:var(--ac);
  border-color:color-mix(in srgb,var(--ac) 30%,var(--bd))}

/* On a narrow screen a wide tree is unusable side to side, so it becomes the
   indented list it used to be — same markup, different rules. */
@media (max-width:820px){
  .og ul{display:block}
  .og li{padding:0 0 0 22px;text-align:left;align-items:flex-start}
  .og li::before{top:0;bottom:0;left:8px;height:auto}
  .og li:last-child::before{bottom:auto;height:19px}
  .og li::after{top:19px;left:8px;right:auto;width:11px}
  .og li:first-child::after{left:8px}
  .og-root > li{padding-left:0}
  .og-root > li::after{display:none}
  .og li > ul{padding-top:2px}
  .og li > ul::before{display:none}
  .og-b{flex-direction:row;align-items:center;width:auto;min-width:0;
    max-width:340px;text-align:left;padding:7px 11px 7px 8px;margin:3px 0}
  .og-b .av{margin:0}
  .og-b > span:not(.av){align-items:flex-start}
  .og-n,.og-t,.og-d{text-align:left}
  .og-k{margin-top:0}
}

/* -- One person's chain, top of the company down to them ------------------ */
.ogc{list-style:none;margin:0;padding:0}
.ogc li{position:relative;padding:0 0 0 20px}
.ogc li::before{content:'';position:absolute;left:6px;top:0;bottom:0;
  border-left:1px solid var(--bd)}
.ogc li:first-child::before{top:16px}
.ogc li:last-child::before{bottom:auto;height:16px}
.ogc li::after{content:'';position:absolute;left:6px;top:16px;width:10px;
  border-top:1px solid var(--bd)}
.ogc li:first-child::after{display:none}
.ogc-b{display:flex;align-items:center;gap:9px;padding:5px 8px;border-radius:8px;
  color:var(--tx)}
.ogc-b:hover{background:var(--bg3);text-decoration:none}
.ogc li.me .ogc-b{background:var(--acBg)}
.ogc-x{min-width:0;flex:1}
.ogc-n{display:block;font-size:11.5px;font-weight:500;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.ogc-t{display:block;font-size:9.5px;color:var(--tx3);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* -- The week of hours ----------------------------------------------------
   Seven columns on a desktop, stacked on a phone. The day header carries its
   own state — a week off, a holiday, an approved day away — because that is
   what decides whether an empty cell is a problem. */
.tsg{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px}
.tsd{border:1px solid var(--bd);border-radius:var(--rl);background:var(--bg2);
  min-height:148px;display:flex;flex-direction:column;overflow:hidden;
  transition:border-color .13s,box-shadow .13s}
.tsd:not(.off):hover{border-color:var(--ac);box-shadow:var(--sh)}
.tsd.off{background:var(--bgI);border-style:dashed}
.tsd.today{border-color:var(--ac);box-shadow:var(--ring)}
.tsd-h{padding:6px 8px;border-bottom:1px solid var(--bdL);background:var(--bgI);
  display:flex;align-items:baseline;justify-content:space-between;gap:6px}
.tsd-d{font-size:10.5px;font-weight:600}
.tsd-n{font-size:8.5px;color:var(--tx3);font-weight:600}
.tsd-b{padding:6px;flex:1;display:flex;flex-direction:column;gap:5px}
.tsd-e{border:1px solid var(--bdL);border-radius:7px;padding:5px 6px;
  background:var(--bgI);font-size:10px;line-height:1.35;cursor:pointer}
.tsd-e:hover{border-color:var(--ac)}
.tsd-e .p{display:block;font-weight:600;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.tsd-e .h{display:block;color:var(--tx3);font-weight:600;font-size:9px;margin-top:1px}
.tsd-f{padding:5px 6px;border-top:1px solid var(--bdL);font-size:9.5px;
  font-weight:600;color:var(--tx2);display:flex;justify-content:space-between}
.tsd-add{border:1px dashed var(--bd);border-radius:7px;padding:5px;font-size:10px;
  font-weight:600;color:var(--tx3);background:none;cursor:pointer;width:100%}
.tsd-add:hover{border-color:var(--ac);color:var(--ac)}
/* An empty day is one big target, not a thin dashed line at the top of a
   hole. The whole card is clickable then — the page wires the card's click
   to this button. */
.tsd-b .tsd-add:only-child{flex:1;display:flex;align-items:center;
  justify-content:center;min-height:72px;font-size:11px}
@media (max-width:900px){
  .tsg{grid-template-columns:1fr 1fr}
}
@media (max-width:560px){
  .tsg{grid-template-columns:1fr}
  .srch{display:none}
}

/* -- A month of days, for one person -------------------------------------- */
.mgrid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px}
.mgrid-h{font-size:8.5px;font-weight:600;color:var(--tx3);text-align:center;
  padding:2px 0;letter-spacing:.3px;text-transform:uppercase}
.mday{aspect-ratio:1;border:1px solid var(--bdL);border-radius:8px;padding:4px;
  display:flex;flex-direction:column;justify-content:space-between;
  font-size:10px;background:var(--bg2);min-height:38px}
.mday.pad{border:none;background:none}
.mday .n{font-weight:600;font-size:10px}
.mday .m{font-size:7.5px;font-weight:600;text-transform:uppercase;letter-spacing:.2px}
.mday.s-present{background:var(--gnBg);border-color:transparent;color:var(--gn)}
.mday.s-wfh{background:var(--blBg);border-color:transparent;color:var(--bl)}
.mday.s-leave{background:var(--viBg);border-color:transparent;color:var(--vi)}
.mday.s-absent{background:var(--rdBg);border-color:transparent;color:var(--rd)}
.mday.s-half_day{background:var(--amBg);border-color:transparent;color:var(--am)}
.mday.s-week_off{background:var(--bgI);color:var(--tx3)}
.mday.s-holiday{background:var(--teBg);border-color:transparent;color:var(--te)}
.mday.today{outline:2px solid var(--ac);outline-offset:-1px}

/* -- A stack of things that happened, newest last -------------------------- */
.trail{list-style:none;margin:0;padding:0 0 0 20px;position:relative}
.trail::before{content:'';position:absolute;left:5px;top:6px;bottom:6px;
  border-left:1px solid var(--bd)}
.trail li{position:relative;padding:0 0 13px}
.trail li:last-child{padding-bottom:0}
.trail li::before{content:'';position:absolute;left:-18px;top:5px;width:7px;
  height:7px;border-radius:50%;background:var(--bg2);
  border:1.6px solid var(--tx3)}
.trail li.on::before{border-color:var(--ac);background:var(--ac)}
.trail .t{display:block;font-size:11.5px;font-weight:500}
.trail .s{display:block;font-size:9.5px;color:var(--tx3);font-weight:600;
  margin-top:1px}

/* -- Two numbers side by side, for a detail header ------------------------ */
.facts{display:flex;flex-wrap:wrap;gap:20px}
.fact .l{display:block;font-size:9px;font-weight:600;color:var(--tx3);
  text-transform:uppercase;letter-spacing:.3px}
.fact .v{display:block;font-size:15px;font-weight:600;letter-spacing:-.02em;
  margin-top:2px}
.fact .v.sm{font-size:12.5px}

/* A short list of consequences inside a confirm dialog. Used where a dialog
   has to state more than one thing that is true and cannot be a paragraph
   without becoming a wall. */
.bul{margin:0;padding:0 0 0 17px;font-size:12px;line-height:1.65;color:var(--tx2)}
.bul li{margin:0 0 4px}
.bul li:last-child{margin-bottom:0}


/* == 27. Going back ========================================================
   A named destination, not browser history. A page opened from a notification
   email has no history inside the product, and the browser's own back button
   takes the reader out of it entirely. */
.bk{display:inline-flex;align-items:center;gap:4px;font-size:9.5px;font-weight:600;
  color:var(--tx3);padding:2px 7px 2px 4px;margin:0 5px 0 -4px;border-radius:var(--r);
  border:1px solid transparent}
.bk:hover{color:var(--tx);background:var(--bg3);border-color:var(--bd);
  text-decoration:none}
.bk svg.i{width:12px;height:12px}

/* == 28. Announcement banners ==============================================
   Loud on purpose and rare on purpose. Tone is carried by a keyline down the
   left and by the icon colour — never by a filled block and never by anything
   that moves. A banner that shouts is a banner people learn to look past, and
   then the one that mattered is the one they looked past. */
.bnw{display:grid;gap:6px;margin-bottom:11px}
.bnw:empty{display:none}
/* The fold. Everything past the first notice lives behind one line, because
   a company with four live announcements used to push every screen in the
   product below the fold. */
.bn-more{display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  padding:6px 11px;border:1px solid var(--bdL);border-radius:var(--rl);
  background:var(--bgI);color:var(--tx3);font:500 11px var(--f);cursor:pointer}
.bn-more:hover{border-color:var(--bd);color:var(--tx2)}
.bn-more svg.i{width:12px;height:12px;flex:none;transition:transform .15s}
.bn-more.on svg.i{transform:rotate(180deg)}
.bn-more>span:first-of-type{flex:none;font-weight:600}
.bn-more-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;opacity:.75}
.bn-rest{display:grid;gap:6px}
/* `display:grid` on the same element beats the user agent's `[hidden]`
   rule, so the fold rendered its contents at full height while claiming to
   be closed. Every `hidden` element that also carries a display in this file
   needs this line beside it. */
.bn-rest[hidden]{display:none}
/* How many identical notices folded into this one. */
.bn-n{display:inline-block;margin-left:7px;font-size:9.5px;font-weight:600;
  background:var(--bg3);color:var(--tx3);border-radius:var(--rp);
  padding:0 6px;vertical-align:middle}
/* A banner carries its tone as a wash and a coloured icon, not as a 3 px
   rail down its left edge. The rail was the one ribbon left in the kit, and
   on the home screen — where three notices stack — it read as a striped
   margin rather than as three separate levels. The tint says the same thing
   across the whole shape, which is also what makes it survive being read on
   a phone at a third of the width. */
.bn{display:flex;align-items:flex-start;gap:11px;padding:11px 14px;
  border:1px solid var(--bd);border-radius:var(--rl);
  background:var(--bg2);box-shadow:var(--sh)}
.bn-ic{flex:none;display:grid;place-items:center;width:20px;height:20px;
  color:var(--tx3)}
.bn-ic svg.i{width:15px;height:15px}
.bn-b{flex:1;min-width:0}
.bn-t{font-size:13px;font-weight:600;letter-spacing:-.015em}
.bn-x{font-size:12px;color:var(--tx2);margin-top:4px;line-height:1.55;
  white-space:pre-wrap;overflow-wrap:anywhere}
.bn .btn{flex:none;align-self:center}
.bn-x-btn{flex:none;width:22px;height:22px;display:grid;place-items:center;
  border:none;background:none;color:var(--tx3);cursor:pointer;border-radius:5px}
.bn-x-btn:hover{background:var(--bg3);color:var(--tx)}
/* Three levels, and the strength is deliberately not uniform: a note is a
   wash, something that wants attention is a full tint, and something urgent
   also takes the border. A screen where every notice is coloured equally is
   a screen where the colour has stopped saying anything. */
.bn-i{background:color-mix(in srgb,var(--blBg) 60%,var(--bg2))}
.bn-i .bn-ic{color:var(--bl)}
.bn-a{background:var(--amBg);border-color:color-mix(in srgb,var(--am) 24%,var(--bd))}
.bn-a .bn-ic{color:var(--am)}
.bn-u{background:var(--rdBg);border-color:color-mix(in srgb,var(--rd) 40%,var(--bd))}
.bn-u .bn-ic{color:var(--rd)}
.bn-u .bn-t{color:var(--rd)}
/* The same three, in the accent, for a note that is neither a warning nor a
   piece of news — the security line on the joining form, most often. */
.bn-ac{background:var(--acBg);border-color:color-mix(in srgb,var(--ac) 22%,var(--bd))}
.bn-ac .bn-ic{color:var(--ac)}

/* == A chart that fills a card =============================================
   Two series of bars, a ceiling, a baseline and month labels. The SVG is
   drawn in its own 100-unit space and stretched, so the card can be any
   width; the axis labels sit outside it in real type, which is why they stay
   the right size when it stretches. */
.bc{display:grid;grid-template-columns:auto 1fr;grid-template-areas:
  "y plot" ". legend";gap:0 9px}
.bc-y{grid-area:y;display:flex;flex-direction:column;justify-content:space-between;
  font-size:9px;font-weight:600;color:var(--tx3);text-align:right;
  font-variant-numeric:tabular-nums;padding:12px 0 15px}
.bc-p{grid-area:plot;min-width:0}
.bc-p svg{width:100%;height:132px;display:block;overflow:visible}
.bc-x{display:flex;justify-content:space-around;font-size:9px;font-weight:600;
  color:var(--tx3);margin-top:4px}
.bc-x span{flex:1;text-align:center;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.bc .lg2{grid-area:legend;margin-top:9px}

/* == Zoom and fill-the-screen ==============================================
   For anything drawn larger than the box it is in — a reporting line, a
   roster grid. The scale is a transform on the wrapper's child, so every
   anchor inside stays clickable and find-in-page keeps working. */
.zc{display:inline-flex;align-items:center;gap:2px;background:var(--bg2);
  border:1px solid var(--bd);border-radius:var(--rp);padding:2px;
  box-shadow:var(--sh)}
.zc .ico-btn{width:24px;height:24px;border-radius:50%}
.zc .ico-btn:disabled{opacity:.35;cursor:default;background:none}
.zc-v{border:0;background:none;font-family:var(--fm);font-size:10px;
  font-weight:500;color:var(--tx2);min-width:38px;cursor:pointer;
  padding:0 2px;font-variant-numeric:tabular-nums}
.zc-v:hover{color:var(--tx)}
.zc-sep{width:1px;height:14px;background:var(--bdL);margin:0 3px}

.zw{position:relative}
.zw > *{transition:transform .16s ease-out}

/* Taking over the window. Fixed rather than the Fullscreen API on purpose:
   the API needs a user gesture on the exact element, drops out of the page's
   own stacking context, and on a locked-down browser is simply refused. This
   always works and Escape always leaves. */
body.zfull-on{overflow:hidden}
.zw.zfull{position:fixed;inset:0;z-index:400;background:var(--bg2);
  padding:52px 16px 16px;overflow:auto;max-height:none;border-radius:0}
.zw.zfull > *{max-height:none}
/* Full screen has ONE scroller — the overlay itself. An inner list that
   keeps its own overflow draws a second scrollbar in the middle of the
   window and the tree pans in a letterbox instead of the screen. */
.zw.zfull .og{overflow:visible;max-height:none}
/* The floating controls while the window is taken over. Without them the
   only way out was knowing about Escape. */
.zfb{position:fixed;top:10px;right:14px;z-index:410;display:flex;gap:6px;
  background:var(--bg2);border:1px solid var(--bd);border-radius:var(--rl);
  padding:5px;box-shadow:var(--shM)}
@media (prefers-reduced-motion:reduce){.zw > *{transition:none}}

/* == 29. SLA clocks ========================================================
   Two promises, side by side, so they are compared rather than read one at a
   time. The label is inside the chip because "4h left" on its own has been
   read as the wrong clock by everybody who has ever been shown it. */
.sla-w{display:inline-flex;gap:5px;flex-wrap:wrap;align-items:center}
.sla{display:inline-flex;align-items:center;gap:5px;font-size:9.5px;font-weight:600;
  padding:2px 7px;border-radius:var(--rp);border:1px solid var(--bd);
  background:var(--bgI);color:var(--tx2);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.sla b{font-weight:600;color:var(--tx3);font-size:8.5px;text-transform:uppercase;
  letter-spacing:.5px}
.sla-ok{background:var(--gnBg);border-color:transparent;color:var(--gn)}
.sla-ok b{color:var(--gn);opacity:.75}
.sla-live{background:var(--blBg);border-color:transparent;color:var(--bl)}
.sla-live b{color:var(--bl);opacity:.75}
.sla-soon{background:var(--amBg);border-color:transparent;color:var(--am)}
.sla-soon b{color:var(--am);opacity:.75}
.sla-late{background:var(--rdBg);border-color:transparent;color:var(--rd)}
.sla-late b{color:var(--rd);opacity:.75}
.sla-none{color:var(--tx3)}
/* The two clocks stacked, on a detail page where there is room to name them. */
.slabox{display:grid;grid-template-columns:1fr 1fr;gap:9px}
@media(max-width:640px){.slabox{grid-template-columns:1fr}}
.slabox .sb-i{border:1px solid var(--bd);border-radius:var(--rl);padding:10px 12px;
  background:var(--bg2)}
.slabox .sb-l{font-size:8.5px;font-weight:600;color:var(--tx3);
  text-transform:uppercase;letter-spacing:.55px}
.slabox .sb-v{font-size:17px;font-weight:600;letter-spacing:-.03em;margin-top:5px;
  font-variant-numeric:tabular-nums}
.slabox .sb-s{font-size:9.5px;color:var(--tx3);font-weight:600;margin-top:3px}
.slabox .sb-i.late{border-color:var(--rd)} .slabox .sb-i.late .sb-v{color:var(--rd)}
.slabox .sb-i.ok .sb-v{color:var(--gn)}
.slabox .sb-i.soon .sb-v{color:var(--am)}

/* == 30. Month calendar ====================================================
   One month as weeks. Built in the kit rather than per screen because three
   screens want it and three copies of date arithmetic is three chances to be
   a day out. */
.cal{border:1px solid var(--bd);border-radius:var(--rx);overflow:hidden;
  background:var(--bg2)}
.cal-hd{display:grid;grid-template-columns:repeat(7,1fr);background:var(--bgI);
  border-bottom:1px solid var(--bd)}
.cal-hd div{padding:7px 9px;font-size:8.5px;font-weight:600;color:var(--tx3);
  text-transform:uppercase;letter-spacing:.6px}
.cal-g{display:grid;grid-template-columns:repeat(7,1fr)}
.cal-d{min-height:96px;padding:6px 7px;border-right:1px solid var(--bdL);
  border-bottom:1px solid var(--bdL);display:flex;flex-direction:column;gap:3px;
  min-width:0}
.cal-d:nth-child(7n){border-right:0}
.cal-d.out{background:var(--bgI)}
.cal-d.off{background:var(--bgI)}
.cal-d.now{background:var(--acBg);box-shadow:inset 0 0 0 1px var(--ac)}
.cal-d[role=button]{cursor:pointer}
.cal-d[role=button]:hover{background:var(--bg3)}
.cal-n{font-size:11px;font-weight:600;color:var(--tx2);
  font-variant-numeric:tabular-nums;line-height:1.2}
.cal-d.now .cal-n{color:var(--ac)}
.cal-d.out .cal-n{display:none}
/* An entry is a line of text on a tint, not a coloured bar with a tooltip:
   the point of a calendar is reading it without hovering anything. */
.cal-e{display:block;font-size:9.5px;font-weight:500;padding:2px 6px;
  border-radius:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cal-e.me{font-weight:600}
.cal-more{font-size:8.5px;color:var(--tx3);font-weight:600;padding-left:2px}
.cal-gn{background:var(--gnBg);color:var(--gn)}
.cal-vi{background:var(--viBg);color:var(--vi)}
.cal-bl{background:var(--blBg);color:var(--bl)}
.cal-or{background:var(--orBg);color:var(--or)}
.cal-te{background:var(--teBg);color:var(--te)}
.cal-ac{background:var(--acBg);color:var(--ac)}
.cal-am{background:var(--amBg);color:var(--am)}
.cal-rd{background:var(--rdBg);color:var(--rd)}
.cal-gy{background:var(--bg3);color:var(--tx2)}
@media(max-width:880px){
  .cal-d{min-height:70px;padding:4px 5px}
  .cal-e{font-size:8.5px;padding:1px 4px}
}
/* The legend. Named colours, once, so nothing on the grid needs a caption. */
.cal-key{display:flex;flex-wrap:wrap;gap:5px 14px;padding:9px 2px 0;
  font-size:9.5px;font-weight:600;color:var(--tx3)}
.cal-key span{display:inline-flex;align-items:center;gap:6px}
.cal-key i{width:9px;height:9px;border-radius:3px;display:block}

/* == 31. Meter =============================================================
   Against a quota. Says both numbers and then draws the ratio — never the
   ratio alone, because a per cent of an unstated total is not actionable. */
.mt{margin-bottom:11px}
.mt:last-child{margin-bottom:0}
.mt-h{display:flex;justify-content:space-between;align-items:baseline;gap:9px;
  font-size:10.5px;font-weight:500;color:var(--tx2);margin-bottom:5px}
.mt-v{font-size:10.5px;font-weight:600;color:var(--tx);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.mt-b{height:6px;border-radius:3px;background:var(--bg3);overflow:hidden}
.mt-b i{display:block;height:100%;background:var(--ac);border-radius:3px;
  transition:width .3s}
.mt.high .mt-b i{background:var(--am)}
.mt.high .mt-v{color:var(--am)}
.mt.full .mt-b i{background:var(--rd)}
.mt.full .mt-v{color:var(--rd)}

/* == 32. Permission picker =================================================
   Fifty-eight codes and a checkbox each was a screen that could only be used
   by somebody who already knew the answer. Every row now says what it does,
   which screens it opens, and whether it is one to be careful with. */
.pm-p{border:1px solid var(--bd);border-radius:var(--rl);margin-bottom:9px;
  overflow:hidden;background:var(--bg2)}
.pm-h{display:flex;align-items:center;gap:9px;padding:9px 12px;background:var(--bgI);
  border-bottom:1px solid var(--bd);cursor:pointer}
.pm-h:hover{background:var(--bg3)}
.pm-nm{font-size:11.5px;font-weight:600;flex:1;min-width:0}
.pm-ct{font-size:9.5px;font-weight:600;color:var(--tx3);
  font-variant-numeric:tabular-nums}
.pm-l{padding:2px 0}
.pm-i{display:flex;align-items:flex-start;gap:11px;padding:9px 12px;
  border-top:1px solid var(--bdL);cursor:pointer}
.pm-i:first-child{border-top:0}
.pm-i:hover{background:var(--bgI)}
.pm-i input{margin-top:2px;accent-color:var(--ac);width:14px;height:14px;flex:none}
.pm-b{flex:1;min-width:0}
.pm-t{font-size:11.5px;font-weight:500;display:flex;align-items:center;gap:7px;
  flex-wrap:wrap}
.pm-w{font-size:10.5px;color:var(--tx2);margin-top:3px;line-height:1.55}
.pm-where{font-size:9.5px;color:var(--tx3);margin-top:4px;font-weight:600}
.pm-code{font-family:var(--fm);font-size:9px;color:var(--tx3)}
/* Marked, not hidden. A permission an administrator cannot find is one they
   will grant by making somebody an owner instead. */
.pm-care{font-size:8.5px;font-weight:600;color:var(--am);background:var(--amBg);
  border-radius:var(--rp);padding:1px 7px;letter-spacing:.3px;white-space:nowrap}
.pm-i.no{opacity:.5}
.pm-i.no input{cursor:not-allowed}
.pm-no{font-size:8.5px;font-weight:600;color:var(--tx3);background:var(--bg3);
  border-radius:var(--rp);padding:1px 7px;white-space:nowrap}

/* == 33. Role cards ========================================================
   A starting point for a group, shown as what it lets somebody do rather than
   as a list of codes. */
.rl{display:grid;grid-template-columns:repeat(auto-fill,minmax(272px,1fr));gap:10px}
.rl-c{border:1px solid var(--bd);border-radius:var(--rl);padding:13px 14px;
  background:var(--bg2);display:flex;flex-direction:column;min-width:0}
.rl-c:hover{border-color:var(--ac)}
.rl-t{font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:8px}
.rl-d{font-size:10.5px;color:var(--tx2);margin-top:5px;line-height:1.55;flex:1}
.rl-does{display:flex;flex-wrap:wrap;gap:4px;margin-top:9px}
.rl-does span{font-size:9px;font-weight:500;background:var(--bg3);color:var(--tx2);
  border-radius:var(--rp);padding:2px 8px}
.rl-f{display:flex;align-items:center;gap:8px;margin-top:11px;
  padding-top:10px;border-top:1px solid var(--bdL)}
.rl-n{font-size:9.5px;color:var(--tx3);font-weight:600;flex:1}

/* == 34. Job cards =========================================================
   An opening, from the inside. */
.jb{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:10px}
.jb-c{border:1px solid var(--bd);border-radius:var(--rx);padding:14px 15px;
  background:var(--bg2);display:flex;flex-direction:column;min-width:0;
  box-shadow:var(--sh)}
.jb-c:hover{border-color:var(--ac);box-shadow:var(--shM)}
.jb-t{font-size:13.5px;font-weight:600;letter-spacing:-.02em;line-height:1.3}
.jb-m{display:flex;flex-wrap:wrap;gap:4px 12px;margin-top:6px;font-size:10.5px;
  color:var(--tx3);font-weight:600}
.jb-m span{display:inline-flex;align-items:center;gap:5px}
.jb-s{display:flex;flex-wrap:wrap;gap:4px;margin-top:10px}
.jb-s span{font-size:9.5px;font-weight:500;background:var(--bg3);color:var(--tx2);
  border-radius:var(--rp);padding:2px 8px}
.jb-f{display:flex;align-items:center;gap:7px;margin-top:12px;padding-top:11px;
  border-top:1px solid var(--bdL)}
.jb-rw{font-size:10px;font-weight:600;color:var(--gn);flex:1}

/* == 35. Card content, straightened ========================================
   Three shapes that were laying out wrong wherever they appeared.

   Two spans in a flex row render on one line, which is how "Farhan
   ShaikhSite Engineer" got onto four screens. The kit now owns the fix rather
   than each page discovering it again. */
.x-n,.x-s{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.x-n{font-weight:500;font-size:11.5px}
.x-s{font-size:10px;color:var(--tx3);font-weight:600}
/* A definition grid whose last row has a right border on the last cell, and a
   ragged bottom edge where the row did not fill. Both are the same fix. */
.dv-i:last-child{border-right:0}
.dv-i{display:flex;flex-direction:column;justify-content:flex-start}
/* A card body whose children are cards should not double its own padding. */
.cd-bd > .cd:last-child{margin-bottom:0}
.cd-bd > .g2:last-child,.cd-bd > .g3:last-child{margin-bottom:0}
/* A card header where the title block and the actions collide at narrow
   widths: the title keeps its line, the actions wrap under it. */
.cd-h > div:first-child{min-width:0;flex:1}
.cd-t{min-width:0;overflow-wrap:anywhere}
.cd-s{overflow-wrap:anywhere}
/* Long values inside a facts grid have to wrap, not push the column open —
   an IFSC or a 200-character note was widening the whole card. */
.kv dd,.dv-v{overflow-wrap:anywhere}

/* == 36. Page sections =====================================================
   A heading with a rule to its right, for a page that has grown past one
   card. `.sec-t` already did this inside a modal; this is its page-level
   twin, with room above it. */
.pg-sec{display:flex;align-items:center;gap:10px;margin:20px 0 10px;
  font-size:11px;font-weight:600;color:var(--tx2);letter-spacing:-.01em}
.pg-sec::after{content:"";flex:1;height:1px;background:var(--bd)}
.pg-sec:first-child{margin-top:0}
.pg-sec .ct{font-size:9.5px;color:var(--tx3);font-weight:600}

/* == 37. A thread ==========================================================
   Two sides talking. Used by the support desk on both planes, and by the
   request desks. Whose message it is has to be answerable at a glance from
   the shape alone, because the names on it are unfamiliar in both
   directions. */
.th{display:grid;gap:10px}
.th-m{display:flex;gap:10px;max-width:min(760px,100%)}
.th-m.mine{margin-left:auto;flex-direction:row-reverse}
.th-av{width:28px;height:28px;border-radius:50%;flex:none;display:grid;
  place-items:center;font-size:9.5px;font-weight:600;color:#fff}
.th-b{border:1px solid var(--bd);border-radius:var(--rl);padding:10px 13px;
  background:var(--bg2);min-width:0}
.th-m.mine .th-b{background:var(--acBg);border-color:transparent}
.th-h{display:flex;align-items:baseline;gap:9px;margin-bottom:4px;flex-wrap:wrap}
.th-who{font-size:11px;font-weight:600}
.th-at{font-size:9.5px;color:var(--tx3);font-weight:600}
.th-t{font-size:12px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere}
/* Effred talking to Effred. Never crosses to the customer's side, and it has
   to be obvious on the screen that it will not. */
.th-m.note .th-b{background:var(--amBg);border-color:var(--am);border-style:dashed}
.th-tag{font-size:8.5px;font-weight:600;color:var(--am);text-transform:uppercase;
  letter-spacing:.5px}

/* == 38. A summary strip ===================================================
   Facts about one record, across the top of its page. Denser than KPI tiles
   and quieter: these are not measurements, they are what the record is. */
.sm{display:flex;flex-wrap:wrap;gap:0;border:1px solid var(--bd);
  border-radius:var(--rl);background:var(--bg2);overflow:hidden;margin-bottom:11px}
.sm-i{padding:10px 15px;border-right:1px solid var(--bdL);min-width:132px;flex:1}
.sm-i:last-child{border-right:0}
.sm-l{font-size:8.5px;font-weight:600;color:var(--tx3);text-transform:uppercase;
  letter-spacing:.55px}
.sm-v{font-size:13px;font-weight:600;margin-top:4px;letter-spacing:-.02em;
  overflow-wrap:anywhere}
.sm-v.big{font-size:19px}
@media(max-width:700px){.sm-i{min-width:50%;flex:none;
  border-bottom:1px solid var(--bdL)}}


/* A figure that goes somewhere.
   -------------------------------------------------------------------------
   Used by the head-room meters on the control plane. Every number on that
   page was a dead end — it said "11 of 1000" and finding which eleven meant
   opening the customer's portal in another tab and hunting for the screen.
   The whole block is the target, because a number is what people aim at. */
.mtr{display:block;color:var(--tx);border-radius:var(--rl);padding:2px;
  margin:-2px;transition:background .12s}
.mtr:hover{background:var(--bgI);text-decoration:none}
.mtr:hover .ki-v{color:var(--ac)}

/* == 39. The greeting strip ================================================
   The first thing on My space: who you are, what today is, and the three
   things people came here to do.

   It replaced a page header. A page header names the page, which on somebody's
   own home screen is the one fact they already have — they clicked the thing
   that brought them here. What they do not have is whether the timesheet is
   due, so the strip carries the actions rather than a title. */
.hail{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap;
  margin-bottom:16px}
.hail-l{flex:1;min-width:240px}
.hail-h{font-size:24px;font-weight:700;letter-spacing:-.035em;line-height:1.15}
.hail-s{font-size:12px;color:var(--tx3);font-weight:500;margin-top:5px;
  display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.hail-s .dt{opacity:.45}
.hail-a{display:flex;align-items:center;gap:8px;flex-wrap:wrap}

/* == 40. An agenda =========================================================
   A day as a column of times. Used by the schedule card on My space, by the
   calendar screen, and by the technician's day.

   The rail down the left is a 1 px hairline with a dot per row, not a bar —
   it says these are in order and stops there. `.now` is the row happening at
   this minute and is the only one that carries the accent, because a day
   where four rows are highlighted has told nobody which one is next. */
.agd{display:grid;gap:0;position:relative}
.agd-r{display:grid;grid-template-columns:62px 12px 1fr auto;gap:11px;
  align-items:flex-start;padding:11px 0;border-bottom:1px solid var(--bdL);
  min-width:0}
.agd-r:last-child{border-bottom:0}
.agd-t{font-size:11px;font-weight:600;color:var(--tx3);
  font-variant-numeric:tabular-nums;padding-top:1px;white-space:nowrap}
/* The dot and the thread it hangs on. Drawn on the marker so a row that is
   the last one does not trail a line into nothing. */
.agd-m{position:relative;width:12px;align-self:stretch;display:flex;
  justify-content:center;padding-top:4px}
.agd-m::before{content:"";position:absolute;top:0;bottom:-11px;width:1px;
  background:var(--bdL)}
.agd-r:last-child .agd-m::before{display:none}
.agd-m i{position:relative;width:8px;height:8px;border-radius:50%;
  background:var(--bd);box-shadow:0 0 0 3px var(--bg2);flex:none}
/* One hue per meeting, hashed off its subject so the same standup is the same
   colour every morning. It is the only thing distinguishing six rows of
   identical shape, and a column of identical grey dots is a column nobody
   scans. */
.agd-m i.c0{background:var(--g-bl)} .agd-m i.c1{background:var(--g-vi)}
.agd-m i.c2{background:var(--g-te)} .agd-m i.c3{background:var(--g-am)}
.agd-m i.c4{background:var(--g-gn)} .agd-m i.c5{background:var(--g-rd)}
.agd-b{min-width:0}
.agd-n{display:block;font-size:12.5px;font-weight:600;
  letter-spacing:-.015em;overflow-wrap:anywhere}
.agd-s{font-size:10.5px;color:var(--tx3);font-weight:500;margin-top:3px;
  display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.agd-x{display:flex;align-items:center;gap:7px;flex:none;padding-top:1px}
.agd-r.done .agd-n{color:var(--tx3)}
.agd-r.done .agd-m i{background:var(--gn)}
.agd-r.now .agd-m i{background:var(--ac);box-shadow:0 0 0 3px var(--acBg)}
.agd-r.now{background:var(--acBg);border-radius:var(--rl);
  padding-left:11px;padding-right:11px;margin:0 -11px;border-bottom-color:transparent}
.agd-r.now .agd-n{color:var(--acD)}
/* A meeting somebody can walk into from here. The button is only drawn when
   there is somewhere to go — a Join that opens nothing is exactly the control
   §4 rules out. */
.agd .jn{flex:none}
@media(max-width:560px){
  .agd-r{grid-template-columns:54px 12px 1fr;row-gap:6px}
  .agd-x{grid-column:3;justify-content:flex-start}
}

/* == 41. What is waiting on somebody ======================================
   Two lists that look alike and mean opposite things: things this person has
   to do, and things they are waiting for somebody else to do. Told apart by
   the heading over each and by the second having a face on it — the face is
   whose desk it is sitting on, which is the only fact that makes waiting
   bearable. */
.tsk{display:grid;gap:0}
.tsk-r{display:flex;align-items:flex-start;gap:11px;padding:11px 0;
  border-bottom:1px solid var(--bdL);min-width:0}
.tsk-r:last-child{border-bottom:0}
.tsk-i{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  flex:none;background:var(--bg3);color:var(--tx2)}
.tsk-i svg.i{width:15px;height:15px}
.tsk-i.am{background:var(--amBg);color:var(--am)}
.tsk-i.rd{background:var(--rdBg);color:var(--rd)}
.tsk-i.ac{background:var(--acBg);color:var(--ac)}
.tsk-b{flex:1;min-width:0}
.tsk-n{display:block;font-size:12.5px;font-weight:600;
  letter-spacing:-.015em;overflow-wrap:anywhere}
.tsk-s{display:block;font-size:10.5px;color:var(--tx3);font-weight:500;
  margin-top:3px}
.tsk-x{flex:none;display:flex;align-items:center;gap:7px;padding-top:3px}
.tsk-w{font-size:10px;font-weight:600;color:var(--tx3);white-space:nowrap}
.tsk-w.due{color:var(--am)} .tsk-w.late{color:var(--rd)}

/* == 42. Who is around =====================================================
   A row of faces and then the names under it. The faces answer how many and
   the names answer who, and both were asked for often enough on the same card
   to be one component. */
.fstack{display:flex;align-items:center;padding-left:6px}
.fstack > *{margin-left:-6px;border:2px solid var(--bg2);flex:none}
.fstack .more{width:30px;height:30px;border-radius:50%;background:var(--bg3);
  color:var(--tx2);display:grid;place-items:center;font-size:9.5px;
  font-weight:600}
.prs{display:grid;gap:0;margin-top:12px}
.prs-r{display:flex;align-items:center;gap:9px;padding:7px 0;
  border-bottom:1px solid var(--bdL);font-size:12px;min-width:0}
.prs-r:last-child{border-bottom:0}
.prs-r .nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-weight:500}
/* A presence dot. Four states and no animation: a pulsing dot on a screen
   somebody keeps open all day is a thing that moves in the corner of their
   eye for eight hours. */
.pdot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--g-gy)}
.pdot.in{background:var(--g-gn)} .pdot.rm{background:var(--g-bl)}
.pdot.busy{background:var(--g-am)} .pdot.off{background:var(--g-gy)}

/* == 43. Dates as chips ====================================================
   A holiday, an anniversary, a renewal — anything that is a date and a
   sentence. The month sits over the day so the column stays 40 px wide
   whatever the length of the month name. */
.dchip{display:flex;align-items:center;gap:11px;padding:9px 0;
  border-bottom:1px solid var(--bdL);min-width:0}
.dchip:last-child{border-bottom:0}
.dchip .cal{width:40px;flex:none;border:1px solid var(--bd);border-radius:9px;
  overflow:hidden;text-align:center;background:var(--bg2)}
.dchip .cal .mo{font-size:8px;font-weight:600;letter-spacing:.6px;
  background:var(--bg3);color:var(--tx3);padding:2px 0}
.dchip .cal .dy{font-size:14px;font-weight:700;letter-spacing:-.03em;
  padding:3px 0 4px;line-height:1}
.dchip.soon .cal .mo{background:var(--acBg);color:var(--acD)}
.dchip .db{min-width:0;flex:1}
.dchip .dn{display:block;font-size:12px;font-weight:600;
  overflow-wrap:anywhere}
.dchip .ds{display:block;font-size:10.5px;color:var(--tx3);
  font-weight:500;margin-top:2px}

/* == 44. The clock card ====================================================
   Check in, check out, and how long you have been here. One figure, one
   sentence, one button — anything else on this card is a thing somebody has
   to read past twice a day for the rest of their employment. */
.clk{text-align:center;padding:6px 0 2px}
.clk-t{font-size:36px;font-weight:700;letter-spacing:-.045em;line-height:1;
  font-variant-numeric:tabular-nums}
.clk-t .ap{font-size:15px;font-weight:600;color:var(--tx3);letter-spacing:0;
  margin-left:5px}
.clk-s{font-size:11px;color:var(--tx3);font-weight:500;margin-top:8px}
.clk-m{display:flex;justify-content:center;gap:9px;flex-wrap:wrap;
  margin-top:12px;font-size:10px;font-weight:600;color:var(--tx3)}
.clk-m span{background:var(--bgI);border:1px solid var(--bd);
  border-radius:var(--rp);padding:3px 10px}

/* == 45. A checklist of paper =============================================
   What somebody still owes, and what has been looked at. Used by the
   onboarding review and by the joiner's own upload page, which is why the row
   has to read the same whether or not there is a file behind it. */
.plist{display:grid;gap:0}
.pl-r{display:flex;align-items:center;gap:11px;padding:11px 0;
  border-bottom:1px solid var(--bdL);min-width:0}
.pl-r:last-child{border-bottom:0}
.pl-m{width:22px;height:22px;border-radius:7px;flex:none;display:grid;
  place-items:center;background:var(--bg3);color:var(--tx3)}
.pl-m svg.i{width:12px;height:12px}
.pl-m.ok{background:var(--gnBg);color:var(--gn)}
.pl-m.no{background:var(--rdBg);color:var(--rd)}
.pl-m.wait{background:var(--amBg);color:var(--am)}
.pl-b{flex:1;min-width:0}
/* Both declared block. `<span class="pl-n">` and `<span class="pl-s">`
   inside a flex child render on one line — "Photo IDaadhaar.pdf" — and
   that is the mistake CLAUDE.md §10 lists as "two spans that should
   stack", caught six times before this one. Fixed on the component
   rather than on the caller, so it cannot come back whichever element
   somebody reaches for. */
.pl-n{display:block;font-size:12.5px;font-weight:600;
  overflow-wrap:anywhere}
.pl-s{display:block;font-size:10.5px;color:var(--tx3);font-weight:500;
  margin-top:2px;overflow-wrap:anywhere}
.pl-x{flex:none;display:flex;align-items:center;gap:6px}
/* A drop target. It is a label wrapping a file input, so the whole box is the
   control and the keyboard reaches it — a div with a click handler is
   neither. */
.drop{display:flex;align-items:center;justify-content:center;gap:9px;
  padding:18px;border:1.5px dashed var(--bd);border-radius:var(--rl);
  background:var(--bgI);color:var(--tx3);font-size:12px;font-weight:500;
  cursor:pointer;text-align:center;transition:border-color .14s,background .14s}
.drop:hover,.drop.over{border-color:var(--ac);background:var(--acBg);
  color:var(--acD)}
.drop input[type=file]{display:none}

/* == 46. A public page =====================================================
   The onboarding form a new joiner opens from a link in their mail, and the
   quotation a customer accepts. Neither person has a login, neither has ever
   seen this product, and both arrived from an email — so the page says whose
   it is at the top and carries no navigation at all, because there is nowhere
   else they may go. */
.pub{min-height:100vh;background:var(--bg);padding:0 0 40px}
.pub-h{background:var(--bg2);border-bottom:1px solid var(--bd);padding:16px 20px}
.pub-hi{max-width:940px;margin:0 auto;display:flex;align-items:center;gap:12px;
  flex-wrap:wrap}
.pub-c{max-width:940px;margin:0 auto;padding:24px 20px 0}
.pub-c.narrow{max-width:640px}
/* The steps across the top of a form somebody fills in once. Numbers, a line
   between them, and the one they are on in the accent. */
.stps{display:flex;align-items:center;gap:0;margin-bottom:20px;overflow-x:auto;
  scrollbar-width:none}
.stps::-webkit-scrollbar{display:none}
.jst{display:flex;align-items:center;gap:9px;flex:none;padding-right:14px}
.jst .n{width:26px;height:26px;border-radius:50%;flex:none;display:grid;
  place-items:center;font-size:11px;font-weight:600;background:var(--bg3);
  color:var(--tx3)}
.jst .l{font-size:11.5px;font-weight:500;color:var(--tx3);white-space:nowrap}
.jst.on .n{background:var(--ac);color:#fff}
.jst.on .l{color:var(--tx);font-weight:600}
.jst.done .n{background:var(--gnBg);color:var(--gn)}
.jst.done .l{color:var(--tx2)}
.jst::after{content:"";width:26px;height:1px;background:var(--bd);
  margin-left:14px;flex:none}
.jst:last-child{padding-right:0}
.jst:last-child::after{display:none}
@media(max-width:640px){.jst .l{display:none}.jst::after{width:16px;margin-left:8px}}

/* == 47. A link somebody was sent ==========================================
   One row per invitation: who it went to, where it got to, and when it stops
   working. The token itself is never drawn — it is in their mail, and a link
   on a screen behind a shoulder is a link that has left the building. */
.lnk-r{display:flex;align-items:center;gap:11px;padding:11px 0;
  border-bottom:1px solid var(--bdL);min-width:0}
.lnk-r:last-child{border-bottom:0}
.lnk-b{flex:1;min-width:0}
.lnk-n{display:block;font-size:12.5px;font-weight:600;
  overflow-wrap:anywhere}
.lnk-s{font-size:10.5px;color:var(--tx3);font-weight:500;margin-top:2px;
  display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.lnk-x{flex:none;display:flex;align-items:center;gap:7px}


/* == 48. A week of hours, as bars =========================================
   Seven columns, today marked. It is the same data the KPI tile draws as a
   sparkline, at the size where the individual days are readable — the tile
   answers "how is the week going", this answers "which day am I short on".

   The bar grows from the bottom of a fixed-height track rather than the
   column being the bar, so seven days of wildly different hours still line
   their labels up. A day with no hours gets no number rather than a nought:
   nought reads as "I worked zero hours" and blank reads as "not yet", and on
   a Wednesday the difference is the whole point. */
.wkb{display:grid;grid-template-columns:repeat(7,1fr);gap:6px;align-items:end}
.wkb-c{display:flex;flex-direction:column;align-items:center;gap:5px;min-width:0}
.wkb-v{font-size:10px;font-weight:600;color:var(--tx3);height:12px;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.wkb-t{width:100%;height:66px;background:var(--bg3);border-radius:6px;
  display:flex;align-items:flex-end;overflow:hidden}
.wkb-t i{display:block;width:100%;background:var(--g-bl);border-radius:6px}
.wkb-d{font-size:9.5px;font-weight:600;color:var(--tx3);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:100%}
/* Today is the one column that carries the accent. A week where every bar is
   coloured has told nobody which day they are standing in. */
.wkb-c.on .wkb-t i{background:var(--ac)}
.wkb-c.on .wkb-d,.wkb-c.on .wkb-v{color:var(--acD)}

/* == 49. A face ===========================================================
   One avatar, used in the stack on the presence card and beside a name in a
   list. Square-ratio, round, and it never distorts a photograph — the
   difference between `object-fit:cover` and the default is a room full of
   people who look slightly wrong. */
.fs-a{width:30px;height:30px;border-radius:50%;flex:none;display:grid;
  place-items:center;font-size:10.5px;font-weight:600;color:#fff;
  overflow:hidden;object-fit:cover}
.fs-a.sm{width:26px;height:26px;font-size:9.5px}
img.fs-a{object-fit:cover}

/* == 50. One figure on its own ============================================
   The last payslip. A number this size is read from across a desk, which is
   the only reason anything in this product is allowed to be 26 px. */
.paybox{background:var(--bgI);border:1px solid var(--bd);border-radius:var(--rl);
  padding:12px 14px;margin-bottom:12px}
.pay-v{font-size:26px;font-weight:700;letter-spacing:-.04em;line-height:1.1;
  margin-top:5px;font-variant-numeric:tabular-nums}


/* == 51. A stacked bar ====================================================
   One bar, several kinds, a legend under it. The leave card had one row per
   type with its own track, which is four bars answering a question — "how
   much have I got left" — that is really one number split several ways.

   The hues are positional rather than semantic: leave type one is always the
   first hue, on every screen, for every company. Nothing here means "good" or
   "bad", so nothing here borrows the tones that do. */
.stk{display:flex;height:9px;border-radius:var(--rp);overflow:hidden;
  background:var(--bg3);margin:4px 0 11px}
.stk i{display:block;height:100%;min-width:3px}
.stk i.k0{background:var(--g-gn)} .stk i.k1{background:var(--g-am)}
.stk i.k2{background:var(--g-vi)} .stk i.k3{background:var(--g-bl)}
.stk i.k4{background:var(--g-te)} .stk i.k5{background:var(--g-rd)}
.stk-l{display:flex;flex-wrap:wrap;gap:6px 14px}
.stk-l span{display:inline-flex;align-items:center;gap:6px;font-size:10.5px;
  font-weight:500;color:var(--tx2)}
.stk-l i{width:8px;height:8px;border-radius:50%;flex:none}
.stk-l i.k0{background:var(--g-gn)} .stk-l i.k1{background:var(--g-am)}
.stk-l i.k2{background:var(--g-vi)} .stk-l i.k3{background:var(--g-bl)}
.stk-l i.k4{background:var(--g-te)} .stk-l i.k5{background:var(--g-rd)}
.stk-l b{font-weight:600;color:var(--tx)}

/* A celebration. Pink for a birthday and violet for an anniversary — the two
   are read at a glance from across the card, and neither borrows a tone that
   means something elsewhere. */
.cel-i{width:30px;height:30px;border-radius:50%;flex:none;display:grid;
  place-items:center;font-size:10.5px;font-weight:600}
.cel-i.bd{background:#FBEAF1;color:#A83862}
.cel-i.an{background:var(--viBg);color:var(--vi)}
.cel-w{font-size:10.5px;font-weight:600;white-space:nowrap}
.cel-w.bd{color:#A83862} .cel-w.an{color:var(--vi)}


/* == 52. The deck =========================================================
   A home screen laid out as a wrapping row of fixed-height cards.

   This replaces the two-column split My space used to run on. That split was
   ragged by construction — two independent stacks end at different heights
   and the difference is a hole — and a masonry flow fixed the hole by making
   the reading order jump columns. Neither is what a dashboard wants.

   The deck is one flex row that wraps. Each card declares how greedy it is
   (`--gw`, the flex-grow) and how narrow it may get before wrapping (`--mw`),
   so a card that is mostly a list can sit beside one that is mostly a number
   and neither has to be the same width. `align-items:stretch` plus a height
   on the card is what makes every row end level whatever is in it.

   The heights are deliberate and they are the whole trick: a card is a fixed
   box with its own scroll, so a week with forty meetings in it renders the
   same shape as a week with two, and the cards below never move. A dashboard
   whose layout changes with the data is one nobody builds a habit around. */
.deck{display:flex;flex-wrap:wrap;gap:14px;align-items:stretch;
  margin-bottom:14px}
.deck > .dk{flex:var(--gw,1) 1 var(--fb,280px);min-width:var(--mw,260px);
  height:var(--h,280px);background:var(--bg2);border:1px solid var(--bd);
  border-radius:16px;padding:18px 20px;display:flex;flex-direction:column;
  min-height:0;overflow:hidden}
/* The head is fixed and the body scrolls under it. Both are load-bearing:
   without `flex-shrink:0` on the head a long list squeezes the title away,
   and without `min-height:0` on the body the scroll never engages, because a
   flex item's default floor is its content. */
.dk-h{display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-bottom:12px;flex-shrink:0}
.dk-t{font-size:15px;font-weight:700;letter-spacing:-.02em}
.dk-b{flex:1;min-height:0;overflow-y:auto;
  display:flex;flex-direction:column;gap:9px;padding-bottom:4px;
  /* Scrolls, and does not draw a bar to say so. Thirteen cards each with a
     6 px groove down the right edge is thirteen vertical lines on a screen
     whose whole point is that it reads as one surface. Wheel, trackpad,
     keyboard and touch are all untouched; only the gutter is gone, and
     `overscroll-behavior` stops a flick inside a card carrying on into the
     page behind it. */
  scrollbar-width:none;-ms-overflow-style:none;overscroll-behavior:contain}
.dk-b::-webkit-scrollbar{width:0;height:0;display:none}
.dk-b.plain{display:block}
/* Pushes whatever follows to the bottom of the card, so a footer sits on the
   floor rather than under the last row. */
.dk-sp{flex:1;min-height:0}
.dk-f{flex-shrink:0;padding-top:10px;font-size:11.5px;color:var(--tx3);
  font-weight:500}
/* A card whose height is genuinely its content — the KPI strip. */
.deck.auto > .dk{height:auto}
@media(max-width:700px){
  .deck > .dk{height:auto;max-height:none}
  .dk-b{overflow:visible}
}

/* == 53. The clock card ===================================================
   The one card on the home screen that is a control rather than a report, and
   the only card in the product that is not white.

   That is on purpose and it is the exception that proves the rule: everything
   else here is something to read, this is the thing most of the company opens
   the portal to press twice a day. Making it the one coloured object on the
   screen is what lets somebody find it without looking. The two rings are
   drawn at 7-9% white — visible as depth, never as decoration competing with
   the figure. */
.dk.clock{background:linear-gradient(160deg,var(--g-gn) 0%,var(--acD) 100%);
  border-color:transparent;color:#fff;position:relative;overflow:hidden}
.dk.clock .dk-t{color:#fff}
.dk.clock::before,.dk.clock::after{content:"";position:absolute;
  border-radius:50%;pointer-events:none}
.dk.clock::before{width:190px;height:190px;border:26px solid rgba(255,255,255,.09);
  top:-70px;right:-70px}
.dk.clock::after{width:120px;height:120px;border:18px solid rgba(255,255,255,.07);
  bottom:-50px;left:-40px}
.dk.clock > *{position:relative}
.ck-pill{display:inline-flex;align-items:center;gap:6px;
  background:rgba(255,255,255,.16);border-radius:var(--rp);padding:4px 10px;
  font-size:11.5px;font-weight:600;white-space:nowrap}
.ck-pill i{width:7px;height:7px;border-radius:50%;background:#7DF0BE;flex:none}
.ck-pill.off i{background:#FFD166}
.ck-t{text-align:center;margin:16px 0 4px}
.ck-n{font-size:42px;font-weight:700;letter-spacing:-.04em;line-height:1;
  font-variant-numeric:tabular-nums}
.ck-n span{font-size:17px;font-weight:600;opacity:.85;letter-spacing:0}
.ck-s{font-size:12.5px;font-weight:500;opacity:.85;margin-top:8px}
.ck-m{display:flex;justify-content:space-between;gap:8px;flex-wrap:wrap;
  font-size:11.5px;font-weight:500;opacity:.85;margin-bottom:12px}
.ck-go{background:#fff;color:var(--acD);border:none;border-radius:11px;
  padding:11px;font-family:var(--f);font-size:13.5px;font-weight:700;
  cursor:pointer;width:100%;flex-shrink:0}
.ck-go:hover{background:var(--acBg)}
.ck-go:disabled{opacity:.6;cursor:default}

/* == 54. An agenda row ====================================================
   A meeting as a tinted block with a coloured rail down its left edge.

   The rail is the one place this product uses one, and it earns it here in a
   way it did not on a KPI tile: six rows of identical shape, read in a
   glance, where the only thing distinguishing one from the next is which
   meeting it is. The hue is hashed off the subject, so the same standup is
   the same colour every morning and the column becomes scannable rather than
   merely legible. */
.ag{display:flex;gap:12px;align-items:stretch;border-radius:11px;
  padding:10px 12px;flex-shrink:0;background:var(--bgI);min-width:0}
.ag-r{width:3.5px;border-radius:3px;flex:none;background:var(--bd)}
.ag-t{width:62px;font-size:12px;font-weight:600;color:var(--tx3);
  padding-top:2px;flex-shrink:0;font-variant-numeric:tabular-nums}
.ag-b{flex:1;min-width:0}
.ag-n{font-size:13.5px;font-weight:600;overflow-wrap:anywhere}
.ag-s{font-size:12px;color:var(--tx3);font-weight:500;margin-top:1px;
  overflow-wrap:anywhere}
.ag-x{align-self:center;flex:none}
/* Six positional hues, matching the stacked bar and the dots elsewhere. */
.ag.c0{background:var(--blBg)} .ag.c0 .ag-r{background:var(--g-bl)}
.ag.c1{background:var(--viBg)} .ag.c1 .ag-r{background:var(--g-vi)}
.ag.c2{background:var(--teBg)} .ag.c2 .ag-r{background:var(--g-te)}
.ag.c3{background:var(--amBg)} .ag.c3 .ag-r{background:var(--g-am)}
.ag.c4{background:var(--gnBg)} .ag.c4 .ag-r{background:var(--g-gn)}
.ag.c5{background:var(--orBg)} .ag.c5 .ag-r{background:var(--g-rd)}
/* The one happening now, and the ones already finished. */
.ag.now{box-shadow:0 0 0 1.5px var(--ac)}
.ag.done .ag-n{color:var(--tx3)}
.ag.free{background:repeating-linear-gradient(135deg,var(--bgI) 0 8px,
  var(--bg) 8px 16px)}
.ag.free .ag-n{color:var(--tx3)}

/* == 55. A task with a box beside it (.tkq — .tk is the support desk's) ======================================
   Things this person has to do. The square is a marker rather than a control
   — it is not a checkbox, because nothing here is completed by ticking it;
   every row is a link to the screen where the work happens. Drawn as a square
   because a column of them reads as a list of outstanding items, which is
   exactly what it is. */
.tkq{display:flex;gap:10px;align-items:flex-start;flex-shrink:0;min-width:0;
  color:var(--tx)}
a.tkq:hover{text-decoration:none}
a.tkq:hover .tkq-n{color:var(--ac)}
.tkq-box{width:17px;height:17px;border-radius:6px;border:1.8px solid var(--bd);
  margin-top:1px;flex-shrink:0}
.tkq-b{flex:1;min-width:0}
.tkq-n{font-size:13.5px;font-weight:600;overflow-wrap:anywhere}
.tkq-s{font-size:12px;color:var(--tx3);font-weight:500;margin-top:1px}
.tkq-w{flex:none;white-space:nowrap}
/* The divider and the heading over the second list. Two lists that look alike
   and mean opposite things — mine to do, theirs to decide — so the heading
   between them is doing real work. */
.tkq-sep{height:1px;background:var(--bd);margin:13px 0 11px;flex-shrink:0}
.tkq-cap{font-size:11.5px;font-weight:600;letter-spacing:.6px;
  color:var(--tx3);margin-bottom:9px;flex-shrink:0;text-transform:uppercase}

/* == 56. A bar per weekday ================================================
   The week as seven columns. The bar grows from the floor of a fixed track
   rather than the column being the bar, so the labels line up whatever the
   hours are. A day with no hours draws a 5 px stub, not a nought: nought
   reads as "I worked zero" and a stub reads as "not yet", and on a Wednesday
   that is the whole difference. */
.wkg{flex:1;display:flex;align-items:flex-end;gap:12px;padding:8px 4px 0;
  min-height:0}
.wkg-c{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;
  height:100%;justify-content:flex-end;min-width:0}
.wkg-v{font-size:11px;font-weight:600;color:var(--tx3);
  font-variant-numeric:tabular-nums}
.wkg-r{width:100%;max-width:42px;border-radius:8px;background:var(--g-gn);
  opacity:.55;min-height:5px}
.wkg-c.today .wkg-r{background:var(--g-am);opacity:1}
.wkg-c.today .wkg-v{color:var(--am);font-weight:600}
.wkg-c.off .wkg-r{background:var(--bd);opacity:1}
.wkg-d{display:flex;gap:12px;padding:6px 4px 0;flex-shrink:0}
.wkg-d > div{flex:1;text-align:center;font-size:11.5px;font-weight:600;
  color:var(--tx3);min-width:0}
.wkg-d > div.today{color:var(--am)}
.wkg-d > div.off{color:var(--bd)}

/* == 57. One figure in a tinted box =======================================
   The last payslip. Read from across a desk, which is the only reason
   anything in this product is allowed to be 22 px. */
.paybox{background:var(--gnBg);border-radius:12px;padding:12px 14px;
  flex-shrink:0}
.paybox .lb{font-size:11.5px;font-weight:600;color:var(--gn);
  text-transform:uppercase;letter-spacing:.5px}
.paybox .v{font-size:22px;font-weight:700;letter-spacing:-.03em;margin-top:3px;
  font-variant-numeric:tabular-nums}
.paybox .s{font-size:11.5px;color:var(--tx3);font-weight:500;margin-top:2px}

/* == 58. A goal with a track ==============================================
   Used by the KRA card. The per-goal hue is positional, matching the stacked
   bar — nothing here means good or bad, so nothing here borrows a tone that
   does. */
.goal{flex-shrink:0}
.goal-h{display:flex;justify-content:space-between;gap:8px;font-size:13px;
  font-weight:600;margin-bottom:6px}
.goal-t{height:7px;border-radius:6px;background:var(--bg);overflow:hidden}
.goal-t i{display:block;height:100%;border-radius:6px;background:var(--g-gn)}
.goal.k1 .goal-t i{background:var(--g-am)} .goal.k1 .goal-h span:last-child{color:var(--am)}
.goal.k2 .goal-t i{background:var(--g-vi)} .goal.k2 .goal-h span:last-child{color:var(--vi)}
.goal.k3 .goal-t i{background:var(--g-bl)} .goal.k3 .goal-h span:last-child{color:var(--bl)}
.goal.k0 .goal-h span:last-child{color:var(--gn)}

/* == 59. A date as a tile =================================================
   A holiday. The month sits over the day so the tile stays 40 px wide
   whatever the length of the month name. */
.dtl{display:flex;align-items:center;gap:11px;flex-shrink:0;min-width:0}
.dtl-c{width:40px;height:40px;border-radius:10px;background:var(--bgI);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  flex-shrink:0}
.dtl-c .mo{font-size:9.5px;font-weight:600;color:var(--tx3)}
.dtl-c .dy{font-size:15px;font-weight:700;line-height:1}
.dtl.soon .dtl-c{background:var(--gnBg)}
.dtl.soon .dtl-c .mo{color:var(--gn)} .dtl.soon .dtl-c .dy{color:var(--acD)}
.dtl-b{flex:1;min-width:0}
.dtl-n{font-size:13px;font-weight:600;overflow-wrap:anywhere}
.dtl-s{font-size:11.5px;color:var(--tx3);font-weight:500}

/* == 60. A face beside a name =============================================
   Shared by the presence list, the celebrations card and the waiting-on-
   others list. */
.fc{width:32px;height:32px;border-radius:50%;flex:none;display:grid;
  place-items:center;font-size:11px;font-weight:600;overflow:hidden}
.fc.sm{width:28px;height:28px;font-size:10.5px}
img.fc{object-fit:cover}
.fstk{display:flex;flex-shrink:0}
.fstk > *{border:2px solid var(--bg2)}
.fstk > * + *{margin-left:-8px}
.fstk .more{background:var(--bgI);color:var(--tx2);font-size:10px}
.prw{display:flex;align-items:center;gap:9px;flex-shrink:0;min-width:0}
.prw .nm{flex:1;min-width:0;font-size:13px;font-weight:600;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.prw .st{font-size:11.5px;color:var(--tx3);font-weight:500;flex:none}
/* Three states and no animation: a pulsing dot on a screen somebody keeps
   open all day is movement in the corner of their eye for eight hours. */
.pdot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--g-gy)}
.pdot.in{background:var(--g-gn)} .pdot.rm{background:var(--g-bl)}
.pdot.off{background:var(--bd)}


/* == 61. A select you can type into =======================================
   The trigger, the filter and the list. The <select> itself is still in the
   DOM and still the value — it is moved out of sight rather than replaced, so
   every form, validator and script that reads it keeps working. `position:
   absolute` rather than `display:none`, because a hidden field is skipped by
   some browsers' form validation and this one still has to be validated. */
.slx{position:relative}
.slx-src{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;
  left:0;bottom:0;padding:0;border:0;margin:0}
.slx-btn{display:flex;align-items:center;gap:8px;width:100%;height:38px;
  padding:0 12px;border:1px solid var(--bd);border-radius:var(--rl);
  background:var(--bgI);font-family:var(--f);font-size:13px;font-weight:500;
  color:var(--tx);cursor:pointer;text-align:left}
.slx-btn:hover{border-color:var(--ac)}
.slx.on .slx-btn{border-color:var(--ac);box-shadow:var(--ring);background:var(--bg2)}
.slx-v{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.slx-v.ph{color:var(--tx3)}
.slx-btn .car{width:5px;height:5px;border-right:1.6px solid var(--tx3);
  border-bottom:1.6px solid var(--tx3);transform:translateY(-2px) rotate(45deg);
  flex:none}
.slx-pop{position:absolute;top:42px;left:0;right:0;z-index:320;display:none;
  background:var(--bg2);border:1px solid var(--bd);border-radius:var(--rl);
  box-shadow:var(--shL);overflow:hidden}
.slx.on .slx-pop{display:block}
.slx-f{display:flex;align-items:center;gap:8px;padding:9px 12px;
  border-bottom:1px solid var(--bdL);color:var(--tx3)}
.slx-f input{border:0;background:none;height:auto;padding:0;font-size:13px;
  font-weight:500;flex:1;min-width:0}
.slx-f input:focus{box-shadow:none;border:0;background:none}
/* This one keeps its scrollbar. A filter list is a menu somebody is
   actively hunting in, often much longer than the box, and the bar is the
   only thing saying how much more there is. */
.slx-l{max-height:244px;overflow-y:auto;padding:5px}
.slx-i{padding:8px 11px;border-radius:8px;font-size:13px;font-weight:500;
  cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* `.at` is where the keyboard is, `.on` is what is chosen. They are different
   facts and a list where they look the same is one you get lost in. */
.slx-i.at{background:var(--bg3)}
.slx-i.on{color:var(--acD);font-weight:600}
.slx-i.on::after{content:"✓";float:right;opacity:.7}
.slx-none{padding:14px 11px;font-size:12px;color:var(--tx3);text-align:center}
